Title: ACE User guide
This article describes how to use ACE and is a good starting point for new users of Apache
ACE. The remainder of this article assumes you have an ACE server and target up and
running. Follow the [getting started in 5 minutes](/docs/getting-started-5-mins.html)
guide in case you have not done so yet.
[TOC]
## Introduction
Apache ACE is a framework that enables you to provision OSGi software (components) in a
controlled manner. What this means is that you have a central server to which clients, or
"targets" in ACE terminology, connect and fetch their software from. This allows one to
control which target gets which software.
The software that is deployed to a target is composed of one or more distributions. A
distribution is roughly similar to a piece of self-contained software. For example, it
could be a plugin or even a full application. On their own, distributions consist of one
or more features, that provide pieces of functionality to your software. The difference
between a feature and distribution is that the former is not necessarily fully
self-contained: it might need other features in order to operate properly. Each feature
groups one or more artifacts. An artifact is anything from an OSGi bundle to a
configuration file or any other kind of artifact that is needed for the software to work.
The artifacts themselves reside in an OSGi Bundle Repository (OBR). Think of an OBR as a
repository, like the Maven repository or a content repository, storing *immutable*
versions of artifacts[^1]. You can use either the default OBR supplied by ACE or an
external one, such as [Sonatype's
Nexus](http://books.sonatype.com/nexus-book/reference/osgi-sect-hosted.html) for storing
your artifacts. As the OBR is the *single source* for all artifacts, and therefore the
software that is deployed on a target, ACE is able to calculate how to upgrade a target
from one version to another version. This is possible because *all* changes made to (the
metadata of) ACE are stored in an internal versioned database. In other words, ACE always
keeps a full history and audit trail for all changes, making it possible to go back and
forth between versions deployed on each target.
## Use cases and workflow
The typical use case for using ACE is where you want to control and manage which software
runs on what target. So, how does one use ACE in practice? To explain the typical workflow
of ACE, let's take the following example.
Assume you are working on a large OSGi-based system that provides some kind of service to
your users (the exact details on what it does isn't relevant for this example).
As professional taking development seriously, you want to set up a [DTAP
environment](http://en.wikipedia.org/wiki/Development,_testing,_acceptance_and_production).
Your developers are working on their development machines, creating and using the latest,
bleeding, edge of software they are working on. Even though they are smart guys that know
the software inside out and can set up their own environments, they still might want to
use ACE on their local machines to validate that changes they make indeed work when
deployed. In this cases it makes sense to use the same deployment method that is used in
production lateron as well.
There are also testers on your team, responsible for testing all the new features and bug
fixes made by your developers. This tester does not want to have to set up his own
environment and fiddle around with configuration files and such. Instead, he simply wants
a working test environment that runs a recent version of the software, or even want to go
back and forth between versions of the software. This is also were ACE can help you out.
All you need to do is create targets for testing, on which a recent software version gets
deployed. That "recent version", can, for example, be a nightly build that comes out of
your CI server that automatically gets pushed to ACE after the nightly build is finished.
Alternatively, the tester also can deploy an older version to his testing target through
the ACE server UI, for example, to do some regression testing. A third scenario might be
to duplicate the exact configuration and version that is currently deployed to a specific
user's target.
Before a new version of your software is put into production, your users want to do
acceptance testing to see whether this new version does not break anything. The acceptance
environment should only be updated when a new version is released and after that remains
as-is. In practice, this is most often not the case, as the acceptance environment is,
when not used by any user, confiscated by your tester for its daily testing purposes,
simply, because ACE allows him to easily deploy other versions to the acceptance
environment. When a user asks for an acceptance test, he simply deploys the latest
greatest official release to the acceptance environment, and lets the user do its testing.
After that, he can repurpose it again. Another scenario obviously is that users setup
dedicated targets for the purpose of acceptance testing.
When all acceptance tests are successful, the new version of your software needs to be
deployed on several production environments, which is done by you, the release
manager[^2]. As most production environments only differ in a few details, such as IP
addresses and maybe the database credentials, you use the template engine of ACE to make
specific configuration files for each production target. This way, you can easily scale up
your production environment by defining new targets and provide them with the necessary
configuration values.
### Workflow
Apache ACE can be used in many different workflows, which makes it rather difficult for
new users to comprehend to use ACE to its full extent. By default, that is, without any
configuration, the workflow of ACE is as follows (see also figure 1):
1. a release manager[^2], ensures that the targets are defined. This is where the software
is deployed and running. You can predefine each target using the ACE web UI, or start
each target (and configure them properly to contact your ACE server) and make them
appear automatically in your workspace (you might need to refresh your workspace before
targets appear in the web UI);
2. the release manager defines the features and distributions that need to be deployed. In
the simplest case, you can define only one feature and distribution, but go also define
much more fine-grained features and distributions if needed. The easiest way to define
features and distributions and to link them to each other is by using the ACE web UI.
This allows you to simply use the "add" buttons and drag-and-drop to achieve this;
3. the artifacts are added to your OBR. This can be done by uploading them through on of
the ACE clients, for example, the web UI. Once uploaded, the artifacts need to be
linked to features in order to be deployed to targets. Again, the ACE web UI makes this
easy by simply using drag-and-drop to link artifacts to features;
4. the next time the target contacts the ACE server, it will retrieve the configured
distribution(s);
5. If you linked artifacts to features using the ACE web UI, it will create "wildcard"
assocations, meaning that it will automatically use the latest version available for
each artifact. This means that if you update *existing* artifacts in the OBR, ACE will
automatically deploy them to all affected targets. If you add new artifacts, you need
to link them to existing or new features and distributions to deploy them.
**Figure 1**: A graphical overview of a typical workflow of ACE (click on image to see full size).
## Working with the ACE Server
The ACE web UI (see figure 2) might look a bit daunting at first, but once you become more
familiar with it, you'll see that it is rather easy to work with.
**Figure 2**: The server UI of ACE after logging in, showing the control area at the top, and the resource area below that (click on image to see full size).
After logging in, the main window consists of two main areas:
1. The control area at the top of the screen, where you can perform actions like
retrieving the latest repository changes, revert the changes you've made locally, add
new artifacts, and so on;
2. The resource area, consisting of (up to) four columns showing the current artifacts,
features, distributions and targets that are known to ACE. When you select an entity
here, the associated entities in other columns will automatically be highlighted,
giving you an instant overview of the links within the system.
Apache ACE allows for concurrent use at every aspect. Many targets can request different
versions of software that need to be served, while at the same time one or more users are
uploading artifacts and/or defining new features or distributions. To support this, ACE
has the concept of a "workspace". This somewhat resembles a VCS you might already use for
your software development. Prior to making changes, you need to "check out" a workspace in
an ACE client. In the web UI, this is done implicitly if you hit the "Retrieve" button.
Once the workspace is checked out, you can make any changes you want, that is, create
features, distributions, targets and/or create links between them. If you are finished,
you need to "commit" your workspace back to the ACE server to persist the changes.
Committing your changes in the ACE web UI is done by using the "Store" button. The
"Revert" button can be used to throw away your changes in the web UI. Note that this does
*not* retrieve the latest changes from the ACE server! This is only done when using the
"Retrieve" button.
### Uploading artifacts
The easiest way to add one or more *new* artifacts is by simply dragging and dropping them
on the artifact column. *Note that a drop is accepted only when a blue line or border is
shown around the artifacts column (see figure 3)*. The artifacts are uploaded
automatically in the background, and when they are complete, a summary of the upload
results is shown as notification (see figure 4).
**Figure 3**: Adding new artifacts by dragging them onto the artifacts column. Note the blue line surrounding the artifacts column denoting the drop can be accepted (click on image to see full size).
**Figure 4**: A notification is shown when all artifacts are successfully uploaded (click on image to see full size).
To add artifacts that are already in the OBR, you click the "Add artifact..." button. An
"Add artifact" dialog opens, showing the artifacts currently in the OBR (but not yet in
the list of selected artifacts) and a list of to-be-uploaded artifacts. This window also
allows you to upload artifacts, and offers two options to do so:
1. by uploading the individual artifacts by pressing the "Upload" button and selecting the
artifact from the file chooser dialog, or;
2. by using drag-and-drop: select all artifacts in an Explorer or Finder and drag them
onto the "Upload artifact" area. This way, you can upload multiple artifacts in one go.
If you try to upload an artifact that is not recognized by ACE, a failure notification is
displayed noting that that particular artifact is not uploaded (see figure 5). Adding
support for new types of artifacts in ACE is discussed in more details in [this
article](/docs/adding-custom-artifact-types.html).
**Figure 5**: A failure notification is shown when one or more artifacts could not be recognized by ACE.
Once all artifacts are uploaded, they appear as selected rows in the artifacts column. You
can immediately drag them onto the feature column to link them to a particular feature. By
double clicking on an artifact, you can edit some of its properties, for example, its
description.
To remove an artifact from the artifacts column, you simply press its trash-can icon. Note
that removing an artifact will only remove it from the artifacts column, *not* from the
OBR.
A very important concept to remember is that *all* metadata in Apache ACE is stored in
versioned databases. This makes it possible to determine what differences there are
between (any) two versions, but only if all artifacts in the OBR also remain the same once
they are uploaded. This is why ACE does not allow you to add the same artifact twice.
**NOTE**: As described earlier, all changes made through the Web UI need to be stored
explicitly by pressing the "Store" button or by hitting CTRL+S (or CMD+S if you happen to
use OSX), otherwise they will not be visible to the ACE server. In case you want to revert
all changes, you can use the "Revert" button or CTRL/CMD+U. This will ignore all local
changes but does *not* retrieve the latest state from the server. To retrieve the latest
state from the server, use the "Retrieve" button or CTRL/CMD+G.
### Creating a new feature, distribution and/or target
Adding features and distributions are very similar. You either click the "+" button above
the features column, or the "+" button above the distributions column. Alternatively, you
canuse the shortcut keys CTRL/CMD+F and/or CTRL/CMD+D to add new features/distributions.
In both cases, you are presented with a dialog that allows you to enter the (mandatory)
name of the feature or distribution and an optional description.
To define a new target in the ACE web UI, you can do either:
1. pre-register a target by clicking the "+" button above the targets column and entering
the name of the new target. This allows you to associate software to this target before
it has ever been started or seen by the server; or,
2. you can register a target that is already running and has already tried to fetch
software from the ACE server. The details on this will be discussed later on.
After a feature, distribution or target is created, you can edit its properties by double
clicking it. For features and distributions, this means you can alter their description,
while for targets, there are more possibilities to view and alter:
* On the **Management** tab, you can register a target, and change whether or not changes
to any distribution associated to that target should be automatically approved to make
the target obtain the latest software. If auto-approve is enabled, all updates will
automatically be approved and distributed to that target. If not, all updates must be
*explicitly* approved prior to being distributed to the target. For convenience, the "A"
button above the targets column in the main UI allows you to approve the changes for one
or more (selected) targets. The "R" button allows you to register one or more selected
targets in a single go;
* On the **Info** tab, you can view the current state of the target, such as the currently
installed version, or the latest available software version;
* On the **Log Viewer** tab, you can view the installation log of the target. This allows
you to review the installation of updates on that target;
* The **Tag Editor** tab allows you to define tags and their values (see also figure 8).
Tags can be used for many things, but one of their more interesting use cases is that
they can be used to replace variables in template artifacts that contain those tags.
This is useful, for example, to have a single configuration file that can be used for
multiple targets, because it is largely the same for all of them;
* The **Verify/resolve** tab provides a basic facility to verify whether a particular
distribution will actually resolve on the target.
### Creating associations
To link artifacts to features, you simply select the artifact and drag it on top of the
feature to which it should be associated. The same principle also applies if you want to
associate features to distributions and distributions to targets. To delete an association
once is created, you can click either the left- or the right hand side of the association
(viz. either the artifact or the feature), and click the "broken chain" button on the
opposite side of the association. For example, to delete an association between an feature
and distribution, you can select the feature first, and hit the "broken chain" button on
the distribution. Alternatively, you can select the distribution first and hit the "broken
chain" button on the feature to delete the association.
There is a subtle, but *very* important, difference when you associate a bundle-artifact
to a feature by dragging its symbolic name (without a version) onto a feature, or when you
drag a bundle-artifact with a version onto a feature. In the first case, you make a
"dynamic" association (see figure 6), which states that you always want the *latest*
version of that bundle to be associated to the feature, including any newer version that
might be uploaded in the future. In the latter case, you make a "static" association (see
figure 7), which states that you always want that particular version of that bundle to be
associated to the feature.
**Figure 6**: Creating a dynamic association by dragging the BSN of a bundle onto a feature.
**Figure 7**: Creating a static association by dragging a particular version of a bundle onto a feature.
Creating dynamic associations is currently only supported for bundle artifacts. For other
types of artifacts, such as configuration files, only static associations can be
created[^4].
### Configuring the server
The ACE server is completely modular and therefore can be configured in many different
ways. As such, the configuration of the server is done by using the Configuration Admin
service which is provisioned by means of configuration files that reside in the
conf directory. The filename of each configuration file equals the service PID
of the managed service and **must** end with .cfg. Directories are considered as
managed service factories of which the directory name equals the service PID.
Configuration files itself are simple Java property files containing key-value pairs
separated by newlines. Configuration values are allowed to contain "placeholders" or
"variables". Everything between ${ and } is considered a variable and
replaced by the value represented by that variable. For example, consider a variable
var that is defined as "value", then ${var} will be replaced
with "value". Variables can refer to another value in the *same* configuration
file, or to a property that is defined in the OSGi-framework or globally in your system as
environment setting.
The configuration files are watched continuously in the background, allowing you to adjust
the configuration of the ACE server at runtime without having to restart it.
## Running a target
As mentioned, a target represents a client on which software can be deployed by ACE.
Actually, a target consists of an OSGi runtime that runs *at least* the ACE management
agent. This management agent periodically checks with the ACE server whether or not new
software is available. In case new software is available for a target, it can
automatically download and install it.
ACE provides a single runnable JAR target.jar that starts an OSGi runtime, the
ACE management agent, and a Gogo shell for easy debugging and demo purposes. It is also
available in the ACE source repository as Eclipse project called run-target.
The management agent, or agent for short, does the following:
1. it uploads the audit log of the target to the ACE server. The audit log contains all
changes in bundle and framework state, such as the starting and stopping of the
framework and (de)installation of bundles;
2. it check whether or not software updates are available. If so, it will download it and
install this update automatically.
To run a target, you need to issue the following command:
:::sh
$ java \
-Dagent.identification.agentid=target-1 \
-Dagent.discovery.serverurls=http://my.ace.server:8080 \
-jar target.jar
____________________________
Welcome to Apache Felix Gogo
...
### Target configuration
The agent can be configured by supplying its options as commandline parameters (e.g.
-Dname=value). A list of most used options are[^8]:
agent.identification.agentid
: defines the name to uniquely identify a target on the ACE server. In case this option is
not supplied, a default value of defaultTargetID is used;
agent.discovery.serverurls
: defines the ACE server URLs to connect to. Multiple URLs can be given to get a form of
fail-over: in case a connection to the first URL cannot be established, the second URL
will be used, and so on. If this option is given, at least one URL should be supplied, and
multiple URLs can be supplied by separating them with a comma. If this option is omitted,
a default value of http://localhost:8080 is used;
agent.discovery.checking
: defines whether or not server URLs should be checked whether they are alive prior to
being used. This implies that a "ping" request is sent to the server URL that is going to
be used. Server URLs that are not responding will not be used and will cause another URL
(defined by agent.discovery.serverurls) to be picked instead. The default value
is true, which means that all server URLs are checked. Use false if your
ACE server(s) are not always available or when running the target on a flacky network;
agent.logging.level
: defines the log level of the agent, and should be one of the following values:
DEBUG, INFO, WARNING or ERROR. The default log level
is INFO;
agent.controller.syncinterval
: defines the interval (in seconds) in which the agent should synchronize with the ACE
server. A default of 60 seconds is used in case this option is not supplied;
agent.controller.syncdelay
: defines how long the agent should wait (in seconds) after startup before it will
synchronize with the ACE server for the first time. A default of 5 seconds is
used in case this option is not supplied;
agent.controller.streaming
: if given a value of false, all software updates will be downloaded completely
first after which it will be installed. Use this value in case you suffer from unreliable
network connections. A value of true (the default) causes the agent to download
and install any software update directly.
agent.controller.fixpackages
: if given a value of true (the default), software updates will only contain the
deltas or changed artifacts. For large deployment packages, this can dramatically reduce
the size of an update. Use a value of false to *always* get *all* artifacts for
*each* software update;
agent.controller.retries
: defines the number of times the agent should retry to install a software update in case
its installation fails. If omitted, an installation is retried 3 times;
agent.feedback.channels
: defines what feedback channels exist and should be synchronized with the ACE server.
Feedback channels can be used to report any kind of information back to the ACE server,
and is by default used to provide basic information on the OSGi environment to the ACE
server. If omitted, the default of auditlog is used. Multiple feedback channels
can be supplied by separating them with commas, like auditlog,myOwnLog. Note that
all mentioned feedback channels *must* be configured on the ACE server as well;
agent.logging.events.exclude
: defines the audit events that should be *excluded* from appearing on the audit feedback
channel. This parameter takes one or more event types represented by integers separated by
commas, for example, 2001,2003,2005,3001. By default, *no* events are excluded;
agent.connection.authtype
: defines how to connections to the server are to be authenticated. Valid values are
NONE for no authentication, BASIC for [using HTTP-BASIC
authentication](/docs/using-basic-auth.html) or CLIENTCERT for [using client
certificates](/docs/using-client-certificates.html). In case this option is omitted, a
value of NONE is assumed and **no** authentication is used. In case of the values
BASIC or CLIENTCERT, additional options should be supplied (see below);
agent.connection.username and agent.connection.password
: provide the username and password used for HTTP-BASIC authentication;
agent.connection.sslProtocol
: defines what SSL protocol is to be used for creating secure connections to the ACE
server, defaults to TLS;
agent.connection.keyfile and agent.connection.keypass
: provide the keystore file and password that contain the certificate information for
establishing a secure conncetion between agent and server;
agent.connection.trustfile and agent.connection.trustpass
: provide the truststore file and password that contain the trusted (server)
certificate(s) for establishing a secure connection between agent and server.
When the agent is started, a new target should appear in the ACE server after you
"Retrieve" the latest changes in the web UI. Note that this can take a little while since
the agent needs to synchronize with the server first, see
agent.controller.syncdelay and agent.controller.syncinterval options
above. If a new target is seen this way by an ACE server instead of adding it through the
"+" button above the targets column, it initially will be *unregistered*. This means that
no metadata is present in the ACE server yet and will not be created.
To register a target, you can either double click the target. On the "Management" tab, you
can check the "Registered?" option (and optionally the "Auto approve?" option as well) and
close the dialog by pressing "Ok"[^3]. Once a target is registered, it cannot be
unregistered unless it is deleted using the trash-icon. Alternatively, you can register
one or more targets directly by selecting them and pressing the "R" button above the
targets column.
### Using the template engine for targets
If you want to provision software to multiple targets, each of those targets probably need
to have their own specific configuration. For example, the IP address on which it should
listen for web requests, or the credentials to access a database. One could create
specific configuration files for each target, however, this can become quite tedious if
you have lots of targets. Besides that, ACE requires that each artifact has a unique name,
so you need to create unique file names for your configuration files for each change you
make. Fortunately, ACE provides an easier way to solve this problem: a template engine.
All configuration files[^5] can be regarded as templates, in which variables are replaced
with values supplied by ACE. In fact, the values are definable per target, distribution,
feature or artifact and ACE will collect all tags of entities that are associated with a
specific target. To define variables and their replacement values (or "tags") for, for
example, a distribution, open up its properties dialog by double clicking on it, and
selecting the "Tag Editor" tab. Each line in this editor represents a tag. The key of a
tag defines that (part of) the variable name to be replaced in configuration files, and
the value of a tag the actual replacement value.
In order to let ACE provision your (templated) configuration files to your target, you
need a **resource processor** that is capable of handling the configuration files. Without
such a resource processor, the configuration files cannot be deployed to your target. See
[this article](/docs/adding-custom-artifact-types.html) for more information about writing
resource processor for your configuration files, or use an existing one, such as [Felix
Autoconf resource
processor](http://felix.apache.org/documentation/subprojects/apache-felix-autoconf.html).
Suppose a valid resource processor is available that recognizes [Java Properties
XML](http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html), consider the
following configuration file:
:::xml
${context.address}
${context.port}
INFO
The ${context.address} and ${context.port} represent variables that can
be replaced. The context. (including the dot) prefix is mandatory, and everything
after this prefix is user-definable and considered as variable name. In this example, two
variables are expected: address and port. The values for these variables
can be added to entities by using the "Tag Editor", available when you double click on an
artifact, feature, distribution or target in the web UI[^6]. It does not really matter on
what entity the variables are actually defined, but in most cases they are either defined
on a distribution and/or target.
Suppose we want to deploy the aforementioned configuration file to two targets,
"target-1", which is supposed to listen on 192.168.2.1:80 and "target-2", which
is supposed to listen on 192.168.2.2:8080. To make the configuration file
specific for both targets, we simply need to define two tags on "target-1", like (see also
figure 7):
* address -> 192.168.2.1;
* port -> 80.
And similar tags on "target-2":
* address -> 192.168.2.2;
* port -> 8080.
**Figure 8**: Using the Tag Editor of a target to supply configuration variables.
Under the covers, ACE uses Velocity[^7] to parse the template. This means that, apart from
variable substitution, you can also use other Velocity macros and create more complex
configurations that might contain conditional sections, loops and other features Velocity
provides. See the Velocity documentation for more information on how to use this
functionality.
In case a variable cannot be resolved, it will simply not be replaced, but left as-is.
This could lead to invalid or unparsable artifacts (configuration files) on your target!
ACE will scan all configuration files and replace all known variables as soon as a new
deployment is created. This means that for our example, both "target-1" and "target-2"
will get a processed version of the configuration file, each with its own specific
content. ACE also automatically versions these generated files, to aid downgrading
software.
[^1]: Once an artifact is uploaded to the OBR, it cannot be modified anymore. This is
necessary in order to allow both software upgrades as downgrades and to ensure that
everything you do is reproducible. One thing to note is that this is not compatible with
the way that Maven handles snapshot versions. A snapshot can contain anything. In stead we
usually use the version qualifier to append a timestamp in such scenarios.
[^2]: To read more about the various roles used in Apache ACE, see [this
page](/docs/ace-roles.html);
[^3]: This is a limitation of the current web UI. It is possible to create more
sophisticated associations by using the REST API or the Gogo shell commands.
[^4]: Do not forget to store your changes!
[^5]: In fact any artifact can be considered as an template, but by default ACE only
considers configuration files.
[^6]: In other UIs, such as the Gogo shell, you need to supply these tags manually.
[^7]: Apache Velocity is an engine that can generate documents by combining a template
with a context that contains variables. To learn more about it, visit the [Velocity
website](http://velocity.apache.org/).
[^8]: A complete list of recognised options can be found in
[org.apache.ace.agent.AgentConstants](https://svn.apache.org/repos/asf/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java).
*[OBR]: OSGi Bundle Repository
*[DTAP]: Development, Testing, Acceptance and Production
*[CI]: Continuous Integration