anchor.diff:  * INSTALL_PLUGIN: Install a plugin. The following properties are supported:
   ** `pluginKey`: required
   ** `pluginType`: required for user provided key  (can be `ruby` or `java`)
  -** `pluginVersion`: optional (for plugins hosted on killbill github organization, there is a https://github.com/killbill/killbill-cloud/blob/master/kpm/lib/kpm/plugins_directory.yml[definition file] to map killbill version with plugin version)
  -** `pluginArtifactId`: required for user provided key  (the maven `artifactId`)
  -** `pluginGroupId`: required for user provided key  (the maven `groupId`)
  -** `pluginPackaging`: optional (the maven `packaging` that will default to `jar` for `java` plugin and `tar.gz` for `ruby` plugins)
  -** `pluginClassifier`: optional (the maven `classifier` that will default to null)
  +** `pluginVersion`: optional (for plugins hosted on the Kill Bill GitHub organization, there is a https://github.com/killbill/killbill-cloud/blob/master/kpm/lib/kpm/plugins_directory.yml[definition file] to map Kill Bill versions with plugin versions)
  +** `pluginArtifactId`: required for user provided key (the Maven `artifactId`)
  +** `pluginGroupId`: required for user provided key (the Maven `groupId`)
  +** `pluginPackaging`: optional (the Maven `packaging`, which will default to `jar` for `java` plugin and `tar.gz` for `ruby` plugins)
  +** `pluginClassifier`: optional (the Maven `classifier`, which will default to null)
   * START_PLUGIN: Start a plugin. The following properties are supported:
   ** `pluginKey`: required
   ** `pluginVersion`: optional (will default to latest installed version of that plugin)
  -* RESTART_PLUGIN:  Restart a plugin. All classes will be unloaded and new classes/ruby files will be loeaded and started. The following properties are supported:
  -** `pluginKey`: required
  -** `pluginVersion`: optional (will default to LATEST version)
  +* RESTART_PLUGIN:  Restart a plugin. All classes will be unloaded and new classes/ruby files will be loaded and started. The following properties are supported:
  +** `pluginKey`: required
  +** `pluginVersion`: optional (will default to latest version)
   * STOP_PLUGIN: Stop a plugin. All classes will be unloaded. The following properties are supported:
   ** `pluginKey`: required
  -** `pluginVersion`: optional (will default to LATEST version)
  -* UNINSTALL_PLUGIN: The command will disable the plugin so it will not be listed as the installed plugin, but the code will be kept on the filesystem (to optimize cases where one would want to re-install the same version of the plugin):
  -** `pluginKey`: required
  -** `pluginVersion`: optional (will default to LATEST version)
  +** `pluginVersion`: optional (will default to latest version)
  +* UNINSTALL_PLUGIN: The command will disable the plugin so it will not be listed as an installed plugin, but the code will be kept on the filesystem (to optimize cases where one would want to re-install the same version of the plugin):
  +** `pluginKey`: required
  +** `pluginVersion`: optional (will default to latest version)
   
   
   === Installation
   
  -The installation of a plugin occurs through the KPM plugin (which itself relies on KPM) and  consists of the following sequence:
  -
  -* Download the binaries and installing them on the filesystem at the right place
  +The installation of a plugin occurs through the KPM plugin (which itself relies on KPM) and consists of the following sequence:
  +
  +* Download the binaries and install them on the filesystem at the right place
   * Set that latest downloaded version as being the default one to start (`isSelectedForStart`)
  -* Notify killbill core to update its view of the existing plugins
  -
  -Example of installing a `paypal plugin` with a specified version of `4.0.0`:
  -[source,bash]
  -----
  -curl -v \
  --u admin:password \
  --H "X-Killbill-ApiKey: bob" \
  --H 'X-Killbill-ApiSecret: lazar' \
  --H "Content-Type: application/json" \
  --H 'X-Killbill-CreatedBy: stephane' \
  --X POST \
  ---data-binary '{
  -    "nodeCommandProperties": [
  -        {
  -            "key": "pluginKey",
  -            "value": "paypal"
  -        },
  -        {
  -            "key": "pluginVersion",
  -            "value": "4.0.0"
  -        }
  -    ],
  -    "nodeCommandType": "INSTALL_PLUGIN",
  -    "systemCommandType": "true"
  -}' \
  -"http://127.0.0.1:8080/1.0/kb/nodesInfo"
  -----
  -
  -Example of installing a `payment test plugin` (one must include all the maven coordinates to specify where this plugin should be installed from):
  -[source,bash]
  -----
  -curl -v \
  --u admin:password \
  --H "X-Killbill-ApiKey: bob" \
  --H 'X-Killbill-ApiSecret: lazar' \
  --H "Content-Type: application/json" \
  --H 'X-Killbill-CreatedBy: stephane' \
  --X POST \
  ---data-binary '{
  -    "nodeCommandProperties": [
  -        {
  -            "key": "pluginKey",
  -            "value": "killbill:payment-test"
  -        },
  -        {
  -            "key": "pluginArtifactId",
  -            "value": "payment-test-plugin"
  -        },
  -        {
  -            "key": "pluginGroupId",
  -            "value": "org.kill-bill.billing.plugin.ruby"
  -        },
  -        {
  -            "key": "pluginType",
  -            "value": "ruby"
  -        }
  -    ],
  -    "nodeCommandType": "INSTALL_PLUGIN",
  -    "systemCommandType": "true"
  -}' \
  -"http://127.0.0.1:8080/1.0/kb/nodesInfo"
  +* Notify Kill Bill core to update its view of the existing plugins
  +
  +Example of installing the `paypal` plugin with a specified version of `4.0.0`:
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     -H "Content-Type: application/json" \
  +     -H 'X-Killbill-CreatedBy: admin' \
  +     -X POST \
  +     --data-binary '{
  +         "nodeCommandProperties": [
  +             {
  +                 "key": "pluginKey",
  +                 "value": "paypal"
  +             },
  +             {
  +                 "key": "pluginVersion",
  +                 "value": "4.0.0"
  +             }
  +         ],
  +         "nodeCommandType": "INSTALL_PLUGIN",
  +         "systemCommandType": "true"
  +     }' \
  +     "http://127.0.0.1:8080/1.0/kb/nodesInfo"
  +----
  +
  +Example of installing the `payment test plugin` (one must include all the Maven coordinates to specify where this plugin should be installed from):
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     -H "Content-Type: application/json" \
  +     -H 'X-Killbill-CreatedBy: admin' \
  +     -X POST \
  +     --data-binary '{
  +         "nodeCommandProperties": [
  +             {
  +                 "key": "pluginKey",
  +                 "value": "killbill:payment-test"
  +             },
  +             {
  +                 "key": "pluginArtifactId",
  +                 "value": "payment-test-plugin"
  +             },
  +             {
  +                 "key": "pluginGroupId",
  +                 "value": "org.kill-bill.billing.plugin.ruby"
  +             },
  +             {
  +                 "key": "pluginType",
  +                 "value": "ruby"
  +             }
  +         ],
  +         "nodeCommandType": "INSTALL_PLUGIN",
  +         "systemCommandType": "true"
  +     }' \
  +     "http://127.0.0.1:8080/1.0/kb/nodesInfo"
   ----
   
   === Starting a plugin
   
  -Starting a plugin occurs purely through killbill (independent of the KPM plugin) and  consists of the following sequence:
  +Starting a plugin occurs purely through Kill Bill (independent of the KPM plugin) and consists of the following sequence:
   
   * Load the classes through the OSGI mechanism
   * Start the plugin
   * Update its view of the existing plugins
   
  -Example of starting the default installed version for the `paypal plugin`:
  -
  -[source,bash]
  -----
  -curl -v \
  --u admin:password \
  --H "X-Killbill-ApiKey: bob" \
  --H 'X-Killbill-ApiSecret: lazar' \
  --H "Content-Type: application/json" \
  --H 'X-Killbill-CreatedBy: stephane' \
  --X POST \
  ---data-binary '{
  -    "nodeCommandProperties": [
  -        {
  -            "key": "pluginKey",
  -            "value": "paypal"
  -        }
  -    ],
  -    "nodeCommandType": "START_PLUGIN",
  -    "systemCommandType": true
  -}' \
  -"http://127.0.0.1:8080/1.0/kb/nodesInfo"
  +Example of starting the default installed version for the `paypal` plugin:
  +
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     -H "Content-Type: application/json" \
  +     -H 'X-Killbill-CreatedBy: admin' \
  +     -X POST \
  +     --data-binary '{
  +         "nodeCommandProperties": [
  +             {
  +                 "key": "pluginKey",
  +                 "value": "paypal"
  +             }
  +         ],
  +         "nodeCommandType": "START_PLUGIN",
  +         "systemCommandType": true
  +     }' \
  +     "http://127.0.0.1:8080/1.0/kb/nodesInfo"
   ----
   
   === Stopping a plugin
   
  -Stopping a plugin occurs purely through killbill (independent of the KPM plugin) and  consists of the following sequence:
  +Stopping a plugin occurs purely through Kill Bill (independent of the KPM plugin) and consists of the following sequence:
   
   * Stop the plugin
   * Unload the classes through the OSGI mechanism
   * Update its view of the existing plugins
   
  -Example of stopping the running version of the  `paypal plugin`:
  -
  -[source,bash]
  -----
  -curl -v \
  --u admin:password \
  --H "X-Killbill-ApiKey: bob" \
  --H 'X-Killbill-ApiSecret: lazar' \
  --H "Content-Type: application/json" \
  --H 'X-Killbill-CreatedBy: stephane' \
  --X POST \
  ---data-binary '{
  -    "nodeCommandProperties": [
  -        {
  -            "key": "pluginKey",
  -            "value": "paypal"
  -        }
  -    ],
  -    "nodeCommandType": "STOP_PLUGIN",
  -    "systemCommandType": true
  -}' \
  -"http://127.0.0.1:8080/1.0/kb/nodesInfo"
  +Example of stopping the running version of the  `paypal` plugin:
  +
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     -H "Content-Type: application/json" \
  +     -H 'X-Killbill-CreatedBy: admin' \
  +     -X POST \
  +     --data-binary '{
  +         "nodeCommandProperties": [
  +             {
  +                 "key": "pluginKey",
  +                 "value": "paypal"
  +             }
  +         ],
  +         "nodeCommandType": "STOP_PLUGIN",
  +         "systemCommandType": true
  +     }' \
  +     "http://127.0.0.1:8080/1.0/kb/nodesInfo"
   ----
   
   === Restarting a plugin
   
  -Restarting a plugin consists of first stopping the plugin and then restarted the plugin (therefore unloading previous classes/code and reloading new one with a potentially different version).
  -
  -Example of restarting the running version of the  `paypal plugin`:
  -
  -[source,bash]
  -----
  -curl -v \
  --u admin:password \
  --H "X-Killbill-ApiKey: bob" \
  --H 'X-Killbill-ApiSecret: lazar' \
  --H "Content-Type: application/json" \
  --H 'X-Killbill-CreatedBy: stephane' \
  --X POST \
  ---data-binary '{
  -    "nodeCommandProperties": [
  -        {
  -            "key": "pluginKey",
  -            "value": "paypal"
  -        }
  -    ],
  -    "nodeCommandType": "RESTART_PLUGIN",
  -    "systemCommandType": true
  -}' \
  -"http://127.0.0.1:8080/1.0/kb/nodesInfo"
  +Restarting a plugin consists of first stopping the plugin and then restarting the plugin (therefore unloading previous classes and reloading new ones with a potentially different version).
  +
  +Example of restarting the running version of the  `paypal` plugin:
  +
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     -H "Content-Type: application/json" \
  +     -H 'X-Killbill-CreatedBy: admin' \
  +     -X POST \
  +     --data-binary '{
  +         "nodeCommandProperties": [
  +             {
  +                 "key": "pluginKey",
  +                 "value": "paypal"
  +             }
  +         ],
  +         "nodeCommandType": "RESTART_PLUGIN",
  +         "systemCommandType": true
  +     }' \
  +     "http://127.0.0.1:8080/1.0/kb/nodesInfo"
   ----
   
   === Uninstallation
   
  -Uninstalling a plugin consists in marking that plugin as being `disabled`. The code remains on the filesystem but killbill will ignore it.
  -
  -Example of uninstalling the  `paypal plugin`:
  -
  -[source,bash]
  -----
  -curl -v \
  --u admin:password \
  --H "X-Killbill-ApiKey: bob" \
  --H 'X-Killbill-ApiSecret: lazar' \
  --H "Content-Type: application/json" \
  --H 'X-Killbill-CreatedBy: stephane' \
  --X POST \
  ---data-binary '{
  -    "nodeCommandProperties": [
  -        {
  -            "key": "pluginKey",
  -            "value": "paypal"
  -        }
  -    ],
  -    "nodeCommandType": "UNINSTALL_PLUGIN",
  -    "systemCommandType": "true"
  -}' \
  -"http://127.0.0.1:8080/1.0/kb/nodesInfo"
  +Uninstalling a plugin consists of marking that plugin as being `disabled`. The code remains on the filesystem but Kill Bill will ignore it.
  +
  +Example of uninstalling the `paypal` plugin:
  +
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     -H "Content-Type: application/json" \
  +     -H 'X-Killbill-CreatedBy: admin' \
  +     -X POST \
  +     --data-binary '{
  +         "nodeCommandProperties": [
  +             {
  +                 "key": "pluginKey",
  +                 "value": "paypal"
  +             }
  +         ],
  +         "nodeCommandType": "UNINSTALL_PLUGIN",
  +         "systemCommandType": "true"
  +     }' \
  +     "http://127.0.0.1:8080/1.0/kb/nodesInfo"
   ----
   
   === Listing all the plugins
   
  -There is an api to retrieve the current view for each killbill node. That API provides details about the running versions of a killbill node along with all the plugin detail information (the json can be quote long so for better readibility one can pipe the output to `python -m json.tool` to format it nicely:
  -
  -[source,bash]
  -----
  -curl -u'admin:password' -v -H "X-Killbill-ApiKey: bob" -H 'X-Killbill-ApiSecret:lazar' http://127.0.0.1:8080/1.0/kb/nodesInfo | python -m json.tool
  -----
  -
  -That would provide the following output:
  -
  -There is an array of entries, one for each running killbill instance. Each of these entresi will contain the following:
  -
  -* nodeName: By default this is the `hostname` of the node running, but this can be configured.
  +There is an API to retrieve the current view for each Kill Bill node. That API provides details about the running versions of a Kill Bill node along with all the plugins detail information (the json can be quite longm so for better readibility one can pipe the output to `python -m json.tool` to format it nicely):
  +
  +[source,bash]
  +----
  +curl -v \
  +     -u admin:password \
  +     -H "X-Killbill-ApiKey: bob" \
  +     -H 'X-Killbill-ApiSecret: lazar' \
  +     http://127.0.0.1:8080/1.0/kb/nodesInfo | python -m json.tool
  +----
  +
  +The output provides an array of entries, one for each running Kill Bill instance. Each of these entries will contain the following:
  +
  +* nodeName: By default, the `hostname` of the node running, but this can be configured
   * bootTime: Time at which that node started
   * kbVersion: Version for https://github.com/killbill/killbill[killbill]
   * apiVersion: Version for https://github.com/killbill/killbill-api[killbill-api]
  
positive.code: [[overview]]
  == Overview
  
  Started with Kill Bill 0.16.0, it is now possible to go through all the lifecycle (`install`, `start`, `stop`, `uninstall` and `list status`) of a plugin using apis.
  The apis have been designed to work on a killbill deployment that consists of several instances.
  
  The feature relies on the following pieces:
  
  * A running version of a (or several) killbill server(s)
  * A running https://github.com/killbill/killbill-kpm-plugin[KPM plugin] on each killbill instance.
  
  Installing the KPM plugin will first need to happen using https://github.com/killbill/killbill-cloud/tree/master/kpm[KPM] itself.
  
  
negative.code:         "apiVersion": "0.32",
          "bootTime": "2015-12-18T19:44:23.000Z",
          "commonVersion": "0.12",
          "kbVersion": "0.15.11",
          "lastUpdatedDate": "2015-12-18T19:44:23.000Z",
          "nodeName": "127.0.0.1-8080",
          "platformVersion": "0.19",
          "pluginApiVersion": "0.18",
          "pluginsInfo": [
  