http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/about-chef.md
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/about-chef.md b/guide/yaml/chef/about-chef.md
new file mode 100644
index 0000000..db3ec3c
--- /dev/null
+++ b/guide/yaml/chef/about-chef.md
@@ -0,0 +1,50 @@
+---
+title: About Chef
+title_in_menu: About Chef
+layout: website-normal
+---
+
+## What you need to know about Chef
+
+Chef works in two different modes, *server* and *solo*. *Server* is where the 
Chef client talks to a central server
+to retrieve information about its roles, policies and cookbooks (where a 
cookbook defines how to install and
+configure a particular piece of software). With *solo*, the client works in 
isolation, therefore its configuration
+and cookbooks must be supplied by another means.
+
+Chef *client* is the Chef agent. This is a Ruby application which is installed 
on each and every managed host. When
+invoked in server mode, it will contact the Chef server to check for updates 
to cookbooks and policy; it then "runs"
+the recipes in its run lists, to converge the machine to a known state. In 
solo mode, it reads the locally-maintained
+cookbooks and policies. The client may be run as a daemon that checks the 
server regularly, or it could merely be
+run manually when required.
+
+The *policy* is a set of rules on the Chef server. A client starts with a set 
of *attributes*, which could be as
+simple as its name and a recipe runlist, or which may involve a more complex 
set of attributes about how it is to be
+configured. The client then augments this with auto-detected metadata - a tool 
called `ohai` is run that collects
+detailed information about the host. Next, the policy on the server modifies 
these attributes - overriding some,
+setting defaults for others - to produce a final set of attributes. It is 
these which are the input to the recipes.
+Finally, the attributes are uploaded to the server where they are stored as 
metadata for the node, where they can be
+inspected and modified by the system operator.
+
+Also of interest is `knife`, which is the workstation toolkit for Chef. 
Typically this would be installed on the
+operation engineer's workstation, where it would be used to interact with the 
Chef server and clients. Of particular
+interest to us is the *bootstrap* operation, which is used for setting up new 
Chef clients - given a virtual machine,
+it will install the Chef client on it, configure it with enough information to 
find the Chef server and performs its
+first run, and then kicks off the Chef client for the first time.
+
+There is often a preconception about how a Chef client is bootstrapped; 
mistakenly, there is the belief that the
+`knife` tool configures the Chef server with information about the client, and 
the client finds out about itself from
+the server. This is not the case - the bootstrap operation does not involve 
`knife` talking to the server. Instead,
+`knife` packages up all of the required information and sends it to the client 
- the client will then introduce
+itself to the server, passing on its configuration.
+
+This diagram summarises the interaction between Brooklyn, the new node, and 
the various Chef tools. Note that there
+is no interaction between the AMP Server and the Chef Server.
+
+[![Chef Flow Diagram](chef-call-flow.png "Chef Flow Diagram" 
)](chef-call-flow.png)
+
+### How Brooklyn interacts with Chef
+
+Brooklyn understands both the *server* and *solo* modes of operation. Server 
mode utilises the `knife` toolkit, and
+therefore `knife` must be installed onto the AMP server and configured 
appropriately. Solo mode does not have any
+special requirements; when running in solo mode, Brooklyn will install and 
configure the Chef client over SSH, just
+like it does most other kinds of entities.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/advanced-chef-integration.md
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/advanced-chef-integration.md 
b/guide/yaml/chef/advanced-chef-integration.md
new file mode 100644
index 0000000..0d65286
--- /dev/null
+++ b/guide/yaml/chef/advanced-chef-integration.md
@@ -0,0 +1,48 @@
+---
+title: Advanced Chef Integration
+title_in_menu: Advanced Chef Integration
+layout: website-normal
+---
+
+### Adding Sensors and Effectors
+
+Custom sensors and effectors can be added using an `entity.initializer` 
section in the YAML blueprint.
+
+One common pattern is to have sensors which extract information from Ohai.
+Another common pattern is to install a monitoring agent as part of the run 
list,
+configured to talk to a monitoring store, and then to add a sensor feed which 
reads data from that store.
+
+On the effector side, you can add SSH-based effectors in the usual way.
+You can also describe additional chef converge targets following the pattern 
set down in
+`ChefLifecycleEffectorTasks`, making use of conveniences in `ChefSoloTasks` 
and `ChefServerTasks`,
+or provide effectors which invoke network API's of the systems under management
+(for example to supply the common `executeScript` effector as on the standard 
`MySqlNode`). 
+   
+
+### Next Steps: Simpifying sensors and effectors, transferring files, and 
configuring ports
+
+The Brooklyn-Chef integration is work in progress, with a few open issues we'd 
still like to add.
+Much of the thinking for this is set forth in the [Google 
document](https://docs.google.com/a/cloudsoftcorp.com/document/d/18ZwzmncbJgJeQjnSvMapTWg6N526cvGMz5jaqdkxMf8)
+indicated earlier.  If you'd like to work with us to implement these, please 
let us know.
+
+
+## Reference
+
+A general schema for the supported YAML is below: 
+
+{% highlight yaml %}
+- type: chef:cookbook_name
+  cookbook_urls:
+    cookbook_name: url://for/cookbook.tgz
+    dependency1: url://for/dependency1.tgz
+  launch_run_list: [ "cookbook_name::start" ]
+  launch_attributes: # map of arguments to set in the chef node
+  service_name: cookbook_service
+  pid_file: /var/run/cookbook.pid
+{% endhighlight %}
+
+If you are interested in exploring the Java code for creating blueprints,
+start with the `TypedToyMySqlEntiyChef` class, which essentially does what 
this tutorial has shown;
+and then move on to the `DynamicToyMySqlEntiyChef` which starts to look at 
more sophisticated constructs.
+(Familiarity with BASH and basic Java blueprints may be useful at that stage.)
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/chef-call-flow.png
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/chef-call-flow.png 
b/guide/yaml/chef/chef-call-flow.png
new file mode 100644
index 0000000..d899de2
Binary files /dev/null and b/guide/yaml/chef/chef-call-flow.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/creating-blueprints.md
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/creating-blueprints.md 
b/guide/yaml/chef/creating-blueprints.md
new file mode 100644
index 0000000..8d30131
--- /dev/null
+++ b/guide/yaml/chef/creating-blueprints.md
@@ -0,0 +1,105 @@
+---
+title: Creating Blueprints from Chef
+title_in_menu: Creating Blueprints from Chef
+layout: website-normal
+---
+
+In a nutshell, a new Chef-based entity can be defined as a service by 
specifying
+`chef:cookbook_name` as the `service_type`, along with a collection of 
optional configuration.
+An illustrative example is below:
+
+{% highlight yaml %}
+{% readj example_yaml/mysql-chef-1.yaml %}
+{% endhighlight %}
+
+*This works without any installation: try it now, copying-and-pasting to the 
Brooklyn console.
+(Don't forget to add your preferred `location: some-cloud` to the spec.)*  
+
+Notice, if you target `google-compute-engine` location, you may need to 
specify `bind_address: 0.0.0.0` for the `mysql` cookbook, as described 
[here](https://github.com/chef-cookbooks/mysql/blob/46dccac22d282a05ee6a401e10ae8f5f8114fd66/README.md#parameters).
+
+We'll now walk through the important constituent parts,
+and then proceed to describing things which can be done to simplify the 
deployment.
+
+
+### Cookbook Primary Name
+
+The first thing to note is the type definition:
+
+    - type: chef:mysql
+
+This indicates that the Chef entity should be used 
(`org.apache.brooklyn.entity.chef.ChefEntity`) 
+to interpret and pass the configuration,
+and that it should be parameterised with a 
`brooklyn.chef.cookbook.primary.name` of `mysql`.
+This is the cookbook namespace used by default for determining what to install 
and run.
+
+
+### Importing Cookbooks
+
+Next we specify which cookbooks are required and where they can be pulled from:
+
+      cookbook_urls:
+        mysql: 
https://github.com/opscode-cookbooks/mysql/archive/v4.0.12.tar.gz
+        openssl: 
https://github.com/opscode-cookbooks/openssl/archive/v1.1.0.tar.gz
+        build-essential: 
https://github.com/opscode-cookbooks/build-essential/archive/v1.4.4.tar.gz
+
+Here, specific versions are being downloaded from the canonical github 
repository.
+Any URL can be used, so long as it is resolvable on either the target machine 
or the
+Brooklyn server; this includes `file:` and `classpath:` URLs.
+
+The archive can be ZIP or TAR or TGZ.
+
+The structure of the archive must be that a single folder is off the root,
+and in that folder contains the usual Chef recipe and auxiliary files.
+For example, the archive might contain `mysql-master/recipes/server.rb`.
+Archives such as those above from github match this format.  
+The name of that folder does not matter, as often they contain version 
information.
+When deployed, these will be renamed to match the short name (the key in the 
`cookbooks_url` map,
+for instance `mysql` or `openssl`).
+
+If Chef server is configured (see below), this section can be omitted.
+
+
+### Launch Run List and Attributes
+
+The next part is to specify the Chef run list and attributes to store when 
launching the entity: 
+
+      launch_run_list:
+      - mysql::server
+      
+      launch_attributes:
+        mysql:
+          server_root_password: p4ssw0rd
+          server_repl_password: p4ssw0rd
+          server_debian_password: p4ssw0rd
+
+For the `launch_run_list`, you can use either the YAML `- recipe` syntax or 
the JSON `[ "recipe" ]` syntax.
+
+The `launch_attributes` key takes a map which will be stored against the 
`node` object in Chef.
+Thus in this example, the parameter `node['mysql']['server_root_password']` 
required by the mysql blueprint
+is set as specified.
+
+You can of course set many other attributes in this manner, in addition to 
those that are required!  
+
+
+### Simple Monitoring
+
+The final section determines how Brooklyn confirms that the service is up.
+Sophisticated solutions may install monitoring agents as part of the 
`launch_run_list`,
+with Brooklyn configured to read monitoring information to confirm the launch 
was successful.
+However for convenience, two common mechanisms are available out of the box:
+
+      #service_name: mysqld
+      pid_file: /var/run/mysqld/mysqld.pid
+
+If `service_name` is supplied, Brooklyn will check the return code of the 
`status` command
+run against that service, ensuring it is 0.  (Note that this is not 
universally reliable,
+although it is the same mechanism which Chef typically uses to test status 
when determining
+whether to start a service. Some services, e.g. postgres, will return 0 even 
if the service
+is not running.)
+
+If a `pid_file` is supplied, Brooklyn will check whether a process with the 
PID specified in that
+file is running. This has been selected for mysql because it appears to be 
more portable:
+the service name varies among OS's:  it is `mysqld` on CentOS but `mysql` on 
Ubuntu!
+
+
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/example_yaml/mysql-chef-1.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/example_yaml/mysql-chef-1.yaml 
b/guide/yaml/chef/example_yaml/mysql-chef-1.yaml
new file mode 100644
index 0000000..bdac530
--- /dev/null
+++ b/guide/yaml/chef/example_yaml/mysql-chef-1.yaml
@@ -0,0 +1,24 @@
+name: chef-mysql-sample
+services:
+- type: chef:mysql
+  
+  cookbook_urls:
+    # only needed for chef solo; URL can be local to brooklyn, or github, 
etc...
+    mysql: https://github.com/opscode-cookbooks/mysql/archive/v4.0.12.tar.gz
+    openssl: https://github.com/opscode-cookbooks/openssl/archive/v1.1.0.tar.gz
+    build-essential: 
https://github.com/opscode-cookbooks/build-essential/archive/v1.4.4.tar.gz
+  
+  launch_run_list: [ "mysql::server" ]
+  launch_attributes:
+    mysql:
+      # these attrs are required by the mysql cookbook under node['mysql']
+      server_root_password: p4ssw0rd
+      server_repl_password: p4ssw0rd
+      server_debian_password: p4ssw0rd
+      # many others are attrs are supported by the cookbook and can be passed 
here...
+      
+  # how to determine if the process is running and how to kill it
+  # (supported options are `service_name` and `pid_file`; normally you should 
just pick one.
+  # here we use the pid_file because the service_name varies, mysql on centos, 
mysqld on ubuntu!)
+  #service_name: mysqld
+  pid_file: /var/run/mysqld/mysqld.pid

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/example_yaml/mysql-chef-2.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/example_yaml/mysql-chef-2.yaml 
b/guide/yaml/chef/example_yaml/mysql-chef-2.yaml
new file mode 100644
index 0000000..ced2dbe
--- /dev/null
+++ b/guide/yaml/chef/example_yaml/mysql-chef-2.yaml
@@ -0,0 +1,28 @@
+name: chef-mysql-sample
+services:
+- type: chef:mysql
+  id: db
+  
+  cookbook_urls:
+    # only needed for chef solo; URL can be local to brooklyn, or github, 
etc...
+    mysql: https://github.com/opscode-cookbooks/mysql/archive/v4.0.12.tar.gz
+    openssl: https://github.com/opscode-cookbooks/openssl/archive/v1.1.0.tar.gz
+    build-essential: 
https://github.com/opscode-cookbooks/build-essential/archive/v1.4.4.tar.gz
+  
+  launch_run_list: [ "mysql::server" ]
+  launch_attributes:
+    mysql:
+      # these attrs are required by the mysql cookbook under node['mysql']
+      server_root_password: $brooklyn:component("db").config("mysql.password")
+      server_repl_password: $brooklyn:component("db").config("mysql.password")
+      server_debian_password: 
$brooklyn:component("db").config("mysql.password")
+      # many others are attrs are supported by the cookbook and can be passed 
here...
+      
+  # how to determine if the process is running and how to kill it
+  # (supported options are `service_name` and `pid_file`; normally you should 
just pick one.
+  # here we use the pid_file because the service_name varies, mysql on centos, 
mysqld on ubuntu!)
+  #service_name: mysqld
+  pid_file: /var/run/mysqld/mysqld.pid
+    
+brooklyn.config:
+  mysql.password: p4ssw0rd

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/index.md
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/index.md b/guide/yaml/chef/index.md
new file mode 100644
index 0000000..f0fa3d0
--- /dev/null
+++ b/guide/yaml/chef/index.md
@@ -0,0 +1,18 @@
+---
+title: Chef in YAML Blueprints
+layout: website-normal
+children:
+- about-chef.md
+- creating-blueprints.md
+- writing-chef.md
+- advanced-chef-integration.md
+---
+
+This guide describes how Brooklyn entities can be easily created from Chef 
cookbooks.
+As of this writing (May 2014) some of the integration points are under active 
development,
+and comments are welcome.
+A plan for the full integration is online 
[here](https://docs.google.com/a/cloudsoftcorp.com/document/d/18ZwzmncbJgJeQjnSvMapTWg6N526cvGMz5jaqdkxMf8).
  
+
+This guide assumes you are familiar with the basics of [creating YAML 
blueprints](../).
+
+{% include list-children.html %}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/chef/writing-chef.md
----------------------------------------------------------------------
diff --git a/guide/yaml/chef/writing-chef.md b/guide/yaml/chef/writing-chef.md
new file mode 100644
index 0000000..0593837
--- /dev/null
+++ b/guide/yaml/chef/writing-chef.md
@@ -0,0 +1,79 @@
+---
+title: Writing Chef for Blueprints
+title_in_menu: Writing Chef for Blueprints
+layout: website-normal
+---
+
+## Making it Simpler
+
+The example we've just seen shows how existing Chef cookbooks can be
+used as the basis for entities.  If you're *writing* the Chef recipes, 
+there are a few simple techniques we've established with the Chef community
+which make blueprints literally as simple as:
+
+    - type: chef:mysql
+      brooklyn.config:
+        mysql_password: p4ssw0rd
+        pid_file: /var/run/mysqld/mysqld.pid
+
+
+### Some Basic Conventions
+
+* **A `start` recipe**:
+  The first step is to provide a `start` recipe in `recipes/start.rb`;
+  if no `launch_run_list` is supplied, this is what will be invoked to launch 
the entity.
+  It can be as simple as a one-line file:
+
+      include_recipe 'mysql::server'
+
+* **Using `brooklyn.config`**:
+  All the `brooklyn.config` is passed to Chef as node attributes in the 
`node['brooklyn']['config']` namespace.
+  Thus if the required attributes in the mysql recipe are set to take a value 
set in
+  `node['brooklyn']['config']['mysql_password']`, you can dispense with the 
`launch_attributes` section.
+
+
+## Using Chef Server
+
+The examples so far have not required Chef Server, so they will work without 
any external
+Chef dependencies (besides the built-in install from 
`https://www.opscode.com/chef/install.sh`
+and the explicitly referenced cookbooks).  If you use Chef Server, however, 
you'll want your
+managed nodes to be integrated with it.  This is easy to set up, with a few 
options:
+
+If you have `knife` set up in your shell environment, the Brooklyn Chef 
support will use it
+by default. If the recipes are installed in your Chef server, you can go ahead 
and remove
+the `cookbooks_url` section!
+
+Use of `solo` or `knife` can be forced by setting the `chef_mode` flag 
(`brooklyn.chef.mode` config key)
+to either of those values.  (It defaults to `autodetect`, which will use 
`knife` if it is on the path and satisfies
+sanity checks).
+
+If you want to specify a different configuration, there are a number of config 
keys you can use:
+
+* `brooklyn.chef.knife.executableFile`: this should be point to the knife 
binary to use
+* `brooklyn.chef.knife.configFile`: this should point to the knife 
configuration to use
+* `brooklyn.chef.knife.setupCommands`: an optional set of commands to run 
prior to invoking knife,
+  for example to run `rvm` to get the right ruby version on the Brooklyn server
+
+If you're interested in seeing the Chef REST API be supported directly 
(without knife),
+please let us know.  We'd like to see this too, and we'll help you along the 
way!
+ 
+
+## Tips and Tricks
+
+To help you on your way writing Chef blueprints, here are a handful of pointers
+particularly useful in this context:
+
+* Configuration keys can be inherited from the top-level and accessed using 
`$brooklyn:component('id').config('key_name')`.
+  An example of this is shown in the `mysql-chef.yaml` sample recipe contained 
in the Brooklyn code base
+  and [here](example_yaml/mysql-chef-2.yaml) for convenience.
+  Here, `p4ssw0rd` is specified only once and then used for all the attributes 
required by the stock mysql cookbook.  
+
+* Github tarball downloads! You'll have noticed these in the example already, 
but they are so useful we thought
+  we'd call them out again. Except when you're developing, we recommend using 
specific tagged versions rather than master.
+
+* The usual machine `provisioning.properties` are supported with Chef 
blueprints, 
+  so you can set things like `minRam` and `osFamily`
+
+* To see more configuration options, and understand the ones presented here in 
more detail, see the javadoc or
+  the code for the class `ChefConfig` in the Brooklyn code base.
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/clusters-and-policies.md
----------------------------------------------------------------------
diff --git a/guide/yaml/clusters-and-policies.md 
b/guide/yaml/clusters-and-policies.md
new file mode 100644
index 0000000..fc65179
--- /dev/null
+++ b/guide/yaml/clusters-and-policies.md
@@ -0,0 +1,42 @@
+---
+title: Clusters and Policies
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+Now let's bring the concept of the "cluster" back in.
+We could wrap our appserver in the same `DynamicCluster` we used earlier,
+although then we'd need to define and configure the load balancer.
+But another blueprint, the `ControlledDynamicWebAppCluster`, does this for us.
+It takes the same `memberSpec`, so we can build a fully functional elastic 
3-tier
+deployment of our `hello-world-sql` application as follows:
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-clustered-w-db.yaml %}
+{% endhighlight %}
+
+This sets up Nginx as the controller by default, but that can be configured
+using the `controllerSpec` key. In fact, JBoss is the default appserver,
+and because configuration in Brooklyn is inherited by default,
+the same blueprint can be expressed more concisely as:
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-clustered-w-db-concise.yaml %}
+{% endhighlight %}
+ 
+The other nicety supplied by the `ControlledDynamicWebAppCluster` blueprint is 
that
+it aggregates sensors from the appserver, so we have access to things like
+`webapp.reqs.perSec.windowed.perNode`.
+These are convenient for plugging in to policies!
+We can set up our blueprint to do autoscaling based on requests per second
+(keeping it in the range 10..100, with a maximum of 5 appserver nodes)
+as follows: 
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-w-policy.yaml %}
+{% endhighlight %}
+
+Use your favorite load-generation tool (`jmeter` is one good example) to send 
a huge
+volume of requests against the server and see the policies kick in to resize 
it.
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/clusters.md
----------------------------------------------------------------------
diff --git a/guide/yaml/clusters.md b/guide/yaml/clusters.md
new file mode 100644
index 0000000..78b1df9
--- /dev/null
+++ b/guide/yaml/clusters.md
@@ -0,0 +1,34 @@
+---
+title: Clusters, Specs, and Composition
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+What if you want multiple machines?
+
+One way is just to repeat the `- type: 
org.apache.brooklyn.entity.software.base.EmptySoftwareProcess` block,
+but there's another way which will keep your powder 
[DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself):
+
+{% highlight yaml %}
+{% readj example_yaml/cluster-vm.yaml %}
+{% endhighlight %}
+
+Here we've composed the previous blueprint introducing some new important 
concepts, the `DynamicCluster`
+the `$brooklyn` DSL, and the "entity-spec".  Let's unpack these. 
+
+The `DynamicCluster` creates a set of homogeneous instances.
+At design-time, you specify an initial size and the specification for the 
entity it should create.
+At runtime you can restart and stop these instances as a group (on the 
`DynamicCluster`) or refer to them
+individually. You can resize the cluster, attach enrichers which aggregate 
sensors across the cluster, 
+and attach policies which, for example, replace failed members or resize the 
cluster dynamically.
+
+The specification is defined in the `memberSpec` key.  As you can see it looks 
very much like the
+previous blueprint, with one extra line.  Entries in the blueprint which start 
with `$brooklyn:`
+refer to the Brooklyn DSL and allow a small amount of logic to be embedded
+(if there's a lot of logic, it's recommended to write a blueprint YAML plugin 
or write the blueprint itself
+as a plugin, in Java or a JVM-supported language).  
+
+In this case we want to indicate that the parameter to `memberSpec` is an 
entity specification
+(`EntitySpec` in the underlying type system); the `entitySpec` DSL command 
will do this for us.
+The example above thus gives us 5 VMs identical to the one we created in the 
previous section.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/configuring-vms.md
----------------------------------------------------------------------
diff --git a/guide/yaml/configuring-vms.md b/guide/yaml/configuring-vms.md
new file mode 100644
index 0000000..97fb9d0
--- /dev/null
+++ b/guide/yaml/configuring-vms.md
@@ -0,0 +1,31 @@
+---
+title: Configuring VMs
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+Another simple blueprint will just create a VM which you can use, without any 
software installed upon it:
+
+{% highlight yaml %}
+{% readj example_yaml/simple-vm.yaml %}
+{% endhighlight %}
+
+
+*We've omitted the `location` section here and in many of the examples below;
+add the appropriate choice when you paste your YAML. Note that the 
`provisioning.properties` will be
+ignored if deploying to `localhost` or `byon` fixed-IP machines.* 
+
+This will create a VM with the specified parameters in your choice of cloud.
+In the GUI (and in the REST API), the entity is called "VM",
+and the hostname and IP address(es) are reported as [sensors]({{ 
site.path.guide }}/concepts/entities.html).
+There are many more `provisioning.properties` supported here,
+including:
+
+* a `user` to create (if not specified it creates the same username as 
`brooklyn` is running under) 
+* a `password` for him or a `publicKeyFile` and `privateKeyFile` (defaulting 
to keys in `~/.ssh/id_rsa{.pub,}` and no password,
+  so if you have keys set up you can immediately ssh in!)
+* `machineCreateAttempts` (for dodgy clouds, and they nearly all fail 
occasionally!) 
+* and things like `imageId` and `userMetadata` and disk and networking options 
(e.g. `autoAssignFloatingIp` for private clouds)
+
+For more information, see [Operations: Locations](../ops/locations/).

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/creating-yaml.md
----------------------------------------------------------------------
diff --git a/guide/yaml/creating-yaml.md b/guide/yaml/creating-yaml.md
new file mode 100644
index 0000000..ffb1e36
--- /dev/null
+++ b/guide/yaml/creating-yaml.md
@@ -0,0 +1,78 @@
+---
+title: The Basic Structure
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+## A First Blueprint
+
+The easiest way to write a blueprint is as a YAML file.
+This follows the  <a href="https://www.oasis-open.org/committees/camp/";>OASIS 
CAMP</a> plan specification, 
+with some extensions described below.
+(A [YAML reference](yaml-reference.html) has more information,
+and if the YAML doesn't yet do what you want,
+it's easy to add new extensions using your favorite JVM language.)
+
+### The Basic Structure
+
+Here's a very simple YAML blueprint plan, to explain the structure:
+
+{% highlight yaml %}
+{% readj example_yaml/simple-appserver.yaml %}
+{% endhighlight %}
+
+* The `name` is just for the benefit of us humans.
+
+* The `location` specifies where this should be deployed.
+  If you've [set up passwordless localhost SSH 
access](../ops/locations/#localhost) 
+  you can use `localhost` as above, but if not, just wait ten seconds for the 
next example.
+  
+* The `services` block takes a list of the typed services we want to deploy.
+  This is the meat of the blueprint plan, as you'll see below.
+
+Finally, the clipboard in the top-right corner of the example plan box above 
(hover your cursor over the box)  lets you easily copy-and-paste into the 
web-console:
+simply [download and launch]({{ site.path.guide }}/start/running.html) 
Brooklyn,
+then in the "Create Application" dialog at the web console
+(usually [http://127.0.0.1:8081/](http://127.0.0.1:8081/), paste the copied 
YAML into the "Yaml" tab of the dialog and press "Finish". 
+There are several other ways to deploy, including `curl` and via the 
command-line,
+and you can configure users, https, persistence, and more, 
+as described [in the ops guide](../ops/).
+
+[![Web Console](web-console-yaml-700.png "YAML via Web 
Console")](web-console-yaml.png)
+
+
+
+<!--
+TODO building up children entities
+
+-->
+
+
+
+### More Information
+
+Topics to explore next on the topic of YAML blueprints are:
+
+{% include list-children.html %}
+
+Plenty of examples of blueprints exist in the Brooklyn codebase,
+so another starting point is to [`git clone`]({{ site.path.guide 
}}/dev/code/index.html) it
+and search for `*.yaml` files therein.
+
+Brooklyn lived as a Java framework for many years before we felt confident
+to make a declarative front-end, so you can do pretty much anything you want to
+by dropping to the JVM. For more information on Java:
+
+* start with a [Maven archetype]({{site.path.guide}}/java/archetype.html)
+* see all [Brooklyn Java guide]({{site.path.guide}}/java/) topics
+* look at test cases in the 
[codebase](https://github.com/apache/incubator-brooklyn)
+
+<!-- 
+TODO
+* review some [examples]({{site.path.guide}}/use/examples/index.html)
+-->
+
+You can also come talk to us, on IRC (#brooklyncentral on Freenode) or
+any of the usual [hailing frequencies]({{site.path.website}}/community/),
+as these documents are a work in progress.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/custom-entities.md
----------------------------------------------------------------------
diff --git a/guide/yaml/custom-entities.md b/guide/yaml/custom-entities.md
new file mode 100644
index 0000000..9698aa8
--- /dev/null
+++ b/guide/yaml/custom-entities.md
@@ -0,0 +1,238 @@
+---
+title: Custom Entities
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+So far we've covered how to configure and compose entities.
+There's a large library of blueprints available, but
+there are also times when you'll want to write your own.
+
+For complex use cases, you can write JVM, but for many common situations,
+some of the highly-configurable blueprints make it easy to write in YAML,
+including `bash` and Chef.
+ 
+
+### Vanilla Software using `bash`
+
+The following blueprint shows how a simple script can be embedded in the YAML
+(the `|` character is special YAML which makes it easier to insert multi-line 
text):
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat.yaml %}
+{% endhighlight %}
+
+This starts a simple `nc` listener on port 4321 which will respond `hello` to 
the first
+session which connects to it. Test it by running `telnet localhost 4321`
+or opening `http://localhost:4321` in a browser.
+
+Note that it only allows you connect once, and after that it fails.
+This is deliberate! We'll repair this later in this example.
+Until then however, in the *Applications* view you can click the server,
+go to the `Effectors` tab, and click `restart` to bring if back to life.  
+
+This is just a simple script, but it shows how any script can be easily 
embedded here,
+including a script to download and run other artifacts.
+Many artifacts are already packaged such that they can be downloaded and 
launched 
+with a simple script, and `VanillaSoftwareProcess` can also be used for them. 
+
+
+#### Downloading Files
+
+We can specify a `download.url` which downloads an artifact 
+(and automatically unpacking TAR, TGZ, and ZIP archives)
+before running `launch.command` relative to where that file is installed (or 
unpacked),
+with the default `launch.command` being `./start.sh`.
+
+So if we create a file `/tmp/netcat-server.tgz` containing just `start.sh` in 
the root
+which consists of the two lines in the previous example,
+we can instead write our example as: 
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-file.yaml %}
+{% endhighlight %}
+
+
+#### Port Inferencing
+
+If you're deploying to a cloud machine, a firewall might block the port 4321.
+We can tell Brooklyn to open this port explicitly by specifying `inboundPorts: 
[ 4321 ]`;
+however a more idiomatic way is to specify a config ending with `.port`,
+such as:
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-port.yaml %}
+{% endhighlight %}
+
+The regex for ports to be opened can be configured using
+the config `inboundPorts.configRegex` (which has `.*\.port` as the default 
value).
+
+Config keys of type `org.apache.brooklyn.api.location.PortRange` (aka `port`)
+have special behaviour: when configuring, you can use range notation 
`8000-8100` or `8000+` to tell Brooklyn
+to find **one** port matching; this is useful when ports might be in use.
+In addition, any such config key will be opened, 
+irrespective of whether it matches the `inboundPorts.configRegex`. 
+To prevent any inferencing of ports to open, you can set the config 
`inboundPorts.autoInfer` to `false`.
+
+Note that in the example above, `netcat.port` must be specified in a 
`brooklyn.config` block.
+This block can be used to hold any config (including for example the 
`launch.command`),
+but for convenience Brooklyn allows config keys declared on the underlying type
+to be specified up one level, alongside the type.
+However config keys which are *not* declared on the type *must* be declared in 
the `brooklyn.config` block. 
+
+
+#### Declaring New Config Keys
+
+We can define config keys to be presented to the user 
+using the `brooklyn.parameters` block:
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-port-parameter.yaml %}
+{% endhighlight %}
+
+The example above will allow a user to specify a message to send back
+and the port where netcat will listen.
+The metadata on these parameters is available at runtime in the UI
+and through the API, and is used when populating a catalog.
+
+The example also shows how these values can be passed as environment variables 
to the launch command.
+The `$brooklyn:config(...)` function returns the config value supplied or 
default.
+For the type `port`, an attribute sensor is also created to report the 
*actual* port used after port inference,
+and so the `$brooklyn:attributeWhenReady(...)` function is used.
+(If `$brooklyn:config("netcat.port")` had been used, `4321+` would be passed 
as `NETCAT_PORT`.)
+
+This gives us quite a bit more power in writing our blueprint:
+
+* Multiple instances of the server can be launched simultaneously on the same 
host, 
+  as the `4321+` syntax enables Brooklyn to assign them different ports
+* If this type is added to the catalog, a user can configure the message and 
the port;
+  we'll show this in the next section
+
+
+#### Using the Catalog and Clustering
+
+The *Catalog* tab allows you to add blueprints which you can refer to in other 
blueprints.
+In that tab, click *+* then *YAML*, and enter the following:
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-catalog.bom %}
+{% endhighlight %}
+
+This is the same example as in the previous section, wrapped according to the 
catalog YAML requirements,
+with one new block added defining an enricher. An enricher creates a new 
sensor from other values;
+in this case it will create a `main.uri` sensor by populating a `printf`-style 
string `"http://%s:%s"`
+with the sensor values.
+
+With this added to the catalog, we can reference the type `netcat-example` 
when we deploy an application.
+Return to the *Home* or *Applications* tab, click *+*, and submit this YAML 
blueprint:
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-reference.yaml %}
+{% endhighlight %}
+
+This extends the previous blueprint which we registered in the catalog,
+meaning that we don't need to include it each time.
+Here, we've elected to supply our own message, but we'll use the default port.
+More importantly, we can package it for others to consume -- or take items 
others have built.
+
+We can go further and use this to deploy a cluster,
+this time giving a custom port as well as a custom message: 
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-cluster.yaml %}
+{% endhighlight %}
+
+In either of the above examples, if you explore the tree in the *Applications* 
view
+and look at the *Summary* tab of any of the server instances, you'll now see 
the URL where netcat is running.
+But remember, netcat will stop after one run, so you'll only be able to use 
each link once
+before you have to restart it.  You can also run `restart` on the cluster,
+and if you haven't yet experimented with `resize` on the cluster you might 
want to do that.
+
+
+#### Determining Successful Launch
+
+One requirement of the launch script is that it store the process ID (PID) in 
the file
+pointed to by `$PID_FILE`, hence the second line of the script.
+This is because Brooklyn wants to monitor the services under management.
+You'll observe this if you connect to one of the netcat services,
+as the process exits afterwards and Brooklyn sets the entity to an `ON_FIRE` 
state.
+(You can also test this with a `killall nc` before connecting
+or issueing a `stop` command on the server -- but not on the example,
+as stopping an application root causes it to be removed altogether!) 
+
+There are other options for determining launch: you can set 
`checkRunning.command` and `stop.command` instead,
+as documented on the javadoc and config keys of the {% include java_link.html 
class_name="VanillaSoftwareProcess" 
package_path="org/apache/brooklyn/entity/software/base" 
project_subpath="software/base" %} class,
+and those scripts will be used instead of checking and stopping the process 
whose PID is in `$PID_FILE`.
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-more-commands.yaml %}
+{% endhighlight %}
+
+And indeed, once you've run one `telnet` to the server, you'll see that the 
+service has gone "on fire" in Brooklyn -- because the `nc` process stops after 
one run. 
+
+
+#### Attaching Policies
+
+Besides detecting this failure, Brooklyn policies can be added to the YAML to 
take appropriate 
+action. A simple recovery here might just to automatically restart the process:
+
+{% highlight yaml %}
+{% readj example_yaml/vanilla-bash-netcat-restarter.yaml %}
+{% endhighlight %}
+
+Autonomic management in Brooklyn often follows the principle that complex 
behaviours emerge
+from composing simple policies.
+The blueprint above uses one policy to triggering a failure sensor when the 
service is down,
+and another responds to such failures by restarting the service.
+This makes it easy to configure various aspects, such as to delay to see if 
the service itself recovers
+(which here we've set to 15 seconds) or to bail out on multiple failures 
within a time window (which again we are not doing).
+Running with this blueprint, you'll see that the service shows as on fire for 
15s after a `telnet`,
+before the policy restarts it. 
+
+
+### Sensors and Effectors
+
+For an even more interesting way to test it, look at the blueprint defining
+[a netcat server and client](example_yaml/vanilla-bash-netcat-w-client.yaml).
+This uses `initializers` to define an effector to `sayHiNetcat` on the `Simple 
Pinger` client,
+using `env` variables to inject the `netcat-server` location and 
+`parameters` to pass in per-effector data:
+
+      env:
+        TARGET_HOSTNAME: 
$brooklyn:component("netcat-server").attributeWhenReady("host.name")
+      brooklyn.initializers:
+      - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector
+        brooklyn.config:
+          name: sayHiNetcat
+          description: Echo a small hello string to the netcat entity
+          command: |
+            echo $message | nc $TARGET_HOSTNAME 4321
+          parameters:
+            message:
+              description: The string to pass to netcat
+              defaultValue: hi netcat
+
+This blueprint also uses initializers to define sensors on the `netcat-server` 
entity
+so that the `$message` we passed above gets logged and reported back:
+
+      launch.command: |
+        echo hello | nc -l 4321 >> server-input &
+        echo $! > $PID_FILE
+      brooklyn.initializers:
+      - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+        brooklyn.config:
+          name: output.last
+          period: 1s
+          command: tail -1 server-input
+
+
+#### Summary
+
+These examples are relatively simple example, but they
+illustrate many of the building blocks used in real-world blueprints,
+and how they can often be easily described and combined in Brooklyn YAML 
blueprints.
+Next, if you need to drive off-piste, or you want to write tests against these 
blueprints,
+have a look at, for example, `VanillaBashNetcatYamlTest.java` in the Brooklyn 
codebase,
+or follow the other references below.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-clustered-w-db-concise.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-clustered-w-db-concise.yaml 
b/guide/yaml/example_yaml/appserver-clustered-w-db-concise.yaml
new file mode 100644
index 0000000..0fd8759
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-clustered-w-db-concise.yaml
@@ -0,0 +1,15 @@
+name: appserver-clustered-w-db-concise
+services:
+- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  initialSize: 2
+  brooklyn.config:
+    wars.root: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+    http.port: 8080+
+    java.sysprops: 
+      brooklyn.example.db.url: 
$brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+           component("db").attributeWhenReady("datastore.url"), "visitors", 
"brooklyn", "br00k11n")
+- type: org.apache.brooklyn.entity.database.mysql.MySqlNode
+  id: db
+  name: DB HelloWorld Visitors
+  brooklyn.config:
+    datastore.creation.script.url: 
https://github.com/apache/incubator-brooklyn/raw/master/usage/launcher/src/test/resources/visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-clustered-w-db.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-clustered-w-db.yaml 
b/guide/yaml/example_yaml/appserver-clustered-w-db.yaml
new file mode 100644
index 0000000..8bbb14f
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-clustered-w-db.yaml
@@ -0,0 +1,18 @@
+name: appserver-clustered-w-db
+services:
+- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  initialSize: 2
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+      brooklyn.config:
+        wars.root: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+        http.port: 8080+
+        java.sysprops: 
+          brooklyn.example.db.url: 
$brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+              component("db").attributeWhenReady("datastore.url"), "visitors", 
"brooklyn", "br00k11n")
+- type: org.apache.brooklyn.entity.database.mysql.MySqlNode
+  id: db
+  name: DB HelloWorld Visitors
+  brooklyn.config:
+    datastore.creation.script.url: 
https://github.com/apache/incubator-brooklyn/raw/master/usage/launcher/src/test/resources/visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-configured-in-config.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-configured-in-config.yaml 
b/guide/yaml/example_yaml/appserver-configured-in-config.yaml
new file mode 100644
index 0000000..f817dd7
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-configured-in-config.yaml
@@ -0,0 +1,6 @@
+name: appserver-configured-in-config
+services:
+- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+  brooklyn.config:
+    wars.root: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+    http.port: 8080

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-configured.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-configured.yaml 
b/guide/yaml/example_yaml/appserver-configured.yaml
new file mode 100644
index 0000000..58416ca
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-configured.yaml
@@ -0,0 +1,5 @@
+name: appserver-configured
+services:
+- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+  war: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+  httpPort: 8080

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-w-db-other-flavor.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-w-db-other-flavor.yaml 
b/guide/yaml/example_yaml/appserver-w-db-other-flavor.yaml
new file mode 100644
index 0000000..ac1106e
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-w-db-other-flavor.yaml
@@ -0,0 +1,17 @@
+name: appserver-w-db-other-flavor
+services:
+- type: org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
+  name: AppServer HelloWorld 
+  brooklyn.config:
+    wars.root: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+    http.port: 8080+
+    java.sysprops: 
+      brooklyn.example.db.url: 
$brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+         component("db").attributeWhenReady("datastore.url"), "visitors", 
"brooklyn", "br00k11n")
+- type: org.apache.brooklyn.entity.database.mariadb.MariaDbNode
+  id: db
+  name: DB HelloWorld Visitors
+  brooklyn.config:
+    datastore.creation.script.url: 
https://github.com/apache/incubator-brooklyn/raw/master/usage/launcher/src/test/resources/visitors-creation-script.sql
+    provisioning.properties:
+      minRam: 8192

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-w-db.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-w-db.yaml 
b/guide/yaml/example_yaml/appserver-w-db.yaml
new file mode 100644
index 0000000..0e9d959
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-w-db.yaml
@@ -0,0 +1,15 @@
+name: appserver-w-db
+services:
+- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+  name: AppServer HelloWorld 
+  brooklyn.config:
+    wars.root: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+    http.port: 8080+
+    java.sysprops: 
+      brooklyn.example.db.url: 
$brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+         component("db").attributeWhenReady("datastore.url"), "visitors", 
"brooklyn", "br00k11n")
+- type: org.apache.brooklyn.entity.database.mysql.MySqlNode
+  id: db
+  name: DB HelloWorld Visitors
+  brooklyn.config:
+    datastore.creation.script.url: 
https://github.com/apache/incubator-brooklyn/raw/master/usage/launcher/src/test/resources/visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/appserver-w-policy.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/appserver-w-policy.yaml 
b/guide/yaml/example_yaml/appserver-w-policy.yaml
new file mode 100644
index 0000000..52bc3b8
--- /dev/null
+++ b/guide/yaml/example_yaml/appserver-w-policy.yaml
@@ -0,0 +1,26 @@
+name: appserver-w-policy
+services:
+- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  initialSize: 1
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+      brooklyn.config:
+        wars.root: 
http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
+        http.port: 8080+
+        java.sysprops: 
+          brooklyn.example.db.url: 
$brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+              component("db").attributeWhenReady("datastore.url"), "visitors", 
"brooklyn", "br00k11n")
+  brooklyn.policies:
+  - policyType: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+    brooklyn.config:
+      metric: $brooklyn:sensor("brooklyn.entity.webapp.DynamicWebAppCluster", 
"webapp.reqs.perSec.windowed.perNode")
+      metricLowerBound: 10
+      metricUpperBound: 100
+      minPoolSize: 1
+      maxPoolSize: 5
+- type: org.apache.brooklyn.entity.database.mysql.MySqlNode
+  id: db
+  name: DB HelloWorld Visitors
+  brooklyn.config:
+    datastore.creation.script.url: 
https://github.com/apache/incubator-brooklyn/raw/master/usage/launcher/src/test/resources/visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/brooklyn-elasticsearch-catalog.bom
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/brooklyn-elasticsearch-catalog.bom 
b/guide/yaml/example_yaml/brooklyn-elasticsearch-catalog.bom
new file mode 100644
index 0000000..bbed240
--- /dev/null
+++ b/guide/yaml/example_yaml/brooklyn-elasticsearch-catalog.bom
@@ -0,0 +1,124 @@
+brooklyn.catalog:
+  id: elasticsearch
+  version: 1.0
+  iconUrl: https://avatars0.githubusercontent.com/u/6764390?v=3&s=400
+  name: Elasticsearch
+  license: Apache-2.0
+  issues_url: https://github.com/Graeme-Miller/brooklyn-elasticsearch/issues
+  item:
+    type: brooklyn.entity.group.DynamicCluster
+    initialSize: 2
+    name: Elasticsearch Cluster
+    id: elasticsearch-cluster
+    description: A cluster of Elasticsearch nodes
+
+    brooklyn.config:
+      install.version: 1.7.1
+      elasticsearch.http.port: 9220
+      elasticsearch.tcp.port: 9330
+
+    brooklyn.enrichers:
+      - type: org.apache.brooklyn.enricher.stock.Aggregator
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("url.tcp")
+          enricher.targetSensor: $brooklyn:sensor("urls.tcp.list")
+          enricher.aggregating.fromMembers: true
+      - type: org.apache.brooklyn.enricher.stock.Joiner
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("urls.tcp.list")
+          enricher.targetSensor: $brooklyn:sensor("urls.tcp.string")
+          uniqueTag: urls.quoted.string
+      - type: org.apache.brooklyn.enricher.stock.Transformer
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("urls.tcp.string")
+          enricher.targetSensor: $brooklyn:sensor("urls.tcp.withBrackets")
+          enricher.targetValue: $brooklyn:formatString("[%s]", 
$brooklyn:attributeWhenReady("urls.tcp.string"))
+      - type: org.apache.brooklyn.enricher.stock.Aggregator
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("url.http")
+          enricher.targetSensor: $brooklyn:sensor("urls.http.list")
+          enricher.aggregating.fromMembers: true
+      - type: org.apache.brooklyn.enricher.stock.Joiner
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("urls.http.list")
+          enricher.targetSensor: $brooklyn:sensor("urls.http.string")
+          uniqueTag: urls.http.quoted.string
+      - type: org.apache.brooklyn.enricher.stock.Transformer
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("urls.http.string")
+          enricher.targetSensor: $brooklyn:sensor("urls.http.withBrackets")
+          enricher.targetValue: $brooklyn:formatString("[%s]", 
$brooklyn:attributeWhenReady("urls.http.string"))
+      - type: org.apache.brooklyn.enricher.stock.Aggregator
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("host.address")
+          enricher.targetSensor: $brooklyn:sensor("host.address.first")
+          enricher.aggregating.fromMembers: true
+          enricher.transformation:
+           $brooklyn:object:
+             type: 
"org.apache.brooklyn.util.collections.CollectionFunctionals$FirstElementFunction"
+
+    memberSpec:
+      $brooklyn:entitySpec:
+        - type: brooklyn.entity.basic.VanillaSoftwareProcess
+          name: Elasticsearch Node
+
+          provisioning.properties:
+            osFamily: ubuntu
+            inboundPorts:
+              - $brooklyn:config("elasticsearch.http.port")
+              - $brooklyn:config("elasticsearch.tcp.port")
+
+          install.command: |
+            $brooklyn:formatString("
+            sudo apt-get update
+            sudo apt-get install -y openjdk-7-jdk wget
+
+            wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | 
sudo apt-key add -
+            echo \"deb http://packages.elastic.co/elasticsearch/1.7/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.7.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.6/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.6.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.5/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.5.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.4/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.4.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.3/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.3.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.2/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.2.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.1/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.1.list
+            echo \"deb http://packages.elastic.co/elasticsearch/1.0/debian 
stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.0.list
+            sudo apt-get update && sudo apt-get -y install elasticsearch=%s
+            ",
+            $brooklyn:config("install.version")
+            )
+
+          customize.command: |
+            $brooklyn:formatString("
+            sudo rm -fr sudo tee /etc/elasticsearch/elasticsearch.yml;
+            echo discovery.zen.ping.multicast.enabled: false | sudo tee -a 
/etc/elasticsearch/elasticsearch.yml;
+            echo discovery.zen.ping.unicast.enabled: true | sudo tee -a 
/etc/elasticsearch/elasticsearch.yml;
+            echo 'discovery.zen.ping.unicast.hosts: %s' | sudo tee -a 
/etc/elasticsearch/elasticsearch.yml;
+            echo http.port: %s | sudo tee -a 
/etc/elasticsearch/elasticsearch.yml;
+            echo transport.tcp.port: %s | sudo tee -a 
/etc/elasticsearch/elasticsearch.yml;
+            ",
+            $brooklyn:component("parent", 
"").attributeWhenReady("urls.tcp.withBrackets"),
+            $brooklyn:config("elasticsearch.http.port"),
+            $brooklyn:config("elasticsearch.tcp.port")
+            )
+
+
+          launch.command: sudo service elasticsearch start
+
+          stop.command: sudo service elasticsearch stop
+
+          checkRunning.command: |
+            $brooklyn:formatString("counter=`wget -T 15 -q -O- %s:%s | grep -c 
\"status. : 200\"`; if [ $counter -eq 0 ]; then exit 1; fi",
+            $brooklyn:attributeWhenReady("host.address"),
+            $brooklyn:config("elasticsearch.http.port"))
+
+          brooklyn.enrichers:
+            - type: org.apache.brooklyn.enricher.stock.Transformer
+              brooklyn.config:
+                enricher.sourceSensor: $brooklyn:sensor("host.address")
+                enricher.targetSensor: $brooklyn:sensor("url.tcp")
+                enricher.targetValue: $brooklyn:formatString("%s:%s", 
$brooklyn:attributeWhenReady("host.address"), 
$brooklyn:config("elasticsearch.tcp.port"))
+            - type: org.apache.brooklyn.enricher.stock.Transformer
+              brooklyn.config:
+                enricher.sourceSensor: $brooklyn:sensor("host.address")
+                enricher.targetSensor: $brooklyn:sensor("url.http")
+                enricher.targetValue: $brooklyn:formatString("%s:%s", 
$brooklyn:attributeWhenReady("host.address"), 
$brooklyn:config("elasticsearch.http.port"))

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/brooklyn-elk-catalog.bom
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/brooklyn-elk-catalog.bom 
b/guide/yaml/example_yaml/brooklyn-elk-catalog.bom
new file mode 100644
index 0000000..6fc11f4
--- /dev/null
+++ b/guide/yaml/example_yaml/brooklyn-elk-catalog.bom
@@ -0,0 +1,35 @@
+brooklyn.catalog:
+  version: 1.0
+  iconUrl: https://avatars0.githubusercontent.com/u/6764390?v=3&s=400
+  license: Apache-2.0
+  issues_url: https://github.com/Graeme-Miller/brooklyn-elk/issues
+  itemType: template
+  item:
+    type: org.apache.brooklyn.entity.stock.BasicApplication
+    name: ELK Stack
+    id: ELK-Stack
+    description: |
+      Simple ELK stack deployment: provisions Elasticsearch, Kibana and 
Logtash as a child of Apache Tomcat 8
+    services:
+      - type: elasticsearch
+        id: es
+        name:  Elasticsearch Cluster
+        brooklyn.config:
+          install.version: 1.4.4
+      - type: kibana-standalone
+        id: kibana
+        name: Kibana Server
+        customize.latch: 
$brooklyn:component("es").attributeWhenReady("service.isUp")
+        brooklyn.config:
+          kibana.elasticsearch.ip: 
$brooklyn:component("es").attributeWhenReady("host.address.first")
+          kibana.elasticsearch.port: 
$brooklyn:component("es").config("elasticsearch.http.port")
+      - type: org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server
+        id: tomcat
+        customize.latch: 
$brooklyn:component("es").attributeWhenReady("service.isUp")
+        brooklyn.config:
+          children.startable.mode: background_late
+        brooklyn.children:
+        - type: logstash-child
+          name: Logstash Child
+          brooklyn.config:
+            logstash.elasticsearch.host: 
$brooklyn:component("es").attributeWhenReady("urls.http.withBrackets")

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/brooklyn-kibana-catalog.bom
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/brooklyn-kibana-catalog.bom 
b/guide/yaml/example_yaml/brooklyn-kibana-catalog.bom
new file mode 100644
index 0000000..ee006d2
--- /dev/null
+++ b/guide/yaml/example_yaml/brooklyn-kibana-catalog.bom
@@ -0,0 +1,52 @@
+brooklyn.catalog:
+  version: 0.0.2
+  iconUrl: http://blog.arungupta.me/wp-content/uploads/2015/07/kibana-logo.png
+  items:
+  - id: kibana-standalone
+    name: "Kibana server"
+    description: "Single Kibana server"
+    description: |
+       Kibana server. Callers should configure 'kibana.elasticsearch.ip'
+    item:
+      type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+      provisioning.properties:
+        osFamily: ubuntu
+
+      brooklyn.config:
+        install.version: "4.1.1"
+        kibana.elasticsearch.ip: 127.0.0.1  # must be supplied by caller!
+        kibana.elasticsearch.port: 9200  # must be supplied by caller!
+        kibana.port: 5601
+
+      shell.env:
+        KIBANA_VERSION: $brooklyn:config("install.version")
+        ELASTICSEARCH_IP: $brooklyn:config("kibana.elasticsearch.ip")
+        ELASTICSEARCH_PORT: $brooklyn:config("kibana.elasticsearch.port")
+        KIBANA_PORT: $brooklyn:config("kibana.port")
+
+      install.command: |
+        # Install required dependencies
+        sudo apt-get update
+        sudo DEBIAN_FRONTEND=noninteractive apt-get install -y 
--allow-unauthenticated tzdata openjdk-7-jdk wget
+
+        # download kibana
+        sudo mkdir -p /opt/kibana/
+        cd /opt/kibana
+        sudo chmod -R 777 /opt/kibana
+        wget -qO - 
https://download.elastic.co/kibana/kibana/kibana-${KIBANA_VERSION}-linux-x64.tar.gz
 | tar xz
+
+        # customize config file for kibana
+        sed -i 
's|http://localhost:9200|http://'"${ELASTICSEARCH_IP}"':'"${ELASTICSEARCH_PORT}"'|g'
 /opt/kibana/kibana-${KIBANA_VERSION}-linux-x64/config/kibana.yml
+        sed -i 's|5601|'"${KIBANA_PORT}"'|g' 
/opt/kibana/kibana-${KIBANA_VERSION}-linux-x64/config/kibana.yml
+        sed -i 's|# log_file: ./kibana.log|log_file: ./kibana.log|g' 
/opt/kibana/kibana-${KIBANA_VERSION}-linux-x64/config/kibana.yml
+
+      launch.command: |
+        nohup /opt/kibana/kibana-${KIBANA_VERSION}-linux-x64/bin/kibana  &
+        echo $! > $PID_FILE
+
+      brooklyn.enrichers:
+        - type: org.apache.brooklyn.enricher.stock.Transformer
+          brooklyn.config:
+            enricher.sourceSensor: $brooklyn:sensor("host.address")
+            enricher.targetSensor: $brooklyn:sensor("main.uri")
+            enricher.targetValue: $brooklyn:formatString("http://%s:%s";, 
$brooklyn:attributeWhenReady("host.address"), $brooklyn:config("kibana.port"))

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/brooklyn-logstash-catalog.bom
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/brooklyn-logstash-catalog.bom 
b/guide/yaml/example_yaml/brooklyn-logstash-catalog.bom
new file mode 100644
index 0000000..7c431f5
--- /dev/null
+++ b/guide/yaml/example_yaml/brooklyn-logstash-catalog.bom
@@ -0,0 +1,59 @@
+brooklyn.catalog:
+  version: 1.5.5
+  iconUrl: http://logstash.net/images/logstash.png
+  items:
+  - id: logstash-standalone
+    name: "Logstash server"
+    description: "Single Logstash server"
+    item:
+      type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+      provisioning.properties:
+        osFamily: ubuntu
+
+      brooklyn.config:
+        install.version: "1.5.4"
+        logstash.config.input: input { file { path => "/var/log/*" } }
+        logstash.config.filter: ''
+        logstash.config.output: output { stdout { } }
+        logstash.config.dir: /etc/logstash/conf.d/
+
+      shell.env:
+        VERSION: $brooklyn:config("install.version")
+        INPUT_CONFIG: $brooklyn:config("logstash.config.input")
+        FILTER_CONFIG: $brooklyn:config("logstash.config.filter")
+        OUTPUT_CONFIG: $brooklyn:config("logstash.config.output")
+        CONFIG_DIR: $brooklyn:config("logstash.config.dir")
+
+      install.command: |
+        # Install required dependencies
+        sudo apt-get update
+        sudo DEBIAN_FRONTEND=noninteractive apt-get install -y 
--allow-unauthenticated tzdata openjdk-7-jdk wget
+
+        # download logstash
+        sudo mkdir -p /opt/logstash/
+        cd /opt/logstash
+        sudo chmod -R 777 /opt/logstash
+        wget -qO - 
https://download.elastic.co/logstash/logstash/logstash-${VERSION}.tar.gz | tar 
xz
+
+        # add a config file for logstash
+        sudo mkdir -p ${CONFIG_DIR}
+        echo "${INPUT_CONFIG} ${FILTER_CONFIG} ${OUTPUT_CONFIG}" | sudo tee 
${CONFIG_DIR}/01-basic.conf
+
+      launch.command: |
+        sudo mkdir -p /var/log/logstash/
+        sudo chmod -R 777 /var/log/logstash/
+        nohup /opt/logstash/logstash-${VERSION}/bin/logstash agent -f 
${CONFIG_DIR} -l /var/log/logstash/logstash.log &
+        echo $! > $PID_FILE
+  - id: logstash-child
+    name: "Logstash Child"
+    description: |
+       Logstash server to be embedded as a child of a SoftwareProcess who
+       publishes his 'log.location' as a sensor.
+       Callers should configure 'logstash.elasticsearch.host' (if using ES)
+       or 'logstash.config.output'.
+    item:
+      type: logstash-standalone
+      brooklyn.config:
+        logstash.config.input: $brooklyn:formatString("input { file { path => 
\"%s\" start_position => \"beginning\" } }", 
$brooklyn:parent().attributeWhenReady("log.location"))
+        logstash.elasticsearch.host: 127.0.0.1:9200  # must be supplied by 
caller!
+        logstash.config.output: $brooklyn:formatString("output { elasticsearch 
{ host => %s protocol => \"http\" embedded => false } }", 
$brooklyn:config("logstash.elasticsearch.host"))

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/cluster-vm.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/cluster-vm.yaml 
b/guide/yaml/example_yaml/cluster-vm.yaml
new file mode 100644
index 0000000..2b57f4e
--- /dev/null
+++ b/guide/yaml/example_yaml/cluster-vm.yaml
@@ -0,0 +1,12 @@
+name: cluster-vm
+services:
+- type: org.apache.brooklyn.entity.group.DynamicCluster
+  initialSize: 5
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
+      name: VM
+      provisioning.properties:
+        minRam: 8g
+        minCores: 4
+        minDisk: 100g

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/simple-appserver-with-location-byon.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/simple-appserver-with-location-byon.yaml 
b/guide/yaml/example_yaml/simple-appserver-with-location-byon.yaml
new file mode 100644
index 0000000..8e9c951
--- /dev/null
+++ b/guide/yaml/example_yaml/simple-appserver-with-location-byon.yaml
@@ -0,0 +1,12 @@
+name: simple-appserver-with-location-byon
+location:
+  byon:
+    user: brooklyn
+    privateKeyFile: ~/.ssh/brooklyn.pem
+    hosts:
+    - 192.168.0.18
+    - 192.168.0.19
+services:
+- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+  location:
+    byon:(hosts="127.0.0.1")

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/simple-appserver-with-location.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/simple-appserver-with-location.yaml 
b/guide/yaml/example_yaml/simple-appserver-with-location.yaml
new file mode 100644
index 0000000..79344c8
--- /dev/null
+++ b/guide/yaml/example_yaml/simple-appserver-with-location.yaml
@@ -0,0 +1,8 @@
+name: simple-appserver-with-location
+location:
+  jclouds:aws-ec2:
+    region: us-east-1
+    identity: AKA_YOUR_ACCESS_KEY_ID
+    credential: <access-key-hex-digits>
+services:
+- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/simple-appserver.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/simple-appserver.yaml 
b/guide/yaml/example_yaml/simple-appserver.yaml
new file mode 100644
index 0000000..8e9d76a
--- /dev/null
+++ b/guide/yaml/example_yaml/simple-appserver.yaml
@@ -0,0 +1,4 @@
+name: simple-appserver
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/simple-vm.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/simple-vm.yaml 
b/guide/yaml/example_yaml/simple-vm.yaml
new file mode 100644
index 0000000..8f6447c
--- /dev/null
+++ b/guide/yaml/example_yaml/simple-vm.yaml
@@ -0,0 +1,8 @@
+name: simple-vm
+services:
+- type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
+  name: VM
+  provisioning.properties:
+    minRam: 8192mb
+    minCores: 4
+    minDisk: 100gb

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/test-app-with-enrichers-slightly-simpler.yaml
----------------------------------------------------------------------
diff --git 
a/guide/yaml/example_yaml/test-app-with-enrichers-slightly-simpler.yaml 
b/guide/yaml/example_yaml/test-app-with-enrichers-slightly-simpler.yaml
new file mode 100644
index 0000000..55d5b87
--- /dev/null
+++ b/guide/yaml/example_yaml/test-app-with-enrichers-slightly-simpler.yaml
@@ -0,0 +1,57 @@
+#
+# example showing how enrichers can be set 
+#
+name: test-app-with-enrichers
+description: Testing many enrichers
+services:
+- type: org.apache.brooklyn.entity.group.DynamicCluster
+  id: cluster
+  initialSize: 3
+  location: localhost
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.core.test.entity.TestEntity
+      brooklyn.enrichers:
+      - type: org.apache.brooklyn.enricher.stock.Transformer
+        # transform "ip" (which we expect a feed, not shown here, to set) to a 
URL;
+        # you can curl an address string to the sensors/ip endpoint an entity 
to trigger these enrichers 
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("ip")
+          enricher.targetSensor: $brooklyn:sensor("url")
+          enricher.targetValue: $brooklyn:formatString("http://%s/";, 
$brooklyn:attributeWhenReady("ip"))
+      - type: org.apache.brooklyn.enricher.stock.Propagator
+        # use propagator to duplicate one sensor as another, giving the 
supplied sensor mapping;
+        # the other use of Propagator is where you specify a producer (using 
$brooklyn:entity(...) as below)
+        # from which to take sensors; in that mode you can specify `propagate` 
as a list of sensors whose names are unchanged,
+        # instead of (or in addition to) this map 
+        brooklyn.config:
+          sensorMapping:
+            $brooklyn:sensor("url"): 
$brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
+  brooklyn.enrichers:
+  - type: org.apache.brooklyn.enricher.stock.Aggregator
+    # aggregate `url` sensors from children into a list
+    brooklyn.config:
+      enricher.sourceSensor: $brooklyn:sensor("url")
+      enricher.targetSensor: $brooklyn:sensor("urls.list")
+      enricher.aggregating.fromMembers: true
+  - type: org.apache.brooklyn.enricher.stock.Joiner
+    # create a string from that list, for use e.g. in bash scripts
+    brooklyn.config:
+      enricher.sourceSensor: $brooklyn:sensor("urls.list")
+      enricher.targetSensor: 
$brooklyn:sensor("urls.list.comma_separated.max_2")
+      maximum: 2
+      # TODO infer uniqueTag, name etc
+      uniqueTag: urls.list.comma_separated.max_2
+  - type: org.apache.brooklyn.enricher.stock.Joiner
+    # pick one uri as the main one to use
+    brooklyn.config:
+      enricher.sourceSensor: $brooklyn:sensor("urls.list")
+      enricher.targetSensor: 
$brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
+      quote: false
+      maximum: 1
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Propagator
+  # if nothing specified for `propagating` or `sensorMapping` then 
+  # Propagator will do all but the usual lifecycle defaults, handy at the root!
+  brooklyn.config:
+    producer: $brooklyn:entity("cluster")

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-catalog.bom
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-catalog.bom 
b/guide/yaml/example_yaml/vanilla-bash-netcat-catalog.bom
new file mode 100644
index 0000000..7551818
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-catalog.bom
@@ -0,0 +1,35 @@
+brooklyn.catalog:
+  id: netcat-example
+  version: "1.0"
+  item:
+    type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+    name: Simple Netcat Server
+
+    launch.command: |
+      echo $MESSAGE | nc -l $NETCAT_PORT &
+      echo $! > $PID_FILE
+        
+    env:
+      MESSAGE: $brooklyn:config("message")
+      NETCAT_PORT: $brooklyn:attributeWhenReady("netcat.port")
+      
+    brooklyn.parameters:
+    - name: message
+      description: a message to send to the caller
+      default: hello
+    - name: netcat.port
+      type: port
+      description: the port netcat should run on
+      default: 4321+
+
+    brooklyn.enrichers:
+    - type: org.apache.brooklyn.enricher.stock.Transformer
+      brooklyn.config:
+        uniqueTag: main-uri-generator
+        enricher.sourceSensor: $brooklyn:sensor("host.address")
+        enricher.targetSensor: $brooklyn:sensor("main.uri")
+        enricher.targetValue:
+          $brooklyn:formatString:
+          - "http://%s:%s/";
+          - $brooklyn:attributeWhenReady("host.address")
+          - $brooklyn:attributeWhenReady("netcat.port")

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-cluster.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-cluster.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-cluster.yaml
new file mode 100644
index 0000000..70b69af
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-cluster.yaml
@@ -0,0 +1,11 @@
+name: Netcat Cluster Example
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.group.DynamicCluster
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: netcat-example
+      message: hello from cluster member
+      netcat.port: 8000+
+  initialSize: 3
+  restartMode: parallel

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-file.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-file.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-file.yaml
new file mode 100644
index 0000000..d768739
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-file.yaml
@@ -0,0 +1,6 @@
+name: Simple Netcat Example From File
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  name: Simple Netcat Server
+  download.url: file:///tmp/netcat-server.tgz

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-more-commands.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-more-commands.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-more-commands.yaml
new file mode 100644
index 0000000..f4e894f
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-more-commands.yaml
@@ -0,0 +1,16 @@
+name: Netcat Example with Explicit Check and Stop Commands
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  name: Simple Netcat Server
+  launch.command: |
+    echo hello | nc -l 4321 &
+    echo $! > $PID_FILE
+
+  # The following overrides demonstrate the use of a custom shell environment 
as well as
+  # check-running and stop commands. These are optional; default behavior will 
"do the
+  # right thing" with the pid file automatically.
+
+  env:                  { CHECK_MARKER: "checkRunning", STOP_MARKER: "stop" }
+  checkRunning.command: echo $CHECK_MARKER >> DATE && test -f "$PID_FILE" && 
ps -p `cat $PID_FILE` >/dev/null
+  stop.command:         echo $STOP_MARKER  >> DATE && test -f "$PID_FILE" && { 
kill -9 `cat $PID_FILE`; rm /tmp/vanilla.pid; }

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-port-parameter.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-port-parameter.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-port-parameter.yaml
new file mode 100644
index 0000000..90f83b4
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-port-parameter.yaml
@@ -0,0 +1,21 @@
+name: Netcat Example with Parameter
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  name: Simple Netcat Server
+  launch.command: |
+    echo $MESSAGE | nc -l $NETCAT_PORT &
+    echo $! > $PID_FILE
+    
+  env:
+    MESSAGE: $brooklyn:config("message")
+    NETCAT_PORT: $brooklyn:attributeWhenReady("netcat.port")
+  
+  brooklyn.parameters:
+  - name: message
+    description: a message to send to the caller
+    default: hello
+  - name: netcat.port
+    type: port
+    description: the port netcat should run on
+    default: 4321+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-port.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-port.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-port.yaml
new file mode 100644
index 0000000..3ec0212
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-port.yaml
@@ -0,0 +1,13 @@
+name: Netcat Example with Port Opened
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  name: Simple Netcat Server
+  launch.command: |
+    echo hello | nc -l 4321 &
+    echo $! > $PID_FILE
+    
+  brooklyn.config:
+    # matching the regex `.*\.port` will cause the port to be opened
+    # if in a cloud where configurable security groups are available
+    netcat.port: 4321

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-reference.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-reference.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-reference.yaml
new file mode 100644
index 0000000..0f10c55
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-reference.yaml
@@ -0,0 +1,5 @@
+name: Netcat Type Reference Example
+location: localhost
+services:
+- type: netcat-example
+  message: hello from netcat using a registered type

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-restarter.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-restarter.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-restarter.yaml
new file mode 100644
index 0000000..47e54ab
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-restarter.yaml
@@ -0,0 +1,20 @@
+name: Netcat Example with Restarter Policy
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  id: netcat-server
+  name: Simple Netcat Server
+  launch.command: |
+    echo hello | nc -l 4321 &
+    echo $! > $PID_FILE
+  brooklyn.enrichers:
+  - type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
+    brooklyn.config:
+      # wait 15s after service fails before propagating failure
+      serviceFailedStabilizationDelay: 15s
+  brooklyn.policies:
+  - type: org.apache.brooklyn.policy.ha.ServiceRestarter
+    brooklyn.config:
+      # repeated failures in a time window can cause the restarter to abort,
+      # propagating the failure; a time window of 0 will mean it always 
restarts!
+      failOnRecurringFailuresInThisDuration: 0

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat-w-client.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat-w-client.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat-w-client.yaml
new file mode 100644
index 0000000..78ed99e
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat-w-client.yaml
@@ -0,0 +1,78 @@
+name: Netcat Example with Client
+
+location: localhost
+
+services:
+
+# the netcat server instance, running in listener mode (-l)
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  id: netcat-server
+  name: Simple Netcat Server
+  launch.command: |
+    echo hello | nc -l 4321 >> server-input &
+    echo $! > $PID_FILE
+
+  # a failure detector and a service restarter work together
+  brooklyn.enrichers:
+  - type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
+    brooklyn.config:
+      # wait 15s after service fails before propagating failure
+      serviceFailedStabilizationDelay: 15s
+
+  brooklyn.policies:
+  - type: org.apache.brooklyn.policy.ha.ServiceRestarter
+    brooklyn.config:
+      # repeated failures in a time window can cause the restarter to abort,
+      # propagating the failure; a time window of 0 will mean it always 
restarts!
+      failOnRecurringFailuresInThisDuration: 0
+      
+  brooklyn.initializers:
+  # two sensors, recording the data sent to this netcat server:
+  
+  - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+    brooklyn.config:
+      name: output.last
+      period: 1s
+      command: tail -1 server-input
+      
+  - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+    brooklyn.config:
+      name: output.all
+      period: 1s
+      command: cat server-input
+
+# a client to hit netcat
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  name: Simple Pinger
+  
+  # set the hostname of the netcat instance as an env var for the scripts 
+  env:
+    TARGET_HOSTNAME: 
+      $brooklyn:component("netcat-server").
+        attributeWhenReady("host.name")
+    
+  # start/check/stop are no-op
+  launch.command: ""
+  checkRunning.command: ""
+  stop.command: ""
+  
+  brooklyn.initializers:
+  # but there is a sample effector which runs nc in client mode
+  
+  - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector
+    brooklyn.config:
+      name: sayHiNetcat
+      description: Echo a small hello string to the netcat entity
+      command: |
+        echo $message | nc $TARGET_HOSTNAME 4321
+      parameters:
+        message:
+          description: The string to pass to netcat
+          defaultValue: hi netcat
+
+# and add an enricher at the root so all sensors from netcat-server are 
visible on the root
+brooklyn.enrichers:
+- enricherType: org.apache.brooklyn.enricher.stock.Propagator
+  brooklyn.config:
+    enricher.producer: $brooklyn:component("netcat-server")
+    enricher.propagating.propagatingAll: true

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/example_yaml/vanilla-bash-netcat.yaml
----------------------------------------------------------------------
diff --git a/guide/yaml/example_yaml/vanilla-bash-netcat.yaml 
b/guide/yaml/example_yaml/vanilla-bash-netcat.yaml
new file mode 100644
index 0000000..df616af
--- /dev/null
+++ b/guide/yaml/example_yaml/vanilla-bash-netcat.yaml
@@ -0,0 +1,8 @@
+name: Simple Netcat Server Example
+location: localhost
+services:
+- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+  name: Simple Netcat Server
+  launch.command: |
+    echo hello | nc -l 4321 &
+    echo $! > $PID_FILE

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/index.md
----------------------------------------------------------------------
diff --git a/guide/yaml/index.md b/guide/yaml/index.md
new file mode 100644
index 0000000..792d9a0
--- /dev/null
+++ b/guide/yaml/index.md
@@ -0,0 +1,22 @@
+---
+title: YAML Blueprints
+layout: website-normal
+children:
+- creating-yaml.md
+- setting-locations.md
+- configuring-vms.md
+- clusters.md
+- multiple-services.md
+- clusters-and-policies.md
+- blueprinting-tips.md
+- custom-entities.md
+- winrm/
+- chef/
+- test/
+- advanced-example.md
+- { path: yaml-reference.md, title: YAML Blueprint Reference }
+- { link: 'https://github.com/brooklyncentral/blueprint-library', title: 
'GitHub Blueprint Library' }
+---
+
+
+{% include list-children.html %}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/guide/yaml/multiple-services.md
----------------------------------------------------------------------
diff --git a/guide/yaml/multiple-services.md b/guide/yaml/multiple-services.md
new file mode 100644
index 0000000..81ddf07
--- /dev/null
+++ b/guide/yaml/multiple-services.md
@@ -0,0 +1,97 @@
+---
+title: Multiple Services and Dependency Injection
+layout: website-normal
+---
+
+We've seen the configuration of machines and how to build up clusters.
+Now let's return to our app-server example and explore how more interesting
+services can be configured, composed, and combined.
+
+
+### Service Configuration
+
+We'll begin by using more key-value pairs to configure the JBoss server to run 
a real app:
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-configured.yaml %}
+{% endhighlight %}
+
+(As before, you'll need to add the `location` info; `localhost` will work for 
these and subsequent examples.)
+
+When this is deployed, you can see management information in the Brooklyn Web 
Console,
+including a link to the deployed application (downloaded to the target machine 
from the `hello-world` URL),
+running on port 8080.
+
+**Tip**:  If port 8080 might be in use, you can specify `8080+` to take the 
first available port >= 8080;
+the actual port will be reported as a sensor by Brooklyn.
+
+It's also worth indicating an alternate, more formal syntax.
+Not all configuration on entities is supported at the top level of the service 
specification
+(only those which are defined as "flags" in the underlying blueprint,
+e.g. the `@SetFromFlag("war")` in the `WebAppServiceConstants` parent of 
`JBoss7Server`).
+All configuration has a formal qualified name, and this can be supplied even 
where flags or config keys are not
+explicitly defined, by placing it into a `brooklyn.config` section:
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-configured-in-config.yaml %}
+{% endhighlight %}
+
+
+### Multiple Services
+
+If you explored the `hello-world-sql` application we just deployed, 
+you'll have noticed it tries to access a database.
+And it fails, because we have not set one up.  Let's do that now:
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-w-db.yaml %}
+{% endhighlight %}
+
+Here there are a few things going on:
+
+* We've added a second service, which will be the database;
+  you'll note the database has been configured to run a custom setup script
+* We've injected the URL of the second service into the appserver as a Java 
system property
+  (so our app knows where to find the database) 
+
+**Caution: Be careful if you write your YAML in an editor which attempts to 
put "smart-quotes" in.
+All quote characters must be plain ASCII, not fancy left-double-quotes and 
right-double-quotes!**
+
+There are as many ways to do dependency injection as there are developers,
+it sometimes seems; our aim in Brooklyn is not to say this has to be done one 
way,
+but to support the various mechanisms people might need, for whatever reasons.
+(We each have our opinions about what works well, of course;
+the one thing we do want to call out is that being able to dynamically update
+the injection is useful in a modern agile application -- so we are 
definitively **not**
+recommending this Java system property approach ... but it is an easy one to 
demo!)
+
+The way the dependency injection works is again by using the `$brooklyn:` DSL,
+this time referring to the `component("db")` (looked up by the `id` field on 
our DB component),
+and then to a sensor emitted by that component.
+All the database entities emit a `database.url` sensor when they are up and 
running;
+the `attributeWhenReady` DSL method will store a pointer to that sensor (a 
Java Future under the covers)
+in the Java system properties map which the JBoss entity reads at launch time, 
blocking if needed.
+
+This means that the deployment occurs in parallel, and if the database comes 
up first,
+there is no blocking; but if the JBoss entity completes its installation and 
+downloading the WAR, it will wait for the database before it launches.
+At that point the URL is injected, first passing it through `formatString`
+to include the credentials for the database (which are defined in the database 
creation script).
+
+
+### An Aside: Substitutability
+
+Don't like JBoss?  Is there something about Maria?
+One of the modular principles we follow in Brooklyn is substitutability:
+in many cases, the config keys, sensors, and effectors are defined
+in superclasses and are portable across multiple implementations.
+
+Here's an example deploying the same application but with different flavors of 
the components:
+
+{% highlight yaml %}
+{% readj example_yaml/appserver-w-db-other-flavor.yaml %}
+{% endhighlight %}
+
+We've also brought in the `provisioning.properties` from the VM example earlier
+so our database has 8GB RAM.
+Any of those properties, including `imageId` and `user`, can be defined on a 
per-entity basis.

Reply via email to