20.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 (that is, from one of the repositories on the local file system, as specified in the io.fabric8.agent PID's org.ops4j.pax.url.mvn.defaultRepositories property or org.ops4j.pax.url.mvn.localRepository property), it tries to download the needed artifact from one of the remote repositories, starting with the Maven proxies. In other words, downloading from a 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 ???).
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 ??? 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 20.1, “Provisioning a Managed Container” shows an outline of the process for resolving a Maven URL at run time in a managed container.

Figure 20.1. 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 the maven-settings.xml file, if so configured).
  3. The Fabric8 agent contacts Zookeeper to discover the URLs of the Fabric8 Maven proxy instances—see Section 20.1, “Introduction to Fabric Maven Proxies”. The Fabric8 agent then inserts the list of Maven proxy URLs at the head of the list of remote Maven repositories.
    The Fabric8 agent parses the requested mvn URL and combines this information with the specified configuration—including the list of Maven proxy URLs—in order to invoke the Eclipse Aether library.
  4. When the Aether library is invoked, the first step is to look up the Maven default repositories to try and find the Maven artifact. The following default repositories are configured by default:
    InstallDir/system
    The JBoss Fuse system directory, which contains all of the Maven artifacts bundled with the JBoss Fuse distribution.
    InstallDir/data/maven/upload
    If this container is an ensemble container (running a Maven proxy), this directory would contain any artifacts explicitly uploaded to the Maven proxy. In a managed container, this directory is normally empty.
    UserHome/.m2/repository
    The user's own local Maven repository in the user's home directory, UserHome.
    If the Maven artifact is found in a default repository, skip straight to step 8.
  5. The Aether library now begins the process of consulting the remote repositories (as specified by the io.fabric8.agent/org.ops4j.pax.url.mvn.repositories PID property and augmented by the list of Maven proxy URLs). This process works in tandem with the local Maven repository (as specified by the io.fabric8.agent/org.ops4j.pax.url.mvn.localRepository PID property), which acts as a cache for the remote repositories.
    The Aether library searches the repositories in the following order:
    • Local Maven repository—by default, InstallDir/data/repository-agent,
    • Maven proxies—iterating over the list of Maven proxy URLs added to the org.ops4j.pax.url.mvn.repositories argument.
    Note
    If you are using a HTTP proxy, you should configure the Fabric8 agent to bypass the HTTP proxy when it accesses the Maven proxy hosts. To bypass the HTTP proxy in this case, configure the Maven proxy hosts to be HTTP non-proxy hosts—see the section called “Configuring an HTTP proxy”.
  6. The Aether library continues the process of consulting the remote repositories, by accessing the remote repositories configured in the io.fabric8.agent/org.ops4j.pax.url.mvn.repositories PID property.
    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 an 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 local Maven repository, InstallDir/data/repository-agent, 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 = daily
    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,
      file:${user.home}/.m2/repository@snapshots@id=local
    ...
    org.ops4j.pax.url.mvn.globalChecksumPolicy = warn
    org.ops4j.pax.url.mvn.settings = ${karaf.etc}/maven-settings.xml
    ...
    org.ops4j.pax.url.mvn.localRepository = ${karaf.data}/repository-agent
    ...
    org.ops4j.pax.url.mvn.repositories = http://repo1.maven.org/maven2@id=maven.central.repo,
      https://maven.repository.redhat.com/ga@id=redhat.ga.repo,
      https://maven.repository.redhat.com/earlyaccess/all@id=redhat.ea.repo,
      https://repository.jboss.org/nexus/content/groups/ea@id=fuseearlyaccess
    ...
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).