14.2. How a Managed Container Resolves Artifacts

Overview

Maven proxies play a critically important role in the way managed containers resolve Maven artifacts. When a managed container fails to locate a needed artifact locally (in its system/ directory or in its local Maven repository) it tries to download the missing artifact from the fabric's Maven proxy server (master instance). In other words, downloading from the Maven proxy is the primary mechanism for managed containers to obtain new artifacts.
The process for resolving artifacts in a managed container is controlled by the Fabric8 agent, which detects when new artifacts need to be deployed (for example, as a result of editing a Fabric profile) and then calls into the Eclipse Aether layer to resolve the artifacts.

Fabric profiles drive bundle provisioning

In the context of Fabric, it is the Fabric profiles that drive provisioning of OSGi bundles and other resource. Provisioning is triggered whenever you edit and save properties from a current bundle—for example by adding a bundle.BundleName entry to the profile's agent properties. Provisioning can also be triggered when you edit other resources (not directly associated with OSGi Config Admin) in a profile—for example, by referencing a resource through a checksum property resolver (see Section C.6, “Checksum property resolver”).
In some cases, you might not want provisioning to be triggered right away. A more controlled way to roll out profile updates is to take advantage of profile versioning—see Section 6.3, “Profile Versions” for details.

Fabric8 agent

After provisioning has been triggered in a managed container, the Fabric8 agent automatically scans the changed profiles to check for any OSGi bundles or Karaf features that were added to (or deleted from) the profile. If there are any new bundles referenced using the mvn URL scheme, the Fabric8 agent is responsible for locating these new bundles through Maven. In the context of Fabric, the Fabric8 agent effectively plays the same role that the Pax URL Aether component plays in a standalone (non-Fabric) container.
In order to locate a Maven artifact, the Fabric8 agent parses the mvn URL, reads the relevant Maven configuration properties, and calls directly into the Eclipse Aether layer to resolve the referenced artifact.

Eclipse Aether layer

The Eclipse Aether layer is fundamental to Maven artifact resolution in Apache Karaf. Ultimately, resolution of Maven artifacts for the Karaf container is always performed by the Aether layer. Note that the Aether layer itself is stateless: the parameters required to perform resolution of a Maven artifact are passed to the Aether layer with every invocation.

Provisioning a managed container

Figure 14.2, “Provisioning a Managed Container” shows an outline of the process for resolving a Maven URL at run time in a managed container.

Figure 14.2. Provisioning a Managed Container

Provisioning a Managed Container

Provisioning steps

The steps followed to locate the required Maven artifacts are:
  1. Provisioning of a profile is triggered when the properties of a current profile are updated. In particular, whenever new bundles or features are added to a profile, the Fabric8 agent is responsible for resolving the new Maven artifacts (referenced through the mvn URL protocol).
  2. The Fabric8 agent reads its Maven configuration from the io.fabric8.agent PID in the default profile (and possibly also from a Maven settings.xml file, if so configured).
  3. The Fabric8 agent contacts Zookeeper to discover the repository URL of the Fabric8 Maven proxy (master instance)—see Section 14.1, “Cluster of Fabric Maven Proxies”. The Fabric8 agent then inserts the discovered Maven proxy URL at the head of the list of remote Maven repositories.
    The Fabric8 agent parses the requested Maven URL and combines this information with the specified configuration—including the discovered Maven proxy URL—in order to invoke the Eclipse Aether library.
  4. When the Aether library is invoked, the first step is to look up any local Maven repositories to try and find the Maven artifact. The following local repositories are configured by default:
    InstallDir/system
    The JBoss A-MQ system directory, which contains all of the Maven artifacts that are bundled with the JBoss A-MQ distribution.
    UserHome/.m2/repository
    The user's own local Maven repository in the user's home directory, UserHome.
    If the Maven artifact is found locally, skip straight to step 8.
  5. If the Maven artifact cannot be found in one of the local repositories, Aether next tries to download the artifact from the Maven proxy. If the Maven artifact is found in the Maven proxy, skip straight to step 7.
    Note
    If you configure the Fabric8 agent to use a HTTP proxy, the Maven proxy would also be accessed through the HTTP proxy. To bypass the HTTP proxy in this case, you could configure the Maven proxy host to be a HTTP non-proxy host—see the section called “Configuring a HTTP proxy”.
  6. Aether next tries to look up the specified remote repositories (using the list of remote repositories specified in the Fabric8 agent configuration). Because the remote repositories are located on the Internet (accessed through the HTTP protocol), it is necessary to have Internet access in order for this step to succeed.
    Note
    If your local network requires you to use a HTTP proxy to access the Internet, it is possible to configure Fabric8 to use a HTTP proxy. For example, see the section called “Configuring a HTTP proxy” for details.
  7. If the Maven artifact is found in the Maven proxy or in a remote repository, Aether automatically installs the artifact into the user's local Maven repository, so that another remote lookup will not be required.
  8. Finally, assuming that the Maven artifact has been successfully resolved, Karaf installs the artifact in the Karaf bundle cache, InstallDir/data/cache, and loads the artifact (usually, an OSGi bundle) into the container runtime. At this point, the artifact is effectively installed in the container.

io.fabric8.agent configuration

The resolution of Maven artifacts in a managed container is configured by setting properties from the io.fabric8.agent PID (also known as agent properties). The Maven properties are normally set in the default profile, which ensures that the same settings are used throughout the entire fabric (recommended).
For example, you can see how the Maven properties are set in the default profile using the fabric:profile-display command, as follows:
JBossFuse:karaf@root> profile-display default
...
Agent Properties : 
    ...
    org.ops4j.pax.url.mvn.globalUpdatePolicy = always
    org.ops4j.pax.url.mvn.defaultRepositories = file:${runtime.home}/${karaf.default.repository}@snapshots@id=karaf-default,
      file:${runtime.data}/maven/upload@snapshots@id=fabric-upload
    org.ops4j.pax.url.mvn.repositories = file:${runtime.home}/${karaf.default.repository}@snapshots@id=karaf-default,
      file:${runtime.data}/maven/upload@snapshots@id=fabric-upload,
      http://repo1.maven.org/maven2@id=central,
      https://repo.fusesource.com/nexus/content/groups/public@id=fusepublic,
      https://repository.jboss.org/nexus/content/repositories/public@id=jbosspublic,
      https://repo.fusesource.com/nexus/content/repositories/releases@id=jbossreleases,
      https://repo.fusesource.com/nexus/content/groups/ea@id=jbossearlyaccess,
      http://repository.springsource.com/maven/bundles/release@id=ebrreleases,
      http://repository.springsource.com/maven/bundles/external@id=ebrexternal
    ...
The properties prefixed by org.ops4j.pax.url.mvn.* are the Maven properties used by the Fabric8 agent.
Important
The org.ops4j.pax.url.mvn.* properties are not related to the Pax URL Aether component. There is some potential for confusion here, because the Fabric8 agent uses the same property names as Pax URL Aether. These properties are read by the Fabric8 agent, however, not by Pax URL Aether (and are associated with the io.fabric8.agent PID, not the org.ops4j.pax.url.mvn PID).