You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/06/16 15:21:48 UTC

[08/28] brooklyn-docs git commit: Refactor Blueprinting

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/blueprints/winrm/index.md
----------------------------------------------------------------------
diff --git a/guide/blueprints/winrm/index.md b/guide/blueprints/winrm/index.md
new file mode 100644
index 0000000..0d29dbc
--- /dev/null
+++ b/guide/blueprints/winrm/index.md
@@ -0,0 +1,630 @@
+---
+title: Windows Blueprints
+layout: website-normal
+children:
+- client.md
+---
+
+Brooklyn can deploy to Windows servers using WinRM to run commands. These deployments can be 
+expressed in pure YAML, and utilise Powershell to install and manage the software process. 
+This approach is similar to the use of SSH for UNIX-like servers.
+
+
+About WinRM
+-----------
+
+WinRM - or *Windows Remote Management* to give its full title - is a system administration service provided in all
+recent Windows Server operating systems. It allows remote access to system information (provided via WMI) and the
+ability to execute commands. For more information refer to [Microsoft's MSDN article on Windows Remote
+Management](https://msdn.microsoft.com/en-us/library/aa384426(v=vs.85).aspx).
+
+WinRM is available by default in Windows Server, but is not enabled by default. Brooklyn will, in most cases, be able
+to switch on WinRM support, but this is dependent on your cloud provider supporting a user metadata service with script
+execution (see [below](#user-metadata-service-requirement)).
+
+
+Locations for Windows
+---------------------
+
+You must define a new location in Brooklyn for Windows deployments. Windows deployments require a different VM image
+ID to Linux, as well as some other special configuration, so you must have separate Brooklyn locations for Windows and
+Linux deployments.
+
+In particular, you will most likely want to set these properties on your location:
+
+* `imageId` or `imageNameRegex` - select your preferred Windows Server image from your cloud provider.
+* `hardwareId` or `minRam`/`minCores` - since Windows machines generally require more powerful servers, ensure you get
+  a machine with the required specification.
+* `useJcloudsSshInit` - this must be set to `false`. Without this setting, jclouds will attempt to connect to the new
+  VMs using SSH, which will fail on Windows Server.
+* `templateOptions` - you may also wish to request a larger disk size. This setting is cloud specific; on AWS, you can
+  request a 100GB disk by setting this property to `{mapNewVolumeToDeviceName: ["/dev/sda1", 100, true]}`.
+
+In your YAML blueprint:
+
+    ...
+    location:
+      jclouds:aws-ec2:
+        region: us-west-2
+        identity: AKA_YOUR_ACCESS_KEY_ID
+        credential: <access-key-hex-digits>
+        imageNameRegex: Windows_Server-2012-R2_RTM-English-64Bit-Base-.*
+        imageOwner: 801119661308
+        hardwareId: m3.medium
+        useJcloudsSshInit: false
+        templateOptions: {mapNewVolumeToDeviceName: ["/dev/sda1", 100, true]}
+    ...
+
+Alternatively, you can define a new named location in `brooklyn.properties`:
+
+    brooklyn.location.named.AWS\ Oregon\ Win = jclouds:aws-ec2:us-west-2
+    brooklyn.location.named.AWS\ Oregon\ Win.displayName = AWS Oregon (Windows)
+    brooklyn.location.named.AWS\ Oregon\ Win.imageNameRegex = Windows_Server-2012-R2_RTM-English-64Bit-Base-.*
+    brooklyn.location.named.AWS\ Oregon\ Win.imageOwner = 801119661308
+    brooklyn.location.named.AWS\ Oregon\ Win.hardwareId = m3.medium
+    brooklyn.location.named.AWS\ Oregon\ Win.useJcloudsSshInit = false
+    brooklyn.location.named.AWS\ Oregon\ Win.templateOptions = {mapNewVolumeToDeviceName: ["/dev/sda1", 100, true]}
+
+
+
+A Sample Blueprint
+------------------
+
+Creating a Windows VM is done using the `org.apache.brooklyn.entity.software.base.VanillaWindowsProcess` entity type. This is very similar
+to `VanillaSoftwareProcess`, but adapted to work for Windows and WinRM instead of Linux. We suggest you read the
+[documentation for VanillaSoftwareProcess]({{ site.path.guide }}/blueprints/custom-entities.html#vanilla-software-using-bash) to find out what you
+can do with this entity.
+
+Entity authors are strongly encouraged to write Windows Powershell or Batch scripts as separate 
+files, to configure these to be uploaded, and then to configure the appropriate command as a 
+single line that executes given script.
+
+For example - here is a simplified blueprint (but see [Tips and Tricks](#tips-and-tricks) below!):
+
+    name: Server with 7-Zip
+
+    location:
+      jclouds:aws-ec2:
+        region: us-west-2
+        identity: AKA_YOUR_ACCESS_KEY_ID
+        credential: <access-key-hex-digits>
+        imageNameRegex: Windows_Server-2012-R2_RTM-English-64Bit-Base-.*
+        imageOwner: 801119661308
+        hardwareId: m3.medium
+        useJcloudsSshInit: false
+        templateOptions: {mapNewVolumeToDeviceName: ["/dev/sda1", 100, true]}
+
+    services:
+    - type: org.apache.brooklyn.entity.software.base.VanillaWindowsProcess
+      brooklyn.config:
+        templates.preinstall:
+          file:///Users/richard/install7zip.ps1: "C:\\install7zip.ps1"
+        install.command: powershell -command "C:\\install7zip.ps1"
+        customize.command: echo true
+        launch.command: echo true
+        stop.command: echo true
+        checkRunning.command: echo true
+        installer.download.url: http://www.7-zip.org/a/7z938-x64.msi
+
+The installation script - referred to as `/Users/richard/install7zip.ps1` in the example above - is:
+
+    $Path = "C:\InstallTemp"
+    New-Item -ItemType Directory -Force -Path $Path
+
+    $Url = "${config['installer.download.url']}"
+    $Dl = [System.IO.Path]::Combine($Path, "installer.msi")
+    $WebClient = New-Object System.Net.WebClient
+    $WebClient.DownloadFile( $Url, $Dl )
+
+    Start-Process "msiexec" -ArgumentList '/qn','/i',$Dl -RedirectStandardOutput ( [System.IO.Path]::Combine($Path, "stdout.txt") ) -RedirectStandardError ( [System.IO.Path]::Combine($Path, "stderr.txt") ) -Wait
+
+Where security-related operation are to be executed, it may require the use of `CredSSP` to obtain
+the correct Administrator privileges: you may otherwise get an access denied error. See the sub-section 
+[How and Why to re-authenticate within a powershell script](#how-and-why-to-re-authenticate-within-a-powershell-script) for more details.
+
+This is only a very simple example. A more complex example can be found in the [Microsoft SQL Server blueprint in the
+Brooklyn source code]({{ site.brooklyn.url.git }}/software/database/src/main/resources/org/apache/brooklyn/entity/database/mssql).
+
+
+Tips and Tricks
+---------------
+
+The best practices for other entities (e.g. using [VanillaSoftwareProcess]({{ site.path.guide }}/blueprints/custom-entities.html#vanilla-software-using-bash))
+apply for WinRM as well.
+
+### Execution Phases
+
+Blueprint authors are strongly encouraged to provide an implementation for install, launch, stop 
+and checkRunning. These are vital for the generic effectors such as stopping and restarting the 
+process.
+
+### Powershell
+
+Powershell commands can be supplied using config options such as `launch.powershell.command`.
+
+This is an alternative to supplying a standard batch command using config such as `launch.command`.
+For a given phase, only one of the commands (Powershell or Batch) should be supplied.
+
+### Getting the Right Exit Codes
+
+WinRM (or at least the chosen WinRM client!) can return a zero exit code even on error in certain 
+circumstances. It is therefore advisable to follow the guidelines below.
+
+*For a given command, write the Powershell or Batch script as a separate multi-command file. 
+Upload this (e.g. by including it in the `files.preinstall` configuration). For the configuration
+of the given command, execute the file.*
+
+When you have a command inside the powershell script which want to report its non zero exiting, 
+please consider adding a check for its exit code after it.
+Example:
+
+    & "C:\install.exe"
+    If ($lastexitcode -ne 0) {
+        exit $lastexitcode
+    }
+
+For Powershell files, consider including 
+
+    $ErrorActionPreference = "Stop"
+
+at the start of the file. 
+`$ErrorActionPreference` Determines how Windows PowerShell responds to a non-terminating
+error (an error that does not stop the cmdlet processing) at the
+command line or in a script, cmdlet, or provider, such as the
+errors generated by the Write-Error cmdlet.
+https://technet.microsoft.com/en-us/library/hh847796.aspx
+
+See [Incorrect Exit Codes](#incorrect-exit-codes) under Known Limitations below.
+
+### Executing Scripts From Batch Commands
+
+In a batch command, you can execute a batch file or Powershell file. For example:
+
+    install.command: powershell -NonInteractive -NoProfile -Command "C:\\install7zip.ps1"
+
+Or alternatively:
+
+    install.command: C:\\install7zip.bat
+
+### Executing Scripts From Powershell
+
+In a Powershell command, you can execute a batch file or Powershell file. There are many ways
+to do this (see official Powershell docs). For example:
+ 
+    install.powershell.command: "& C:\\install7zip.ps1"
+
+Or alternatively:
+
+    install.powershell.command: "& C:\\install7zip.bat"
+
+Note the quotes around the command. This is because the "&" has special meaning in a YAML value. 
+
+### Uploading Script and Configuration Files
+
+Often, blueprints will require that (parameterized) scripts and configuration files are available to be copied to the
+target VM. These must be URLs resolvable from the Brooklyn instance, or on the Brooklyn classpath. One simple way 
+to achieve this is to compile the support files into a .jar, which is then added to AMP's 'dropins' folder. Alternatively, 
+an OSGi bundle can be used, referenced from the catalog item. 
+
+Ensure that these scripts end each line with "\r\n", rather than just "\n".
+
+There are two types of file that can be uploaded: plain files and templated files. A plain 
+file is uploaded unmodified. A templated file is interpreted as a [FreeMarker](http://freemarker.org) 
+template. This supports a powerful set of substitutions. In brief, anything (unescaped) of the form
+`${name}` will be substituted, in this case looking up "name" for the value to use.
+
+Templated files (be they configuration files or scripts) gives a powerful way to inject dependent 
+configuration when installing an entity (e.g. for customising the install, or for referencing the
+connection details of another entity). A common substitution is of the form `${config['mykey']}`. 
+This looks up a config key (in this case named "mykey") and will insert the value into the file.
+Another common substitution is is of the form `${attribute['myattribute']}` - this looks up the
+attribute named "myattribute" of this entity.
+
+Files can be referenced as URLs. This includes support for things like `classpath://mypath/myfile.bat`. 
+This looks for the given (fully qualified) resource on the Brooklyn classpath.
+
+The destination for the file upload is specified in the entity's configuration. Note that "\" must
+be escaped. For example `"C:\\install7zip.ps1"`.
+
+A list of plain files to be uploaded can be configured under `files.preinstall`, `files.install` and
+`files.runtime`. These are uploaded respectively prior to executing the `pre.install.command`,
+prior to `install.command` and prior to `pre.launch.command`.
+
+A list of templated files to be uploaded can be configured under `templates.preinstall`, `templates.install`
+and `templates.runtime`. The times these are uploaded is as for the plain files. The templates 
+substitutions will be resolved only at the point when the file is to be uploaded.
+
+For example:
+
+    files.preinstall:
+    - classpath://com/acme/installAcme.ps1
+    - classpath://com/acme/acme.conf
+
+### Parameterised Scripts
+
+Calling parameterised Batch and Powershell scripts is done in the normal Windows way - see
+offical Microsoft docs. For example:
+
+    install.command: "c:\\myscript.bat myarg1 myarg2"
+
+Or as a Powershell example:
+
+    install.powershell.command: "& c:\\myscript.ps1 -key1 myarg1 -key2 myarg2"
+
+It is also possible to construct the script parameters by referencing attributes of this or
+other entities using the standard `attributeWhenReady` mechanism. For example:
+
+    install.command: $brooklyn:formatString("c:\\myscript.bat %s", component("db").attributeWhenReady("datastore.url"))
+
+### Powershell - Using Start-Process
+
+When you are invoking a command from a powershell script with `Start-Process` cmdlet,
+please use the `-Wait` and the `-PassThru` arguments.
+Example `Start-Process C:\mycommand -Wait -PassThru`
+
+Using `-Wait` guarantees that the script process and its children and thus the winrm session won't be terminated until it is finished.
+`-PassThru` Returns a process object for each process that the cmdlet started. By default, this cmdlet does not generate any output.
+See https://technet.microsoft.com/en-us/library/hh849848.aspx
+
+### Rebooting
+
+Where a reboot is required as part of the entity setup, this can be configured using
+config like `pre.install.reboot.required` and `install.reboot.required`. If required, the 
+installation commands can be split between the pre-install, install and post-install phases
+in order to do a reboot at the appropriate point of the VM setup.
+
+We Strongly recommend to **write blueprints in a way that they do NOT restart automatically windows** and
+use one of the `pre.install.reboot.required` or `install.reboot.required` parameters to perform restart.
+
+### Install Location
+
+Blueprint authors are encouraged to explicitly specify the full path for file uploads, and 
+for paths in their Powershell scripts (e.g. for installation, configuration files, log files, etc).
+
+### How and Why to re-authenticate within a powershell script
+
+Some installation scripts require the use of security-related operations. In some environments,  
+these fail by default when executed over WinRM, even though the script may succeed when run locally   
+(e.g. by using RDP to connect to the machine and running the script manually). There may be no  
+clear indication from Windows why it failed (e.g. for MSSQL install, the only clue is a   
+security exception in the installation log).
+
+When a script is run over WinRM, the credentials under which the script are run are marked as
+'remote' credentials, which are prohibited from running certain security-related operations. The 
+solution is to obtain a new set of credentials within the script and use those credentials to 
+required commands.
+
+The WinRM client uses Negotiate+NTLM to authenticate against the machine.
+This mechanism applies certain restrictions to executing commands on the windows host.
+
+For this reason you should enable CredSSP on the windows host which grants all privileges available to the user.
+ https://technet.microsoft.com/en-us/library/hh849719.aspx#sectionSection4
+
+To use `Invoke-Command -Authentication CredSSP` the Windows Machine has to have:
+- Up and running WinRM over http. The custom-enable-credssp.ps1 script enables winrm over http because `Invoke-Command` use winrm over http by default.
+  Invoke-Command can be used with -UseSSL option but this will lead to modifying powershell scripts.
+  With always enabling winrm over http on the host, blueprint's powershell scripts remain consistent and not depend on the winrm https/http environments.
+  We hope future versions of winrm4j will support CredSSP out of the box and wrapping commands in Invoke-Command will not be needed.
+- Added trusted host entries which will use Invoke-Command
+- Allowed CredSSP
+
+All the above requirements are enabled in Apache Brooklyn through [brooklyn-server/software/base/src/main/resources/org/apache/brooklyn/software/base/custom-enable-credssp.ps1](https://github.com/apache/brooklyn-server/blob/master/software/base/src/main/resources/org/apache/brooklyn/software/base/custom-enable-credssp.ps1)
+script which enables executing commands with CredSSP in the general case.
+The script works for most of the Windows images out there version 2008 and later.
+
+Please ensure that Brooklyn's changes are compatible with your organisation's security policy.
+
+Check Microsoft Documentation for more information about [Negotiate authenticate mechanism on technet.microsoft.com](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378748(v=vs.85).aspx)
+
+Re-authentication also requires that the password credentials are passed in plain text within the
+script. Please be aware that it is normal for script files - and therefore the plaintext password - 
+to be saved to the VM's disk. The scripts are also accessible via the Brooklyn web-console's 
+activity view. Access to the latter can be controlled via 
+[Entitlements]({{site.path.guide}}/blueprints/java/entitlements.html).
+
+As an example (taken from MSSQL install), the command below works when run locally, but fails over 
+WinRM:
+
+    ( $driveLetter + "setup.exe") /ConfigurationFile=C:\ConfigurationFile.ini
+
+The code below can be used instead (note this example uses Freemarker templating):
+
+    & winrm set winrm/config/service/auth '@{CredSSP="true"}'
+    & winrm set winrm/config/client/auth '@{CredSSP="true"}'
+    #
+    $pass = '${attribute['windows.password']}'
+    $secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
+    $mycreds = New-Object System.Management.Automation.PSCredential ($($env:COMPUTERNAME + "\${location.user}"), $secpasswd)
+    #
+    $exitCode = Invoke-Command -ComputerName $env:COMPUTERNAME -Credential $mycreds -ScriptBlock {
+        param($driveLetter)
+        $process = Start-Process ( $driveLetter + "setup.exe") -ArgumentList "/ConfigurationFile=C:\ConfigurationFile.ini" -RedirectStandardOutput "C:\sqlout.txt" -RedirectStandardError "C:\sqlerr.txt" -Wait -PassThru -NoNewWindow
+        $process.ExitCode
+    } -Authentication CredSSP -ArgumentList $driveLetter
+    #
+    exit $exitCode
+
+In this example, the `${...}` format is FreeMarker templating. Those sections will be substituted
+before the script is uploaded for execution. To explain this example in more detail:
+
+* `${attribute['windows.password']}` is substituted for the entity's attribute "windows.password".
+  This (clear-text) password is sent as part of the script. Assuming that HTTPS and NTLM is used,
+  the script will be encrypted while in-flight.
+
+* The `${location.user}` gets (from the entity's machine location) the username, substituting this 
+  text for the actual username. In many cases, this will be "Administrator". However, on some  
+  clouds a different username (with admin privileges) will be used.
+
+* The username and password are used to create a new credential object (having first converted the
+  password to a secure string).
+
+* Credential Security Service Provider (CredSSP) is used for authentication, to pass the explicit  
+  credentials when using `Invoke-Command`.
+
+
+### Windows AMIs on AWS
+
+Windows AMIs in AWS change regularly (to include the latest Windows updates). If using the community
+AMI, it is recommended to use an AMI name regex, rather than an image id, so that the latest AMI is 
+always picked up. If an image id is used, it may fail as Amazon will delete their old Windows AMIs.
+
+If using an image regex, it is recommended to include the image owner in case someone else uploads
+a similarly named AMI. For example:
+
+    brooklyn.location.named.AWS\ Oregon\ Win = jclouds:aws-ec2:us-west-2
+    brooklyn.location.named.AWS\ Oregon\ Win.imageNameRegex = Windows_Server-2012-R2_RTM-English-64Bit-Base-.*
+    brooklyn.location.named.AWS\ Oregon\ Win.imageOwner = 801119661308
+    ...
+
+## stdout and stderr in a Powershell script
+
+When calling an executable in a Powershell script, the stdout and stderr will usually be output to the console.
+This is captured by Brooklyn, and shown in the activities view under the specific tasks.
+
+An alternative is to redirect stdout and stderr to a file on the VM, which can be helpful if one expects sys admins
+to log into the VM. However, be warned that this would hide the stdout/stderr from Brooklyn's activities view.
+
+For example, instead of running the following:
+
+    D:\setup.exe /ConfigurationFile=C:\ConfigurationFile.ini
+
+ The redirect can be achieved by using the `Start-Process` scriptlet:
+
+    Start-Process D:\setup.exe -ArgumentList "/ConfigurationFile=C:\ConfigurationFile.ini" -RedirectStandardOutput "C:\sqlout.txt" -RedirectStandardError "C:\sqlerr.txt" -PassThru -Wait
+
+The `-ArgumentList` is simply the arguments that are to be passed to the executable, `-RedirectStandardOutput` and
+`RedirectStandardError` take file locations for the output (if the file already exists, it will be overwritten). The
+`-PassThru` argument indicates that Powershell should write to the file *in addition* to the console, rather than
+*instead* of the console. The `-Wait` argument will cause the scriptlet to block until the process is complete.
+
+Further details can be found on the [Start-Process documentation page](https://technet.microsoft.com/en-us/library/hh849848.aspx)
+on the Microsoft TechNet site.
+
+
+Troubleshooting
+---------------
+
+Much of the [operations troubleshooting guide]({{ site.path.guide }}/ops/troubleshooting/) is applicable for Windows blueprints.  
+
+### User metadata service requirement
+
+WinRM requires activation and configuration before it will work in a standard Windows Server deployment. To automate
+this, Brooklyn will place a setup script in the user metadata blob. Services such as Amazon EC2's `Ec2ConfigService`
+will automatically load and execute this script. If your chosen cloud provider does not support `Ec2ConfigService` or
+a similar package, or if your cloud provider does not support user metadata, then you must pre-configure a Windows image
+with the required WinRM setup and make Brooklyn use this image.
+
+If the configuration options `userMetadata` or `userMetadataString` are used on the location, then this will override
+the default setup script. This allows one to supply a custom setup script. However, if userMetadata contains something
+else then the setup will not be done and the VM may not not be accessible remotely over WinRM.
+
+### Credentials issue requiring special configuration
+
+When a script is run over WinRM over HTTP, the credentials under which the script are run are marked as
+'remote' credentials, which are prohibited from running certain security-related operations. This may prevent certain
+operations. The installer from Microsoft SQL Server is known to fail in this case, for example. For a workaround, please
+refer to [How and Why to re-authenticate withing a powershell script](#how-and-why-to-re-authenticate-within-a-powershell-script) 
+above.
+
+### WebServiceException: Could not send Message
+
+We detected a `WebServiceException` and different `SocketException`
+during deployment of long lasting Application Blueprint against VcloudDirector.
+
+Launching the blueprint bellow was giving constantly this type of error on launch step.
+
+    services:
+      type: org.apache.brooklyn.entity.software.base.VanillaWindowsProcess
+      brooklyn.config:
+        pre.install.command: echo preInstallCommand
+        install.command: echo installCommand > C:\\install.txt
+        post.install.command: echo postInstallCommand
+        customize.command: echo customizeCommand
+        pre.launch.command: echo preLaunchCommand
+        launch.powershell.command: |
+          Start-Sleep -s 400
+          Write-Host Test Completed
+        post.launch.command: echo postLaunchCommand
+        checkRunning.command: echo checkRunningCommand
+        stop.command: echo stopCommand
+        
+With series of tests we concluded that on the Vcloud Director environment we were using
+a restart was happening ~2 minutes after the VM is provisioned.
+Logging in the host and search for System event of type 1074 in Windows Event Viewer, we found two 1074 events where the second one was
+
+    The process C:\Windows\system32\winlogon.exe (W2K12-STD) has initiated the restart of computer WIN-XXXX on behalf of user
+    NT AUTHORITY\SYSTEM for the following reason: Operating System: Upgrade (Planned) Reason Code: 0x80020003 Shutdown Type: restart Comment:
+
+Normally on other clouds only one restart event is registered and the first time winrm connection is made the Windows VM is ready for use. 
+
+For this particular case when you want this second restart to finish we made `waitWindowsToStart` location parameter
+which basically adds additional check assuring the Windows VM provisioning is done.
+
+
+For example when using `waitWindowsToStart: 5m` location parameter, Apache Brooklyn will wait 5 minutes to see if a disconnect occurs.
+If it does, then it will again wait 5m for the machine to come back up.
+The default behaviour in Apache Brooklyn is to consider provisioning done on the first successful winrm connection, without waiting for restart. 
+
+
+To determine whether you should use this parameter you should carefully inspect how the image you choose to provision is behaving.
+If the description above matches your case and you are getting **connection failure message in the middle of the installation process** for your blueprints,
+a restart probably occurred and you should try this parameter.
+
+Before using this parameter we advice to check whether this is really your case.
+To verify the behavior check as described above.
+
+### AMIs not found
+
+If using the imageId of a Windows community AMI, you may find that the AMI is deleted after a few weeks.
+See [Windows AMIs on AWS](#windows-amis-on-aws) above.
+
+### VM Provisioning Times Out
+
+In some environments, provisioning of Windows VMs can take a very long time to return a usable VM.
+If the image is old, it may install many security updates (and reboot several times) before it is
+usable.
+
+On a VMware vCloud Director environment, the guest customizations can cause the VM to reboot (sometimes
+several times) before the VM is usable.
+
+This could cause the WinRM connection attempts to timeout. The location configuration option 
+`waitForWinRmAvailable` defaults to `30m` (i.e. 30 minutes). This can be increased if required.
+
+Incorrectly prepared Windows template can cause the deployment to time-out expecting an interaction by the user.
+You can verify if this is the case by RDP to the deployment which is taking to much time to complete. 
+It is recommended to manually deploy a single VM for every newly created Windows template to verify that it can be
+used for unattended installations and it doesn't wait and/or require an input by the user.
+See [Windows template settings for an Unattended Installation](#windows-template-settings-for-an-unattended-installation) under Known Limitations below. 
+
+### Windows log files
+
+Details of the commands executed, and their results, can be found in the Brooklyn log and in the Brooklyn 
+web-console's activity view. 
+
+There will also be log files on the Windows Server. System errors in Windows are usually reported in the Windows Event Log -  
+see [https://technet.microsoft.com/en-us/library/cc766042.aspx](https://technet.microsoft.com/en-us/library/cc766042.aspx) 
+for more information.
+
+Additional logs may be created by some Windows programs. For example, MSSQL creates a log in 
+`%programfiles%\Microsoft SQL Server\130\Setup Bootstrap\Log\` - for more information see 
+[https://msdn.microsoft.com/en-us/library/ms143702.aspx](https://msdn.microsoft.com/en-us/library/ms143702.aspx).
+
+
+Known Limitations
+-----------------
+
+WinRM 2.0 supports encryption mechanisms on top of HTTP. However those are not supported in Apache Brooklyn.
+For production adoptions please make sure you follow Microsoft Guidelines https://msdn.microsoft.com/en-us/library/ee309366(v=vs.85).aspx
+
+### Apache Brooklyn limitations on using WinRM over HTTP and HTTPS
+
+By default Apache Brooklyn is currently using unencrypted HTTP for WinRM communication. It does not support encrypted HTTP for WinRM.
+
+HTTPS is supported but there is no mechanism of specifying which certificates to trust.
+Currently Apache Brooklyn will accept any certificate used in a HTTPS WinRM connection.
+
+### Incorrect Exit Codes
+
+Some limitations with WinRM (or at least the chosen WinRM Client!) are listed below:
+
+##### Single-line Powershell files
+
+When a Powershell file contains just a single command, the execution of that file over WinRM returns exit code 0
+even if the command fails! This is the case for even simple examples like `exit 1` or `thisFileDoesNotExist.exe`.
+
+A workaround is to add an initial command, for example:
+
+    Write-Host dummy line for workaround 
+    exit 1
+
+##### Direct Configuration of Powershell commands
+
+If a command is directly configured with Powershell that includes `exit`, the return code over WinRM
+is not respected. For example, the command below will receive an exit code of 0.
+
+    launch.powershell.command: |
+      echo first
+      exit 1
+
+##### Direct Configuration of Batch commands
+
+If a command is directly configured with a batch exit, the return code over WinRM
+is not respected. For example, the command below will receive an exit code of 0.
+
+    launch.command: exit /B 1
+
+##### Non-zero Exit Code Returned as One
+
+If a batch or Powershell file exits with an exit code greater than one (or negative), this will 
+be reported as 1 over WinRM.
+
+We advise you to use native commands (non-powershell ones) since executing it as a native command
+will return the exact exit code rather than 1.
+For instance if you have installmssql.ps1 script use `install.command: powershell -command "C:\\installmssql.ps1"`
+rather than using `install.powershell.command: "C:\\installmssql.ps1"`
+The first will give you an exact exit code rather than 1
+
+### PowerShell "Preparing modules for first use"
+
+The first command executed over WinRM has been observed to include stderr saying "Preparing 
+modules for first use", such as that below:
+
+    < CLIXML
+    <Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><Obj S="progress" RefId="0"><TN RefId="0"><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N="SourceId">1</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj><Obj S="progress" RefId="1"><TNRef RefId="0" /><MS><I64 N="SourceId">2</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs>
+
+The command still succeeded. This has only been observed on private clouds (e.g. not on
+AWS). It could be related to the specific Windows images in use. It is recommended that 
+VM images are prepared carefully, e.g. so that security patches are up-to-date and the
+VM is suitably initialised.
+
+### WinRM executeScript failed: httplib.BadStatusLine: ''
+
+As described in https://issues.apache.org/jira/browse/BROOKLYN-173, a failure has been
+observed where the 10 attempts to execute the command over WinRM failed with:
+
+    httplib.BadStatusLine: ''
+
+Subsequently retrying the command worked. It is unclear what caused the failure, but could 
+have been that the Windows VM was not yet in the right state.
+
+One possible workaround is to ensure the Windows VM is in a good state for immediate use (e.g. 
+security updates are up-to-date). Another option is to increase the number of retries, 
+which defaults to 10. This is a configuration option on the machine location, so can be set on
+the location's brooklyn.properties or in the YAML: 
+
+    execTries: 20
+
+### Direct Configuration of Multi-line Batch Commands Not Executed
+
+If a command is directly configured with multi-line batch commands, then only the first line 
+will be executed. For example the command below will only output "first":
+
+    launch.command: |
+      echo first
+      echo second
+
+The workaround is to write a file with the batch commands, have that file uploaded, and execute it.
+
+Note this is not done automatically because that could affect the capture and returning
+of the exit code for the commands executed.
+
+### Install location
+
+Work is required to better configure a default install location on the VM (e.g. so that 
+environment variables are set). The installation pattern for linux-based blueprints,
+of using brooklyn-managed-processes/installs, is not used or recommended on Windows.
+Files will be uploaded to C:\ if no explicit directory is supplied, which is untidy, 
+unnecessarily exposes the scripts to the user, and could cause conflicts if multiple 
+entities are installed.
+
+Blueprint authors are strongly encourages to explicitly specific directories for file
+uploads and in their Powershell scripts.
+
+### Windows template settings for an Unattended Installation
+
+Windows template needs certain configuration to be applied to prevent windows setup UI from being displayed.
+The default behavior is to display it if there are incorrect or empty settings. Showing Setup UI will prevent the proper
+deployment, because it will expect interaction by the user such as agreeing on the license agreement or some of the setup dialogs.
+
+Detailed instruction how to prepare an Unattended installation are provided at [https://technet.microsoft.com/en-us/library/cc722411%28v=ws.10%29.aspx](https://technet.microsoft.com/en-us/library/cc722411%28v=ws.10%29.aspx).
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/blueprints/yaml-reference.md
----------------------------------------------------------------------
diff --git a/guide/blueprints/yaml-reference.md b/guide/blueprints/yaml-reference.md
new file mode 100644
index 0000000..7a46970
--- /dev/null
+++ b/guide/blueprints/yaml-reference.md
@@ -0,0 +1,253 @@
+---
+title: YAML Blueprint Reference
+layout: website-normal
+---
+
+## Root Elements
+
+* `name`: human readable names
+* `services`: a list of `ServiceSpecification` elements
+* `location` (or `locations` taking a list): a `LocationSpecification` element as a string or a map
+
+
+## Service Specification Elements
+
+Within the `services` block, a list of maps should be supplied, with each map
+defining a `ServiceSpecification`.  Each `ServiceSpecification` should declare the
+service `type` (synonyms `serviceType` and `service_type`), indicating what type of 
+service is being specified there.  The following formats are supported for
+defining types:
+
+* `com.acme.brooklyn.package.JavaEntityClass`
+* `java:com.acme.brooklyn.package.JavaEntityClass`
+* `java-entity-class` (where this has been added to the [catalog]({{ site.path.guide }}/blueprints/catalog/))
+
+A reference of some of the common service `type` instances used is included in a section below.
+
+Within the `ServiceSpecification`, other key-value pairs can be supplied to customize
+the entity being defined, with these being the most common:
+
+* `id`: an ID string, used to refer to this service
+
+* `location` (or `locations`): as defined in the root element 
+  
+* `brooklyn.config`: configuration key-value pairs passed to the service entity being created
+
+* `brooklyn.children`: a list of `ServiceSpecifications` which will be configured as children of this entity
+
+* `brooklyn.policies`: a list of policies, each as a map described with their `type` and their `brooklyn.config` as keys
+
+* `brooklyn.enrichers`: a list of enrichers, each as a map described with their `type` and their `brooklyn.config` as keys;
+  see the keys declared on individual enrichers; 
+  also see [this enricher example](example_yaml/test-app-with-enrichers-slightly-simpler.yaml) for a detailed and commented illustration
+  <!-- TODO assert that this yaml maches the yaml we test against -->
+
+* `brooklyn.initializers`: a list of `EntityInitializer` instances to be constructed and run against the entity, 
+  each as a map described with their `type` and their `brooklyn.config` as keys.
+  An `EntityInitiailzer` can perform arbitrary customization to an entity whilst it is being constructed,
+  such as adding dynamic sensors and effectors. These classes must expose a public constructor taking
+  a single `Map` where the `brooklyn.config` is passed in.
+  Some common initializers are:
+  
+  * `org.apache.brooklyn.core.effector.ssh.SshCommandEffector`: takes a `name` and `command`,
+    and optionally a map of named `parameters` to their `description` and `defaultValue`,
+    to define an effector with the given name implemented by the given SSH command
+    (on an entity which as an ssh-able machine)
+
+  * `org.apache.brooklyn.core.sensor.ssh.SshCommandSensor`: takes a `name` and `command`,
+    and optionally a `period`, to create a sensor feed which populates the sensor with
+    the given name by running the given command (on an entity which as an ssh-able machine)
+
+  * `org.apache.brooklyn.core.sensor.windows.WinRmCommandSensor`: For a command supplied via WinRm. Takes a `name`, `command`,
+    and optionally a `period` and `executionDir`, to create a sensor feed which populates the sensor with
+    the given name by running the given command (on an entity which as an winrm-able machine).<br/>
+    _`"~"` will use the default execution directory for the WinRm session which is usually `%USERPROFILE%`_
+
+* `brooklyn.parameters`: documents a list of typed parameters the entity accepts. If none
+  are specified the config keys declared in the entity's class are used (including the
+  information from the `@CatalogConfig` annotation). The items have the following properties:
+  * `name` (required): identifier by which to reference the parameter when setting
+    or retrieving its value
+  * `label`: a value to present to the user, same as `name` if empty
+  * `description`: short text describing the parameter behaviour/usage, presented
+    to the user
+  * `type`: the type of the parameter, one of `string`, `integer`, `long`, `float`,
+    `double`, `timestamp`, `duration`, `port`, or a fully qualified Java type name;
+    the default is `string`;
+    obvious coercion is supported so 
+    `timestamp` accepts most common ISO date formats, `duration` accepts `5m`, and port accepts `8080+`
+  * `default`: a default value; this will be coerced to the declared `type`
+  * `pinned`: mark the parameter as pinned (always displayed) for the UI. The default is `true`
+  * `constraints`: a list of constraints the parameter should meet;
+    for details, see [Entity Configuration]({{ site.path.guide }}/blueprints/entity-configuration.html#config-key-constraints).
+
+  A shorthand notation is also supported where just the name of the parameter is supplied
+  as an item in the list, with the other values being unset or the default.
+  See `displayName` in the following example for an illustration of this:
+
+  ~~~ yaml
+  brooklyn.parameters:
+  # user.age parameter is required, pinned and fully specified
+  - name: user.age
+  type: integer
+  label: Age
+  description: the age of the user
+  pinned: true
+  constraints:
+  - required
+  # user.name is optional, is not pinned and has a default
+  - name: user.name
+  default: You
+  pinned: false
+  # shorthand notation: displayName will be an optional config of type string with no default
+  - displayName
+  ~~~
+
+  Entities, policies, and initializers may accept additional key-value pairs,
+  usually documented in their documentation (e.g. javadoc), or in the case of Java
+  often as static fields in the underlying Java class.
+  Often there are config keys or flags (indicated by `@SetFromFlag`) declared on the class;
+  these declared flags and config keys may be passed in at the root of the `ServiceSpecification` or in `brooklyn.config`.
+  (Undeclared config is only accepted in the `brooklyn.config` map.)
+  Referencing the parameters from within java classes is identical to using config keys. In yaml it's
+  usually referenced using `$brooklyn:scopeRoot().config("displayName")`. See below for more details on scopes.
+
+* `brooklyn.tags`: documents a list of tag objects which should be assigned to the entity.
+
+
+## Location Specification Elements
+
+<!-- TODO - expand this, currently it's concise notes -->
+
+In brief, location specs are supplied as follows, either for the entire application (at the root)
+or for a specific `ServiceSpecification`:
+
+    location:
+      jclouds:aws-ec2:
+        region: us-east-1
+        identity: AKA_YOUR_ACCESS_KEY_ID
+        credential: <access-key-hex-digits>
+
+Or in many cases it can be in-lined:
+
+    location: localhost
+    location: named:my_openstack
+    location: aws-ec2:us-west-1
+
+For the first immediately, you'll need password-less ssh access to localhost.
+For the second, you'll need to define a named location in `brooklyn.properties`,
+using `brooklyn.location.named.my_openstack....` properties.
+For the third, you'll need to have the identity and credentials defined in
+`brooklyn.properties`, using `brooklyn.location.jclouds.aws-ec2....` properties.
+
+If specifying multiple locations, e.g. for a fabric:
+
+    locations:
+    - localhost
+    - named:my_openstack
+    - aws-ec2:us-east-2   # if credentials defined in `brooklyn.properties
+    - jclouds:aws-ec2:
+        region: us-east-1
+        identity: AKA_YOUR_ACCESS_KEY_ID
+        credential: <access-key-hex-digits>
+
+If you have pre-existing nodes, you can use the `byon` provider, either in this format:
+
+    location:
+      byon:
+        user: root
+        privateKeyFile: ~/.ssh/key.pem
+        hosts:
+        - 81.95.144.58
+        - 81.95.144.59
+        - brooklyn@159.253.144.139
+        - brooklyn@159.253.144.140
+
+or:
+
+    location:
+      byon:
+        user: root
+        privateKeyFile: ~/.ssh/key.pem
+        hosts: "{81.95.144.{58,59},brooklyn@159.253.144.{139-140}"
+
+You cannot use glob expansions with the list notation, nor can you specify per-host
+information apart from user within a single `byon` declaration.
+However you can combine locations using `multi`:
+
+    location:
+      multi:
+        targets:
+        - byon:
+            user: root
+            privateKeyFile: ~/.ssh/key.pem
+            hosts:
+            - 81.95.144.58
+            - 81.95.144.59
+        - byon:
+            privateKeyFile: ~/.ssh/brooklyn_key.pem
+            hosts: brooklyn@159.253.144{139-140}
+
+
+## DSL Commands
+
+Dependency injection other powerful references and types can be built up within the YAML using the
+concise DSL defined here:
+ 
+* `$brooklyn:attributeWhenReady("sensor")` will store a future which will be blocked when it is accessed,
+  until the given `sensor` from this entity "truthy" (i.e. non-trivial, non-empty, non-zero) value
+  (see below on `component` for looking up values on other sensors) 
+* `$brooklyn:config("key")` will insert the value set against the given key at this entity (or nearest ancestor);
+  can be used to supply config at the root which is used in multiple places in the plan
+* `$brooklyn:sensor("sensor.name")` returns the given sensor on the current entity if found, or an untyped (Object) sensor;
+  `$brooklyn:sensor("com.acme.brooklyn.ContainingEntityClass", "sensor.name")` returns the strongly typed sensor defined in the given class
+* `$brooklyn:entity("ID")` refers to a Brooklyn entity with the given ID; you can then access the following subfields,
+  using the same syntax as defined above but with a different reference entity,
+  e.g. `$brooklyn:entity("ID").attributeWhenReady("sensor")`:
+  * `.attributeWhenReady("sensor")`
+  * `.config("key")`
+  * `.sensor("sensor.name")`
+* `$brooklyn:component("scope", "ID")` is also supported, to limit scope to any of
+  * `global`: looks for the `ID` anywhere in the plan
+  * `child`: looks for the `ID` anywhere in the child only
+  * `descendant`: looks for the `ID` anywhere in children or their descendants
+  * `sibling`: looks for the `ID` anywhere among children of the parent entity
+  * `parent`: returns the parent entity (ignores the `ID`)
+  * `this`: returns this entity (ignores the `ID`)
+* `$brooklyn:root()` will return the topmost entity (the application)
+* `$broopklyn:scopeRoot()` will return the root entity in the current plan scope.
+  For catalog items it's the topmost entity in the plan, for application plans it is the same as
+  `$brooklyn:root()`.
+* `$brooklyn:formatString("pattern e.g. %s %s", "field 1", "field 2")` returns a future which creates the formatted string
+  with the given parameters, where parameters may be strings *or* other tasks such as `attributeWhenReady`
+* `$brooklyn:urlEncode("val")` returns a future which creates a string with the characters escaped
+  so it is a valid part of a URL. The parameter can be a string *or* another task. For example,
+  `$brooklyn:urlEncode($brooklyn:config(\"mykey\"))`. It uses "www-form-urlencoded" for the encoding,
+  which is appropriate for query parameters but not for some other parts of the URL (e.g. space is encoded as '+').
+* `$brooklyn:literal("string")` returns the given string as a literal (suppressing any `$brooklyn:` expansion)
+* `$brooklyn:object(Map)` creates an object, using keys `type` to define the java type,
+  and either `object.fields` or `brooklyn.config` to supply bean/constructor/flags to create an instance
+* `$brooklyn:entitySpec(Map)` returns a new `ServiceSpecification` as defined by the given `Map`,
+  but as an `EntitySpec` suitable for setting as the value of `ConfigKey<EntitySpec>` config items
+  (such as `dynamiccluster.memberspec` in `DynamicCluster`)
+
+<!-- TODO examples for object and entitySpec -->
+
+Parameters above can be supplied either as strings or as lists and maps in YAML, 
+and the `$brooklyn:` syntax can be used within those parameters.  
+
+
+## Some Powerful YAML Entities
+
+All entities support configuration via YAML, but these entities in particular 
+have been designed for general purpose use from YAML.  Consult the Javadoc for these
+elements for more information:
+
+* **Vanilla Software** in `VanillaSoftwareProcess`: makes it very easy to build entities
+  which use `bash` commands to install and the PID to stop and restart
+* **Chef** in `ChefSoftwareProcess`: makes it easy to use Chef cookbooks to build entities,
+  either with recipes following conventions or with configuration in the `ServiceSpecification`
+  to use artibitrary recipes 
+* `DynamicCluster`: provides resizable clusters given a `dynamiccluster.memberspec` set with `$brooklyn.entitySpec(Map)` as described above 
+* `DynamicFabric`: provides a set of homogeneous instances started in different locations,
+  with an effector to `addLocation`, i.e. add a new instance in a given location, at runtime

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/index.md
----------------------------------------------------------------------
diff --git a/guide/index.md b/guide/index.md
index cdb3b46..f3dbfff 100644
--- a/guide/index.md
+++ b/guide/index.md
@@ -8,8 +8,7 @@ children:
 - { path: /guide/start/index.md }
 - { path: /guide/misc/download.md }
 - { path: /guide/concepts/index.md }
-- { path: /guide/yaml/index.md }
-- { path: /guide/java/index.md }
+- { path: /guide/blueprints/index.md }
 - { path: /guide/ops/index.md }
 - { path: /guide/misc/index.md }
 ---

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/java/archetype.md
----------------------------------------------------------------------
diff --git a/guide/java/archetype.md b/guide/java/archetype.md
deleted file mode 100644
index 4bc7325..0000000
--- a/guide/java/archetype.md
+++ /dev/null
@@ -1,114 +0,0 @@
----
-title: Creating from a Maven Archetype
-layout: website-normal
-toc: ../guide_toc.json
-categories: [use, guide, defining-applications]
----
-
-### Maven Archetype
-
-Brooklyn includes a maven archetype, which can be used to create the project structure for 
-developing a new Java entity, and generating the OSGi bundle for it.
-
-
-#### Generating the Project
-
-The archetype can be used interactively, by running:
-{% highlight bash %}
-$ mvn archetype:generate
-{% endhighlight %}
-
-The user will be prompted for the archetype to use (i.e. group "org.apache.brooklyn" 
-and artifact "brooklyn-archetype-quickstart"), as well as options for the project 
-to be created.
-
-Alternatively, all options can be supplied at the command line. For example, 
-if creating a project named "autobrick" for "com.acme":
-
-{% highlight bash %}
-$ BROOKLYN_VERSION={{ site.brooklyn-version }}
-$ mvn archetype:generate \
-	-DarchetypeGroupId=org.apache.brooklyn \
-	-DarchetypeArtifactId=brooklyn-archetype-quickstart \
-	-DarchetypeVersion=${BROOKLYN_VERSION} \
-	-DgroupId=com.acme \
-	-DartifactId=autobrick \
-	-Dversion=0.1.0-SNAPSHOT \
-	-DpackageName=com.acme.autobrick \
-	-DinteractiveMode=false
-{% endhighlight %}
-
-This will create a directory with the artifact name (e.g. "autobrick" in the example above).
-Note that if run from a directory containing a pom, it will also modify that pom to add this as 
-a module!
-
-The project will contain an example Java entity. You can test this using the supplied unit tests,
-and also replace it with your own code.
-
-The `README.md` file within the project gives further guidance.
-
-
-#### Building
-
-To build, run the commands:
-
-{% highlight bash %}
-$ cd autobrick
-$ mvn clean install
-{% endhighlight %}
-
-
-#### Adding to the Catalog
-
-The build will produce an OSGi bundle in `target/autobrick-0.1.0-SNAPSHOT.jar`, suitable for 
-use in the [Brooklyn catalog]({{ site.path.guide }}/ops/catalog/) (using `brooklyn.libraries`).
-
-To use this in your Brooklyn catalog you will first have to copy the target jar to a suitable location. 
-For developing/testing purposes storing on the local filesystem is fine. 
-For production use, we recommend uploading to a remote maven repository or similar.
-
-Once your jar is in a suitable location the next step is to add a new catalog item to Brooklyn. 
-The project comes with a `catalog.bom` file, located in `src/main/resources`. 
-Modify this file by adding a 'brooklyn.libraries' statement to the bom pointing to the jar. 
-For example:
-
-{% highlight yaml %}
-brooklyn.catalog:
-    brooklyn.libraries:
-    - file:///path/to/jar/autobrick-0.1.0-SNAPSHOT.jar
-    version: "0.1.0-SNAPSHOT"
-    itemType: entity
-    items:
-    - id: com.acme.autobrick.MySample
-      item:
-        type: com.acme.autobrick.MySample
-{% endhighlight %}
-
-The command below will use the CLI to add this to the catalog of a running Brooklyn instance:
-
-{% highlight bash %}
-    br catalog add catalog.bom
-{% endhighlight %}
-
-After running that command, the OSGi bundle will have been added to the OSGi container, and the
-entity will have been added to your catalog. It can then be used in the same way as regular AMP 
-entities.
-
-For example, you can use the blueprint:
-
-{% highlight yaml %}
-services:
-- type: com.acme.autobrick.MySample
-{% endhighlight %}
-
-
-### Testing Entities
-
-The project comes with unit tests that demonstrate how to test entities, both within Java and
-also using YAML-based blueprints.
-
-A strongly recommended way is to write a YAML test blueprint using the test framework, and making  
-this available to anyone who will use your entity. This will allow users to easily run the test
-blueprint in their own environment (simply by deploying it to their own Brooklyn server) to confirm 
-that the entity is working as expected. An example is contained within the project at 
-`src/test/resources/sample-test.yaml`.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/java/bundle-dependencies.md
----------------------------------------------------------------------
diff --git a/guide/java/bundle-dependencies.md b/guide/java/bundle-dependencies.md
deleted file mode 100644
index 5a894eb..0000000
--- a/guide/java/bundle-dependencies.md
+++ /dev/null
@@ -1,135 +0,0 @@
----
-title: Handling Bundle Dependencies
-layout: website-normal
----
-
-Some Java blueprints will require third party libraries. These need to be made available to the
-Apache Brooklyn runtime. There are a number of ways this can be achieved.
-
-### Classic Mode: Dropins Folder
-
-In Brooklyn classic mode (i.e. when not using Karaf), jars can be added to `./lib/dropins/`.
-After restarting Brooklyn, these will be available on the classpath.
-
-In Brooklyn classic mode, there is an embedded OSGi container. This is used for installing 
-libraries referenced in catalog items.
-
-### OSGi Bundles
-
-#### Introduction to OSGi Bundles
-
-An [OSGi bundle](https://en.wikipedia.org/wiki/OSGi#Bundles) is a jar file with additional 
-metadata in its manifest file. The `MANIFEST.MF` file contains the symbolic name and version 
-of the bundle, along with details of its dependencies and of the packages it exports 
-(which are thus visible to other bundles).
-
-The [maven-bundle-plugin](http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html) 
-is a convenient way of building OSGi bundles.
-
-#### OSGi Bundles Declared in Catalog Items  
-
-Within a [catalog item]({{ site.path.guide}}/ops/catalog/), a list of URLs can be supplied under
-`brooklyn.libraries`. Each URL should point to an OSGi bundle. This list should include the OSGi 
-bundle that has the Java code for your blueprint, and also the OSGi bundles that it depends
-on (including all transitive dependencies).
-
-It is vital that these jars are built correctly as OSGi bundles, and that all transitive 
-dependencies are included. The bundles will be added to Karaf in the order given, so a bundle's
-dependencies should be listed before the bundle(s) that depend on them.
-
-In the [GistGenerator example]({{ site.path.guide}}/java/defining-and-deploying.html), the 
-[catalog.bom file]({{ site.path.guide}}/java/gist_generator/gist_generator.bom) included
-the URL of the dependency `org.eclipse.egit.github.core`. It also (before that line) included
-its transitive dependency, which is a specific version of `gson`.
-
-For Java blueprint developers, this is often the most convenient way to share a blueprint.
-
-Similarly for those wishing to use a new blueprint, this is often the simplest mechanism: the
-dependencies are fully described in the catalog item, which makes it convenient for deploying 
-to Apache Brooklyn instances where there is not direct access to Karaf or the file system.
-
-
-#### Adding Bundles and Features Directly to Karaf
-
-Bundles and features can be added manually, directly to Karaf.
-
-However, note this only affects the single Karaf instance. If running in HA mode or if provisioning
-a new instance of Apache Brooklyn, the bundles will also need to be added to these Karaf instances.
-
-
-##### Karaf Console
-
-Login to the [Karaf console](https://karaf.apache.org/manual/latest/#_shell_console_basics)
-using `./bin/client`, and add the bundles and features as desired.
-
-Examples of some useful commands are shown below:
-
-{% highlight bash %}
-karaf@amp> bundle:install -s http://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.egit.github.core/2.1.5_1/org.apache.servicemix.bundles.egit.github.core-2.1.5_1.jar
-Bundle ID: 316
-
-karaf@amp> bundle:list -t 0 -s | grep github
-318 | Active   |  80 | 2.1.5.1                       | org.apache.servicemix.bundles.egit.github.core
-
-karaf@amp> bundle:headers org.apache.servicemix.bundles.egit.github.core
-...
-
-karaf@amp> bundle:uninstall org.apache.servicemix.bundles.egit.github.core
-{% endhighlight %}
-
-
-##### Karaf Deploy Folder
-
-Karaf support [hot deployment](https://karaf.apache.org/manual/latest/#_deployers). There are a 
-set of deployers, such as feature and KAR deployers, that handle deployment of artifacts added
-to the `deploy` folder.
-
-Note that the Karaf console can give finer control (including for uninstall).
-
-
-### Karaf KAR files
-
-[Karaf KAR](https://karaf.apache.org/manual/latest/kar) is an archive format (Karaf ARchive).
-A KAR is a jar file (so a zip file), which contains a set of feature descriptors and bundle jar files.
-
-This can be a useful way to bundle a more complex Java blueprint (along with its dependencies), to
-make it easier for others to install.
-
-A KAR file can be built using the 
-[maven plugin org.apache.karaf.tooling:features-maven-plugin](https://karaf.apache.org/manual/latest/#_maven).
-
-
-### Karaf Features
-
-A [karaf feature.xml](https://karaf.apache.org/manual/latest/#_create_a_features_xml_karaf_feature_archetype)
-defines a set of bundles that make up a feature. Once a feature is defined, one can add it to a Karaf instance:
-either directly (e.g. using the [Karaf console](https://karaf.apache.org/manual/latest/#_shell_console_basics)), or
-by referencing it in another feature.xml file. 
-
-
-### Embedded Dependencies
-
-An OSGi bundle can 
-[embed jar dependencies](http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html#embedding-dependencies)
-within it. This allows dependencies to be kept private within a bundle, and easily shipped with that bundle.
-
-To keep these private, it is vital that the OSGi bundle does not import or export the packages
-contained within those embedded jars, and does not rely on any of those packages in the public 
-signatures of any packages that are exported or imported.
-
-
-### Converting Non-OSGi Dependencies to Bundles
-
-If a dependencies is not available as an OSGi bundle (and you don't want to just [embed the jar](#embedded-dependencies)),
-there are a few options for getting an equivalent OSGi bundle:
-
-* Use a ServiceMix re-packaged jar, if available. ServiceMix have re-packed many common dependencies as
-  OSGi bundles, and published them on [Maven Central](https://search.maven.org).
-
-* Use the `wrap:` prefix. The [PAX URL Wrap protocol](https://ops4j1.jira.com/wiki/display/paxurl/Wrap+Protocol) 
-  is an OSGi URL handler that can process your legacy jar at runtime and transform it into an OSGi bundle.  
-  This can be used when declaring a dependency in your feature.xml, and when using the Karaf console's 
-  `bundle:install`. Note that it is not yet supported in Brooklyn's `brooklyn.libraries` catalog items.
-
-* Re-package the bundle yourself, offline, to produce a valid OSGi bundle.
-

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/java/common-usage.md
----------------------------------------------------------------------
diff --git a/guide/java/common-usage.md b/guide/java/common-usage.md
deleted file mode 100644
index ccafd9b..0000000
--- a/guide/java/common-usage.md
+++ /dev/null
@@ -1,205 +0,0 @@
----
-title: Common Classes and Entities
-layout: website-normal
----
-
-<!-- TODO old, needs work (refactoring!) and use of java_link -->
-
-### Entity Class Hierarchy
-
-By convention in Brooklyn the following words have a particular meaning:
-
-* *Group* - a homogeneous grouping of entities (which need not all be managed by the same parent 
-  entity)
-* *Cluster* - a homogeneous collection of entities (all managed by the "cluster" entity)
-* *Fabric* - a multi-location collection of entities, with one per location; often used with a cluster per location
-* *Application* - a top-level entity, which can have one or more child entities.
-
-The following constructs are often used for Java entities:
-
-* *entity spec* defines an entity to be created; used to define a child entity, or often to 
-  define the type of entity in a cluster.
-* *traits* (mixins) providing certain capabilities, such as *Resizable* and *Startable*.
-* *Resizable* entities can re-sized dynamically, to increase/decrease the number of child entities.
-  For example, scaling up or down a cluster. It could similarly be used to vertically scale a VM,
-  or to resize a disk.
-* *Startable* indicates the effector to be executed on initial deployment (`start()`) and on 
-  tear down (`stop()`).
-
-
-### Configuration
-
-Configuration keys are typically defined as static named fields on the Entity interface. These
-define the configuration values that can be passed to the entity during construction. For
-example:
-
-{% highlight java %}
-public static final ConfigKey<String> ROOT_WAR = new ConfigKeys.newStringConfigKey(
-        "wars.root",
-        "WAR file to deploy as the ROOT, as URL (supporting file: and classpath: prefixes)");
-{% endhighlight %}
-
-One can optionally define a `@SetFromFlag("war")`. This defines a short-hand for configuring the
-entity. However, it should be used with caution - when using configuration set on a parent entity
-(and thus inherited), the `@SetFromFlag` short-form names are not checked. The long form defined 
-in the constructor should be meaningful and sufficient. The usage of `@SetFromFlag` is therefore
-discouraged.
-
-The type `AttributeSensorAndConfigKey<?>` can be used to indicate that a config key should be resolved,
-and its value set as a sensor on the entity (when `ConfigToAttributes.apply(entity)` is called).
-
-A special case of this is `PortAttributeSensorAndConfigKey`. This is resolved to find an available 
-port (by querying the target location). For example, the value `8081+` means that then next available
-port starting from 8081 will be used.
-
-
-### Declaring Sensors
-
-Sensors are typically defined as static named fields on the Entity interface. These define 
-the events published by the entity, which interested parties can subscribe to. For example:
-
-{% highlight java %}
-AttributeSensor<String> MANAGEMENT_URL = Sensors.newStringSensor(
-        "crate.managementUri",
-        "The address at which the Crate server listens");
-{% endhighlight %}
-
-
-### Declaring Effectors
-
-Effectors are the operations that an entity supports. There are multiple ways that an entity can 
-be defined. Examples of each are given below.
-
-#### Effector Annotation
-
-A method on the entity interface can be annotated to indicate it is an effector, and to provide
-metadata about the effector and its parameters.
-
-{% highlight java %}
-@org.apache.brooklyn.core.annotation.Effector(description="Retrieve a Gist")
-public String getGist(@EffectorParam(name="id", description="Gist id") String id);
-{% endhighlight %}
-
-
-#### Static Field Effector Declaration
-
-A static field can be defined on the entity to define an effector, giving metadata about that effector.
-
-{% highlight java %}
-public static final Effector<String> EXECUTE_SCRIPT = Effectors.effector(String.class, "executeScript")
-        .description("invokes a script")
-        .parameter(ExecuteScriptEffectorBody.SCRIPT)
-        .impl(new ExecuteScriptEffectorBody())
-        .build();
-{% endhighlight %}
-
-In this example, the implementation of the effector is an instance of `ExecuteScriptEffectorBody`. 
-This implements `EffectorBody`. It will be invoked whenever the effector is called.
-
-
-#### Dynamically Added Effectors
-
-An effector can be added to an entity dynamically - either as part of the entity's `init()`
-or as separate initialization code. This allows the implementation of the effector to be shared
-amongst multiple entities, without sub-classing. For example:
-
-{% highlight java %}
-Effector<Void> GET_GIST = Effectors.effector(Void.class, "createGist")
-        .description("Create a Gist")
-        .parameter(String.class, "id", "Gist id")
-        .buildAbstract();
-
-public static void CreateGistEffectorBody implements EffectorBody<Void>() {
-    @Override
-    public Void call(ConfigBag parameters) {
-        // impl
-        return null;
-    }
-}
-
-@Override
-public void init() {
-    getMutableEntityType().addEffector(CREATE_GIST, new CreateGistEffectorBody());
-}
-{% endhighlight %}
-
-
-### Effector Invocation
-
-There are several ways to invoke an effector programmatically:
-
-* Where there is an annotated method, simply call the method on the interface.
-
-* Call the `invoke` method on the entity, using the static effector declaration. For example:  
-  `entity.invoke(CREATE_GIST, ImmutableMap.of("id", id));`.
-
-* Call the utility method `org.apache.brooklyn.core.entity.Entities.invokeEffector`. For example:  
-  `Entities.invokeEffector(this, targetEntity, CREATE_GIST, ImmutableMap.of("id", id));`.
-
-When an effector is invoked, the call is intercepted to wrap it in a task. In this way, the 
-effector invocation is tracked - it is shown in the Activity view.
-
-When `invoke` or `invokeEffector` is used, the call returns a `Task` object (which extends 
-`Future`). This allows the caller to understand progress and errors on the task, as well as 
-calling `task.get()` to retrieve the return value. Be aware that `task.get()` is a blocking 
-function that will wait until a value is available before returning.
-
-
-### Tasks
-
-_Warning: the task API may be changed in a future release. However, backwards compatibility
-will be maintained where possible._
-
-When implementing entities and policies, all work done within Brooklyn is executed as Tasks.
-This makes it trackable and visible to administrators. For the activity list to show a break-down 
-of an effector's work (in real-time, and also after completion), tasks and sub-tasks must be 
-created.
-
-In common situations, tasks are implicitly created and executed. For example, when implementing
-an effector using the `@Effector` annotation on a method, the method invocation is automatically
-wrapped as a task. Similarly, when a subscription is passed an event (e.g. when using 
-`SensorEventListener.onEvent(SensorEvent<T> event)`, that call is done inside a task.
-
-Within a task, it is possible to create and execute sub-tasks. A common way to do this is to 
-use `DynamicTasks.queue`. If called from within a a "task queuing context" (e.g. from inside an
-effector implementation), it will add the task to be executed. By default, the outer task will not be
-marked as done until its queued sub-tasks are complete.
-
-When creating tasks, the `TaskBuilder` can be used to create simple tasks or to create compound tasks
-whose sub-tasks are to be executed either sequentially or in parallel. For example:
-
-{% highlight java %}
-TaskBuilder.<Integer>builder()
-        .displayName("stdout-example")
-        .body(new Callable<Integer>() { public Integer call() { System.out.println("example"; } })
-        .build();
-{% endhighlight %}
-
-There are also builder and factory utilities for common types of operation, such as executing SSH 
-commands using `SshTasks`.
-
-A lower level way to submit tasks within an entity is to call `getExecutionContext().submit(...)`.
-This automatically tags the task to indicate that its context is the given entity.
-
-An even lower level way to execute tasks (to be ignored except for power-users) is to go straight  
-to the `getManagementContext().getExecutionManager().submit(...)`. This is similar to the standard
-Java `Executor`, but also supports more metadata about tasks such as descriptions and tags.
-It also supports querying for tasks. There is also support for submitting `ScheduledTask` 
-instances which run periodically.
-
-The `Tasks` and `BrooklynTaskTags` classes supply a number of conveniences including builders to 
-make working with tasks easier.
-
-
-### Subscriptions and the Subscription Manager
-
-Entities, locations, policies and enrichers can subscribe to events. These events could be
-attribute-change events from other entities, or other events explicitly published by the entities.
-
-A subscription is created by calling `subscriptions().subscribe(entity, sensorType, sensorEventListener)`.
-The `sensorEventListener` will be called with the event whenever the given entity emits a sensor of
-the given type. If `null` is used for either the entity or sensor type, this is treated as a 
-wildcard.
-
-It is very common for a policy or enricher to subscribe to events, to kick off actions or to 
-publish other aggregated attributes or events. 

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/java/defining-and-deploying.md
----------------------------------------------------------------------
diff --git a/guide/java/defining-and-deploying.md b/guide/java/defining-and-deploying.md
deleted file mode 100644
index 8c1fc6e..0000000
--- a/guide/java/defining-and-deploying.md
+++ /dev/null
@@ -1,177 +0,0 @@
----
-title: Defining and Deploying
-layout: website-normal
----
-
-## Intro
-
-This walkthrough will set up a simple entity, add it to the catalog, and provision it.
-
-For illustration purposes, we will write an integration with [Github Gist](https://gist.github.com/), 
-with an effector to create new gists.
-
-
-## Project Setup
-
-Follow the instructions to create a new Java project using the [archetype](archetype.html), and
-import it into your [favorite IDE]({{ site.path.guide }}/dev/env/ide/). This example assumes you 
-used the groupId `com.acme` and artifact id `autobrick`.
-
-First ensure you can build this project at the command line, using `mvn clean install`.
-
-
-## Java Entity Classes
-
-For this particular example, we will use a third party Gist library, so will need to add that as 
-a dependency. Add the following to your `pom.xml` inside the `<dependencies>` section 
-(see [Maven](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html) 
-for more details):
-
-{% highlight xml %}
-<dependency>
-  <groupId>org.eclipse.mylyn.github</groupId>
-  <artifactId>org.eclipse.egit.github.core</artifactId>
-  <version>2.1.5</version>
-</dependency>
-{% endhighlight %}
-
-Create a new Java interface, `GistGenerator`, to describe the entity's interface (i.e. the 
-configuration options, sensors, and effectors). The code below assumes you have created this
-in the package `com.acme` for `src/main/java`.
-
-{% highlight java %}
-{% readj gist_generator/GistGenerator.java %}
-{% endhighlight %}
-
-To describe each part of this:
-
-* The `@ImplementedBy` indicates the implementation class for this entity type - i.e. the class 
-  to instantiate when an entity of this type is created.
-* By extending `Entity`, we indicate that this interface is an Entity type. We could alternatively
-  have extended one of the other sub-types of Entity.
-* The `OAUTH_KEY` is a configuration key - it is configuration that can be set on the entity when 
-  it is being instantiated.
-* The `@Effector` annotation indicates that the given method is an effector, so should be presented
-  and tracked as such. Execution of the effector is intercepted, to track it as a task and show its
-  execution in the Activity view.
-* The `@EffectorParam` annotations give metadata about the effector's parameters. This metadata,
-  such as the parameter description, is available to those using the client CLI, rest API and 
-  web-console.
-
-Note there is an alternative way of defining effectors - adding them to the entity dynamically, 
-discussed in the section [Dynamically Added Effectors](common-usage.html#dynamically-added-effectors).
-
-Next lets add the implementation. Create a new Java class named `GistGeneratorImpl`.
-
-{% highlight java %}
-{% readj gist_generator/GistGeneratorImpl.java %}
-{% endhighlight %}
-
-To describe each part of this:
-
-* Extends `AbstractEntity` - all entity implementations should extend this, or one of its 
-  sub-types.
-* Implements `GistGenerator`: this is the Entity type definition, so must be implemented.
-  Users of the entity will only refer to the interface; they will never be given an instance 
-  of the concrete class - instead a [dynamic proxy](https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html) 
-  is used (to allow remoting).
-* `org.slf4j.Logger` is the logger used throughout Apache Brooklyn.
-* Implements the `createGist` effector - we do not need to re-declare all the annotations.
-* If no `oath.key` parameter was passed in, then use the configuration set on the entity.
-* Use the third party library to create the gist.
-
-
-### Configuring GitHub
-
-First, create a github.com account, if you do not already have one.
-
-Before running the blueprint, we'll need to generate an access token that has permissions to
-create a gist programmatically.
-
-First [create a new access token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/) 
-that our blueprint will use to create a gist:
-
-[![Create a new access key.](gist_generator/gist_create_token.png "Create a new access key")](gist_generator/gist_create_token.png)
-
-Next, grant the token rights to create gists:
-
-[![Grant access.](gist_generator/gist_grant_access.png "Grant access")](gist_generator/gist_grant_access.png)
-
-
-### Testing
-
-The archetype project comes with example unit tests that demonstrate how to test entities, 
-both within Java and also using YAML-based blueprints. 
-
-We will create a similar Java-based test for this blueprint. Create a new Java class named 
-`GistGeneratorTest` in the package `com.acme`, inside `src/test/java`.
-
-You will need to substitute the github access token you generated in the previous section for
-the placeholder text `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`.
-
-{% highlight java %}
-{% readj gist_generator/GistGeneratorTest.java %}
-{% endhighlight %}
-
-Similarly, we can write a test that uses the `GistGenerator` from a YAML blueprint. 
-Create a new Java class named `GistGeneratorYamlTest` in the package `com.acme`, 
-inside `src/test/java`.
-
-Again you will need to substitute the github access token you generated in the previous section for
-the placeholder text `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`. See the section on 
-[externalised configuration]({{ site.path.guide }}/ops/externalized-configuration.html) 
-for how to store these credentials more securely. 
-
-{% highlight java %}
-{% readj gist_generator/GistGeneratorYamlTest.java %}
-{% endhighlight %}
-
-
-## Building the OSGi Bundle
-
-Next we will build this example as an [OSGi Bundle](https://www.osgi.org/developer/architecture/) 
-so that it can be added to the Apache Brooklyn server at runtime, and so multiple versions of the  
-blueprint can be managed.
-
-The `mvn clean install` will automatically do this, creating a jar inside the `target/` sub-directory
-of the project. This works by using the 
-[Maven Bundle Plugin](http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html)
-which we get automatically by declaring the `pom.xml`'s parent as `brooklyn-downstream-parent`.
-
-
-## Adding to the catalog
-
-Similar to the `sample.bom` entity that ships with the archetype, we will define a `.bom` file
-to add our `GistGenerator` to the catalog. Substitute the URL below for your own newly built 
-artifact (which will be in the `target` sub-directory after running `mvn clean install`).
-
-{% highlight yaml %}
-{% readj gist_generator/gist_generator.bom %}
-{% endhighlight %}
-
-See [Handling Bundle Dependencies]({{ site.path.guide}}/java/bundle-dependencies.html)
-for a description of the `brooklyn.libraries` used above, and for other alternative approaches.
-
-The command below will use the `br` CLI to add this to the catalog of a running Brooklyn instance.
-Substitute the credentials, URL and port for those of your server.
-
-{% highlight bash %}
-$ br login https://127.0.0.1:8443 admin pa55w0rd
-$ br catalog add gist_generator.bom
-{% endhighlight %}
-
-
-## Using the blueprint
-
-The YAML blueprint below shows an example usage of this blueprint:
-
-    name: my sample
-    services:
-    - type: example.GistGenerator
-      brooklyn.config:
-        oauth.key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
-Note the type name matches the id defined in the `.bom` file.
-
-You can now call the effector by any of the standard means - [web console]({{ site.path.guide }}/ops/gui/), 
-[REST api]({{ site.path.guide }}/ops/rest.html), or [Client CLI]({{ site.path.guide }}/ops/cli/).

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/1330dcd3/guide/java/enrichers.md
----------------------------------------------------------------------
diff --git a/guide/java/enrichers.md b/guide/java/enrichers.md
deleted file mode 100644
index 436a423..0000000
--- a/guide/java/enrichers.md
+++ /dev/null
@@ -1,180 +0,0 @@
----
-title: Enrichers
-layout: website-normal
-toc: ../guide_toc.json
-categories: [use, guide, defining-applications]
----
-
-Enrichers provide advanced manipulation of an entity's sensor values.
-See below for documentation of the stock enrichers available in Apache Brooklyn.
-
-#### Transformer
-
-[`org.apache.brooklyn.enricher.stock.Transformer`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Transformer.html)
-
-Takes a source sensor and modifies it in some way before publishing the result in a new sensor. See below an example using `$brooklyn:formatString`.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- 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"))
-{% endhighlight %}
-
-#### Propagator
-
-[`org.apache.brooklyn.enricher.stock.Propagator`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Propagator.html)
-
-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.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Propagator
-  brooklyn.config:
-    producer: $brooklyn:entity("cluster")
-- type: org.apache.brooklyn.enricher.stock.Propagator
-  brooklyn.config:
-    sensorMapping:
-      $brooklyn:sensor("url"): $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
-{% endhighlight %}
-
-#### Custom Aggregating
-
-[`org.apache.brooklyn.enricher.stock.Aggregator`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Aggregator.html)
-
-Aggregates multiple sensor values (usually across a tier, esp. a cluster) and performs a supplied aggregation method to them to return an aggregate figure, e.g. sum, mean, median, etc.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Aggregator
-  brooklyn.config:
-    enricher.sourceSensor: $brooklyn:sensor("webapp.reqs.perSec.windowed")
-    enricher.targetSensor: $brooklyn:sensor("webapp.reqs.perSec.perNode")
-    enricher.aggregating.fromMembers: true
-    transformation: average
-{% endhighlight %}
-
-There are a number of additional configuration keys available for the Aggregators:
-
-| Configuration Key                 | Default | Description                                                         |
-|-----------------------------------|---------|---------------------------------------------------------------------|
-| enricher.transformation.untyped   | list    | Specifies a transformation, as a function from a collection to the value, or as a string matching a pre-defined named transformation, such as 'average' (for numbers), 'sum' (for numbers), 'isQuorate' (to compute a quorum), or 'list' (the default, putting any collection of items into a list) |
-| quorum.check.type                 |         | The requirement to be considered quorate -- possible values: 'all', 'allAndAtLeastOne', 'atLeastOne', 'atLeastOneUnlessEmpty', 'alwaysHealthy'", "allAndAtLeastOne" |
-| quorum.total.size                 | 1       | The total size to consider when determining if quorate              |
-
-#### Joiner
-
-[`org.apache.brooklyn.enricher.stock.Joiner`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Joiner.html)
-
-Joins a sensor whose output is a list into a single item joined by a separator.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- 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
-{% endhighlight %}
-
-There are a number of additional configuration keys available for the joiner:
-
-| Configuration Key                 | Default | Description                                                         |
-|-----------------------------------|---------|---------------------------------------------------------------------|
-| enricher.joiner.separator         | ,       | Separator string to insert between each argument                    |
-| enricher.joiner.keyValueSeparator | =       | Separator string to insert between each key-value pair              |
-| enricher.joiner.joinMapEntries    | false   | Whether to add map entries as key-value pairs or just use the value |
-| enricher.joiner.quote             | true    | Whether to bash-escape each parameter and wrap in double-quotes     |
-| enricher.joiner.minimum           | 0       | Minimum number of elements to join; if fewer than this, sets null   |
-| enricher.joiner.maximum           | null    | Maximum number of elements to join (null means all elements taken)  |
-
-####	Delta Enricher
-
-[`org.apache.brooklyn.policy.enricher.DeltaEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/DeltaEnricher.html)
-
-Converts an absolute sensor into a delta sensor (i.e. the difference between the current and previous value)
-
-####	Time-weighted Delta
-
-[`org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricher.html)
-
-Converts absolute sensor values into a difference over time. The `enricher.delta.period` indicates the measurement interval.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher
-  brooklyn.config:
-    enricher.sourceSensor: reqs.count
-    enricher.targetSensor: reqs.per_sec
-    enricher.delta.period: 1s
-{% endhighlight %}
-
-####	Rolling Mean
-
-[`org.apache.brooklyn.policy.enricher.RollingMeanEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.html)
-
-Transforms a sensor into a rolling average based on a fixed window size. This is useful for smoothing sample type metrics, such as latency or CPU time
-
-#### Rolling Time-window Mean
-
-[`org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.html)
-
-Transforms a sensor's data into a rolling average based on a time window. This time window can be specified with the config key `confidenceRequired` - Minimum confidence level (ie period covered) required to publish a rolling average (default `8d`).
-
-#### Http Latency Detector
-
-[`org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher.HttpLatencyDetector`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.html)
-
-An Enricher which computes latency in accessing a URL, normally by periodically polling that URL. This is then published in the sensors `web.request.latency.last` and `web.request.latency.windowed`.
-
-There are a number of additional configuration keys available for the Http Latency Detector:
-
-| Configuration Key                 | Default | Description                                                          |
-|-----------------------------------|---------|----------------------------------------------------------------------|
-| latencyDetector.url               |         | The URL to compute the latency of                                    |
-| latencyDetector.urlSensor         |         | A sensor containing the URL to compute the latency of                |
-| latencyDetector.urlPostProcessing |         | Function applied to the urlSensor value, to determine the URL to use |
-| latencyDetector.rollup            |         | The window size (in duration) over which to compute                  |
-| latencyDetector.requireServiceUp  | false   | Require the service is up                                            |
-| latencyDetector.period            | 1s      | The period of polling                                                |
-
-#### Combiner
-
-[`org.apache.brooklyn.enricher.stock.Combiner`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Combiner.html)
-
-Can be used to combine the values of sensors.  This enricher should be instantiated using `Enrichers.builder().combining(..)`.
-This enricher is only available in Java blueprints and cannot be used in YAML.
-
-#### Note On Enricher Producers
-
-If an entity needs an enricher whose source sensor (`enricher.sourceSensor`) belongs to another entity, then the enricher
-configuration must include an `enricher.producer` key referring to the other entity.
-
-For example, if we consider the Transfomer from above, suppose that `enricher.sourceSensor: $brooklyn:sensor("urls.tcp.list")`
-is actually a sensor on a different entity called `load.balancer`. In this case, we would need to supply an
-`enricher.producer` value.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Transformer
-  brooklyn.config:
-    enricher.producer: $brooklyn:entity("load.balancer")
-    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.string")
-    enricher.targetSensor: $brooklyn:sensor("urls.tcp.withBrackets")
-    enricher.targetValue: |
-      $brooklyn:formatString("[%s]", $brooklyn:attributeWhenReady("urls.tcp.string"))
-{% endhighlight %}
-
-It is important to note that the value supplied to `enricher.producer` must be immediately resolvable. While it would be valid
-DSL syntax to write:
-
-{% highlight yaml %}
-enricher.producer: brooklyn:entity($brooklyn:attributeWhenReady("load.balancer.entity"))
-{% endhighlight %}
-
-(assuming the `load.balancer.entity` sensor returns a Brooklyn entity), this will not function properly because `enricher.producer`
-will unsuccessfully attempt to get the supplied entity immediately.