Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

OSGi Provisioning

Thomas Diesler edited this page Jan 22, 2014 · 3 revisions

OSGi Class Loading

osgi-modularity

  • No separation between shared and unshared modules
  • Package visibility controlled by the underlying bundle
  • Separation between API and implementation modules works
  • Dependencies between implementation bundles not portable

OSGi Provisioner

Like with any other target container, Gravia provides an OSGi Provisioner Service that allows a client to use a container agnostic API together with a set of portable meta data and artefacts. Provisioning works from the content of the associate Repository. It also possible to deploy any other Bundle to the Framework by-passing the provisioning system - in this case we are talking about deployment which is not aware of the current runtime state of the container. Provisioning is aware of that runtime state and hence can guarantee to only provision the needed delta and guarantee transitions from one consistent runtime state to the next.

It is important to realise that in case of OSGi there are two sets of meta data and dependency definitions at play. The Gravia defined set of portable metadata is input to the Gravia Resolver and results in module wiring. The underlying OSGi framework uses the meta data defined in the bundle's manifest. Manifest defined dependencies are are input to the OSGi Resolver and result in bundle wiring

The module wiring is not derived from the bundle wiring, nor do Gravia defined dependencies determine the bundle wiring at runtime - there are completely separate. The Gravia notion of module wiring is however portable and works in all supported target containers.

Repository Resource Definitions

Below is a simple resource definition in the repository. The first defines an abstract "camel.core.feature", the second defines an actual resource that references the camel-core maven artefact.

<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="PersistentRepository">

  <!-- 
    camel.core.feature 
  -->
  <resource>
    <capability namespace="gravia.identity">
      <attribute name="gravia.identity" value="camel.core.feature" />
      <attribute name="type" value="abstract" />
    </capability>
    <requirement namespace="gravia.identity">
      <attribute name="gravia.identity" value="org.apache.camel.core" />
      <attribute name="version" value="[2.11,3.0)" />
    </requirement>
  </resource>
  <!-- 
    org.apache.camel.core
  -->
  <resource>
    <capability namespace="gravia.identity">
      <attribute name="gravia.identity" value="org.apache.camel.core" />
      <attribute name="maven.identity" value="org.apache.camel:camel-core:jar:2.11.0" />
      <attribute name="version" value="2.11.0" />
      <attribute name="shared" value="true" />
    </capability>
    <requirement namespace="gravia.identity">
      <attribute name="gravia.identity" value="javax.api" />
    </requirement>
    <requirement namespace="gravia.identity">
      <attribute name="gravia.identity" value="org.slf4j" />
    </requirement>
  </resource>
</repository>

Dependencies generally work with resource identities. The abstract camel.core.feature has a single resource dependency with a given version range. The "org.apache.camel.core" resource has resource dependencies on "javax.api" and "org.slf4j". These must either be provided by the Environment or defined in the repository so that they can be included in the set of artefacts that need to be provisioned. In the case of the default Karaf installation, "javax.api" and "org.slf4j" are provided by the environment.

Client API Usage

Client side usage of this API is simple. You can use any RequirementBuilder to build the requirement that you have on the runtime. Then pass that requirement to the provisioner, which on successful completion will return a set of resource handles. These handles can be used to interact with the associated modules or later to uninstall the resource from the runtime.

    ResourceIdentity identity = ResourceIdentity.fromString("camel.core.feature:0.0.0");
    Requirement req = new IdentityRequirementBuilder(identity).getRequirement();
    Set<ResourceHandle> result = provisioner.provisionResources(Collections.singleton(req));