10.3. The Deployment Agent

Actions performed

The deployment agent listens for local configuration changes on the io.fabric8.agent PID. Any change in that configuration will trigger the deployment agent.
When the deployment agent is triggered, it performs the following actions:
  1. The deployment agent reads the whole io.fabric8.agent PID and calculates what bundles are to be installed in the container.
  2. If the profiles assigned to the container specify any Karaf features, the deployment agent translates them into a list of bundles, so that the agent obtains a complete list of bundles to install.
  3. The deployment agent compares the list of bundles to install with the list of bundles currently installed, in order to identify:
    • Bundles to uninstall,
    • Bundles to install,
    • Bundles to update.
  4. The deployment agent then performs the bundle uninstalling, installing, and updating in the container.

Downloading artifacts

The deployment agent is capable of downloading artifacts from two different types of maven repository:
  • Registered Fabric Maven proxies
  • Configured Maven repositories (any Maven repository configured in the profile overlay).
Priority is always given to the Fabric Maven proxies. If more than one Maven proxy is registered in the fabric, the proxies are used in order, from the oldest to the newest.
If the target artifact is not found in the Maven proxies, the configured Maven repositories are used instead. The list of repositories is determined by the org.ops4j.pax.url.mvn.repositories property of the io.fabric8.agent PID.
To change the list of repositories for a specific profile, you can simply change the org.ops4j.pax.url.mvn.repositories property using the fabric:profile-edit command:
fabric:profile-edit --pid io.fabric8.agent/org.ops4j.pax.url.mvn.repositories=http://repositorymanager.mylocalnetwork.net default
It is recommended that you specify this configuration in one profile only, and have the rest of profiles inherit from it. The default profile, which is the ancestor of all of the standard profiles, is the ideal place for this.

Container restarts

In most cases, when a container is provisioned by the provisioning agent, the container is kept alive and no restart is needed. A restart becomes necessary, however, whenever the following changes are made:
  • Changes to the OSGi framework;
  • Changes to the OSGi framework configuration.
The normal case is where the container stays alive during provisioning, because it is rarely necessary to make changes to the underlying OSGi framework. If a container does need to restart, the restart is performed automatically by the deployment agent and, after the restart, the container reconnects to the cluster without any manual intervention.

Monitoring the provisioning status

Throughout the whole process of deploying and provisioning, the deployment agent stores the provisioning status in the runtime registry, so that it is available to the whole cluster. The user can check the provisioning status at any time using the fabric:container-list command.
JBossFuse:karaf@root> fabric:container-list

[id]                           [version] [alive] [profiles]                     [provision status]
root*                          1.0       true    fabric, fabric-ensemble-0000-1 success
mq1                            1.0       true    mq                             success
mq2                            1.0       true    mq                             downloading
billing-broker                 1.0       true    billing                        success
    admin-console              1.0       true    web, admin-console             success
To monitor the provisioning status in real time, you can pass the fabric:container-list command as an argument to the shell:watch command, as follows:
shell:watch fabric:container-list

Resolution and startup ordering

To figure out what bundles need to be installed and what bundles need to be removed, the Fabric agent uses the OSGi Bundle Repository (OBR) resolver. The OBR resolver makes sure that all requirements are met (usually package requirements, but potentially also service requirements). To discover a bundle's requirements, the OBR reads the following bundle headers:
For each package listed here, the OBR resolver searches for a bundle that declares the package in a corresponding Export-Package header.
For each service listed here, the OBR resolver searches for a bundle that declares the service in a corresponding Export-Service header.
If you are using Blueprint configuration files, it is especially important to be aware of the need to add an Export-Service header to bundles that implement services. Blueprint configuration files with mandatory references to services will automatically be packaged with the Import-Service bundle header (assuming that you use the maven-bundle-plugin). If the bundle that exports the service does not explicitly specify an Export-Service header, resolution will fail. To fix this error, either the exporter bundle must add an Export-Service declaration, or the importer bundle must remove the Import-Service directive.
If resolution is successful, the Fabric agent will start the bundles. Even though you should try to avoid having requirements in the startup order of your bundles, the Fabric agent will attempt to start the bundles based on their expressed requirements and capabilities. This will not solve all issues, especially in cases where asynchronous service registration is involved. The best way to deal with this kind of issues is to use OSGi services.