• Articles about computing
• Articles about software development
• Apache integration software
Deploying an OSGi application on Apache Fabric8, from the ground up
Apache Fabric8 is an OSGi-based platform
designed to run Apache integration products (ActiveMQ, Camel, CXF) in
a distributed environment. Fabric8 is broadly aligned with
RedHat JBoss Fuse 6.1, and the demonstrations in this article will
run on Fuse 6.1, with the few small changes that are mentioned.
The core of Fabric8 is a repository of software components, and a
distributed configuration management system. The configuration management
system keeps track of which software should be running on which
host (specifically, in which container — but more on that
This article briefly describes the Fabric8 architecture, and explains
how to deploy a simple application on it. I'll be using the
same "Tick/Tock" application as in the article
Dynamic configuration of OSGi bundles running on Apache Karaf, from the ground up. This application consists of
two OSGi bundles called Tick and Tock, that interact according to a service
producer/consumer model. The application is very simple, and the only
sign that it is running is to look for its messages in the log. I use
this application because it has few dependencies on other components,
and can easily be built from source using command-line tools. You won't
need to build the code to follow this article — just download
the application (see the Download link at the end of the article), and
unpack it to extract the two bundle archives
osgitest_tick1.jar. If you have no idea what
an OSGi bundle is, I would suggest reading my article
Creating OSGI bundles and services from the ground up using Apache Karaf. That article also describes how the Tick/Tock
application works, which might be helpful if you haven't looked at
earlier articles in this series.
The steps in this article were test using version 1.1.0.Beta4 of
Fabric8 and version 6.1.0-379 of JBoss Fuse, on a Fedora Linux system.
Windows users will, as always, have to fiddle about with some filenames.
Fabric8 provides a code and configuration repository, and a way to manage
will host that code in accordance with the configuration. Each container is
a JVM in its own right;
containers can be distributed across physical hosts, and will
synchronize to one another over the network. Each installation will have
at least one root container, that provides an administration console
and manages any number of child containers on which applications are deployed
(actually, you can deploy code on the root container as well, but that
doesn't really demonstrate anything interesting). The root container
provides a web-based administration GUI which listens, by
default, on port 8181. On the whole both the web GUI and the console
provide the same features, but in this article I use the console, simply
because it's easier to describe.
Child containers keep in constant communication with their root container,
but will continue to run if the root is shut down or becomes unreachable
(there will be many messages in the log if this happens, and containers
will strive to reconnect as soon as possible).
The unit of application deployment in Fabric8 is the profile.
A profile lists one or more features, each of which references
one or more bundles. The bundles can be OSGi bundles, as in this example,
or Fuse Application Bundles (FABs). The use FABs is sometimes
preferable, as some of the dependency management issues can be
taken care of at runtime, rather than being a chore for the developer.
However, the use of FABs is outside the scope of this article.
The list of features in the profile is just that — a list. There
is no actual code referenced in the profile, just the names of
the features. Associated with each profile is one or more
repositories. A repository is a URI that indicates a place
where the software features can be obtained. In practice,
this is usually a Maven repository, but in this example
the repository will be a simple XML file on the local filesystem,
which refers to OSGi bundles which are also on the local
filesystem. This is very easy to set up and test but, obviously,
it's limited to testing on a single host (unless you use
some sort of shared filesystem).
Each container caches the bundles it retrieves from the repository
so that although the repository itself might not be fault tolerant,
that won't reduce the fault tolerance of the fabric itself, once
code has been deployed.
Profiles can form a parent-child relationship and, in practice,
all administrator-defined profiles will need to inherit from the
default profile at least. The
specifies the components that are needed for inter-container communication
(among other things), and the container won't work properly without these
Profiles are also associated with a set of configuration properties,
of which more later.
the structure of a profile is shown diagramatically below:
profile configuration properties
profile repository list
In this example, we'll set up a very simple profile, which will
have the following structure:
bundle 1 ('osgitest_tick2.jar')
bundle 2 ('osgitest_tock2.jar')
profile configuration properties
'delay' (delay between ticks in milliseconds)
profile repository list (reference to a file 'features.xml')
The parent-child relationship between profiles is very important in
practice, because it allows profiles to differ only in their
configuration. For example, we could specify all the code needed to
implement a web services application in the parent profile, and
then in sub-profiles specify only configuration properties such as
the HTTP port. Then the different sub-profiles can be assigned to
different containers, so that each gets the same code but different
Install and initialize fabric8
Fabric8 is available from the Fabric8 web site. The RedHat product, JBoss Fuse 6.1,
is available from here,
but you'll need to sign up for the community program (free). In most
respects, so far as this simple article is concerned, the two pieces
of sofware behave identically. Where they don't, I'll point it out.
Note that the Fabric8 binary bundle is available in .zip or .tar.gz format.
The .zip format did not work for me — I suspect that Windows-friendly
.zip files unpack with missing permissions on Linux.
$ unzip fabric8-karaf-1.1.0.Beta4.tar.gz
$ cd fabric8-karaf-1.1.0.Beta4
Note that with Fuse the startup command is
Fabric8, the admin user credentials are already defined in the file
etc/users.properties. With Fuse this user is commented
out, so you'll need to restore it if you want to use the Web console.
The console command
fabric:create creates a default
configuration for the root container, for stand-alone use. You can
fabric:join to make a Fabric8 installation
participate in an existing cluster.
Create the application profile
The profile is the unit of application deployment. Running the command
Fabric8:karaf@root> profile-create --parents default test
creates a new profile called 'test' (sorry about the dull name), as
a child of the default profile. If you want to create a more sophisticated
application, it may be better to use one of the more feature-rich profiles
provided with Fabric8, than to define all the necessary dependencies in
your own profile; but 'default' is fine for this simple example.
Now we need to create the software repository, which will host the
two OSGi bundles that compromise the Tick/Tock application.
This repository will be on the local filesystem — not a great idea in
a production setting, but fine for this test.
The repository will consist of the two bundle JAR files (which can
be anywhere on the filesystem), and an XML file, whose location we
will supply to the profile. So the links go like this: the profile
references the filesystem location of the XML file, and the XML
file references the filesystem locations of the bundles. I have
created the XML file as
/home/kevin/features/features.xml — any location is fine for this simple test.
looks like this:
xml version="1.0" encoding="UTF-8"
This XML file indicates that one feature is available, called 'ticktock',
and that it consists of two OSGi bundles, whose full paths are specified.
To assign the 'ticktock' feature to a profile, we indicate the path
the XML file, and the name of the feature, as follows:
Fabric8:karaf@root> profile-edit --repositories file:///home/kevin/features/features.xml
Fabric8:karaf@root> profile-edit --features ticktock test
For a quick check that the profile has been set up:
Fabric8:karaf@root> profile-display test
Profile id: test
Version : 1.0
If it's more convenient, you can inspect and edit profiles and features using
the Web GUI — the 'test' profile is shown in the following
The values entered into the profile are not checked in any way at this stage, not even for basic sanity. It's easy to make mistakes with names and patchs, and generally these will not show up until you try to assign the profile to a container.
Manage the application on discrete containers
The application is now defined as a Fabric8 profile called 'test',
but it is
not deployed anywhere. The next step is to create a new container
into which to deploy the code, and to manage it. You can create
multiple containers, each with its own profile, or profiles, and
in a production environment they can be on distributed hosts.
For this example, we need only one container, to host the single
profile we've defined.
Create a new container called test1
The following console command creates a new container called
test1 (sorry about my lack of imagination, as always)
as a child of the root container. There are
variants of this command that will create multiple child containers,
Fabric8:karaf@root> container-create-child root test1
By default, containers are started as soon as they are created. They
will have a default profile, that is, enough code deployed on them to
be able to take part in administration operations.
Each container runs in its own JVM and, on Linux, you'll be able
to see the new container using the
The console command
container:info will helpfully give
the operating system process ID, which can be useful if you have
large numbers of containers running, and can't tell them apart.
When the container is created, its data and configuration are stored
in a subdirectory of the
instances directory of
the Fabric8 installation. Of
particular importance are the instance specific logs, which in
this example will be in
At first, there will only be a single
these logs are rotated as they fill up. In the following text, all
references to 'the log file' mean to
Install the feature on container test1
container-change-profile command to assign
the profile 'test' to the new container 'test1'.
Fabric8:karaf@root> container-change-profile test1 test
@notebox(If the container immediately loses contact with the console, so
that you can't even tell if it's running or not, consider whether you correctly specified the parent of the new profile. 'default' is not, in this case, a default — it must explicitly be given as the parent of the profile.)
In the log for the test1 container, you should see the application
bundles starting up, and the Tick service starting to issue Tick! messages.
65 - io.fabric8.fabric-agent - 1.1.0.Beta4 | Configuration changed. New bundles list:
65 - io.fabric8.fabric-agent - 1.1.0.Beta4 | file:///home/kevin/shared_source/osgitest2/osgitest_tick2.jar
65 - io.fabric8.fabric-agent - 1.1.0.Beta4 | file:///home/kevin/shared_source/osgitest2/osgitest_tock2.jar
111 - net.kevinboone.OSGiTest.tick - 1.0.2 | Tick bundle started
111 - net.kevinboone.OSGiTest.tick - 1.0.2 | updated() called
111 - net.kevinboone.OSGiTest.tick - 1.0.2 | Passed a null configuration
111 - net.kevinboone.OSGiTest.tick - 1.0.2 | Tick! (v2.05) after delay 5000 msec
112 - net.kevinboone.OSGiTest.tock - 1.0.2 | tock
Note that I've removed the date/time information from the log information
since this doesn't contribute much; so the first entry on each line
is the OSGi bundle ID. In this case, 65 is a system bundle that is
managing the code deployment, and 111 and 112 are the IDs of our
The message "Passed a null configuration" is displayed by the Tick bundle
because, at this point, no configuration has been defined in the
profile for this bundle. It must therefore using its default time
interval of five seconds. The next section explains how to configure
Configure the Tick service at runtime
Fabric8 contains a distributed persistent configuration store; this
means that any changes you make to a profile configuration, even
at runtime, are stored, and need not be made again. In a clustered
environment, the configuration is replicated such that the failure
of one node of the cluster should not prevent other nodes getting
access to their profiles' configuration. To set the value of
the tick interval in the 'test' profile,
profile-edit as follows:
Fabric8:karaf@root> profile-edit -p net.kevinboone.tick/delay=10000 test
net.kevinboone.tick is the 'Persistent ID'
defined by the Java class
the implements the Tick bundle. There is absolutely nothing — apart
from good documentation — to stop you entering the wrong ID here,
or the wrong property name,
and this is not considered an error. In an environment that
can be flexibly reconfigured at any time, it has to be possible to
add values to the profile that are not yet registered with any bundle,
or for the bundle to read values from the profile that have not
yet been defined. Considerable care is needed in this area to ensure
When the profile is updated, you should see the following messages
in the log, indicating that a new value for the tick delay has
113 - net.kevinboone.OSGiTest.tick - 1.0.2 | Passed a non-null configuration
113 - net.kevinboone.OSGiTest.tick - 1.0.2 | Passed a new delay: 10000 msec
113 - net.kevinboone.OSGiTest.tick - 1.0.2 | Tick! (v2.05) after delay 10000 msec
Remove the feature from container test1
To remove the feature, which amounts to undeploying the application
from the container,
container-remove-profile to remove the
profile from the container.
Fabric8:karaf@root> container-remove-profile test1 test
This change takes effect immediately on any container that uses
the affected profile. In the log, you should see the bundles
65 - io.fabric8.fabric-agent - 1.1.0.Beta4 | Stopping bundles:
112 - net.kevinboone.OSGiTest.tock - 1.0.2 | Tock bundle stopped
111 - net.kevinboone.OSGiTest.tick - 1.0.2 | Tick bundle stopped
Then the code will be dereferenced and eventually garbage-collected.
This has been a very brief overview of setting up a single Fabric8/Fuse6.1
installation, and deploying code on it. Although this example used only
a single physical host, the same basic principles apply to managing
the applications on containers in a distributed environment.
Source code, including compiled OSGi bundles