

h1. Provisioning

Karaf provides a simple, yet flexible, way to provision applications or "features".  Such a mechanism is mainly provided by a set of commands available in the {{features}} shell.  The provisioning system uses xml "repositories" that define a set of features.

h2. Repositories

The complete xml schema for feature descriptor are available on [Features XML Schema|provisioning-schema] page. We recommend using this XML schema. It will allow Karaf to validate your repository before parsing. You may also verify your descriptor before adding it to Karaf by simply validation, even from IDE level.


Here is an example of such a repository:
{code:lang=xml}
<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
    <feature name="spring" version="3.0.4.RELEASE">
        <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_1</bundle>
        <bundle>mvn:org.springframework/spring-core/3.0.4.RELEASE</bundle>
        <bundle>mvn:org.springframework/spring-beans/3.0.4.RELEASE</bundle>
        <bundle>mvn:org.springframework/spring-aop/3.0.4.RELEASE</bundle>
        <bundle>mvn:org.springframework/spring-context/3.0.4.RELEASE</bundle>
        <bundle>mvn:org.springframework/spring-context-support/3.0.4.RELEASE</bundle>
    </feature>
</features>
{code}

A repository includes a list of {{feature}} elements, each one representing an application that can be installed.  The feature is identified by its {{name}} which must be unique amongst all the repositories used and consists of a set of bundles that need to be installed along with some optional dependencies on other features and some optional configurations for the Configuration Admin OSGi service.

References to features define in other repositories are allow and can be achieved by adding a list of repository.

{code:xml}
<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
  <repository>mvn:org.apache.servicemix.nmr/apache-servicemix-nmr/1.3.0/xml/features</repository>
  <repository>mvn:org.apache.camel.karaf/apache-camel/2.5.0/xml/features</repository>
  <repository>mvn:org.apache.karaf/apache-karaf/2.1.2/xml/features</repository>
  ...
{code}

{warning}
Be careful when you define them as there is a risk of 'cycling' dependencies.
{warning}

Remark: By default, all the features defined in a repository are not installed at the launch of Apache Karaf (see section hereafter 'h2. Service configuration' for more info).

h3. Bundles

The main information provided by a feature is the set of OSGi bundles that defines the application.  Such bundles are URLs pointing to the actual bundle jars.  For example, one would write the following definition:
{code:lang=xml}
<bundle>http://repo1.maven.org/maven2/org/apache/servicemix/nmr/org.apache.servicemix.nmr.api/1.0.0-m2/org.apache.servicemix.nmr.api-1.0.0-m2.jar</bundle>
{code}
Doing this will make sure the above bundle is installed while installing the feature.

However, Karaf provides several URL handlers, in addition to the usual ones (file, http, etc...). One of these is the Maven URL handler, which allow reusing Maven repositories to point to the bundles.

h4. Maven URL Handler

The equivalent of the above bundle would be:
{code}
<bundle>mvn:org.apache.servicemix.nmr/org.apache.servicemix.nmr.api/1.0.0-m2</bundle>
{code}
In addition to being less verbose, the Maven url handlers can also resolve snapshots and can use a local copy of the jar if one is available in your Maven local repository.

The {{org.ops4j.pax.url.mvn}} bundle resolves {{mvn}} URLs. This flexible tool can be configured through the configuration service. For example, to find the current repositories type:

{code}
karaf@root:/> config:list
...
----------------------------------------------------------------
Pid:            org.ops4j.pax.url.mvn
BundleLocation: mvn:org.ops4j.pax.url/pax-url-mvn/0.3.3
Properties:
   service.pid = org.ops4j.pax.url.mvn
   org.ops4j.pax.url.mvn.defaultRepositories = file:/opt/development/karaf/assembly/target/apache-felix-karaf-1.2.0-SNAPSHOT/system@snapshots
   org.ops4j.pax.url.mvn.repositories = http://repo1.maven.org/maven2, 
                                         http://svn.apache.org/repos/asf/servicemix/m2-repo 
   below = list of repositories and even before the local repository
{code}

The repositories checked are controlled by these configuration properties. 

For example, {{org.ops4j.pax.url.mvn.repositories}} is a comma separate list of repository URLs specifying those remote repositories to be checked. So, to replace the defaults with a new repository at {{http://www.example.org/repo}} on the local machine:

{code}
karaf@root:/> config:edit org.ops4j.pax.url.mvn
karaf@root:/> config:proplist                  
   service.pid = org.ops4j.pax.url.mvn
   org.ops4j.pax.url.mvn.defaultRepositories = file:/opt/development/karaf/assembly/target/apache-felix-karaf-1.2.0-SNAPSHOT/system@snapshots
   org.ops4j.pax.url.mvn.repositories = http://repo1.maven.org/maven2,
                                        http://svn.apache.org/repos/asf/servicemix/m2-repo
   below = list of repositories and even before the local repository
karaf@root:/> config:propset org.ops4j.pax.url.mvn.repositories http://www.example.org/repo
karaf@root:/> config:update
{code}

By default, snapshots are disabled. To enable an URL for snapshots append @snapshots. For example

{code}
http://www.example.org/repo@snapshots
{code}

Repositories on the local machine are supported through {{file:/}} URLs

h4. Bundle start-level

*Available since Karaf 2.0*

By default, the bundles deployed through the feature mechanism will have a start-level equals to the value defined in the configuration file {{config.properties}}
with the variable {{karaf.startlevel.bundle=80}}. This value can be changed using the xml attribute start-level. 

{code:xml}
  <feature name='my-project' version='1.0.0'>
    <feature version='2.4.0'>camel-spring</feature>
    <bundle start-level='80'>mvn:com.mycompany.myproject/myproject-dao</bundle>    
    <bundle start-level='85'>mvn:com.mycompany.myproject/myproject-service</bundle>
    <bundle start-level='85'>mvn:com.mycompany.myproject/myproject-camel-routing</bundle>
  </feature> 
{code}  

The advantage in defining the bundle start-level is that you can deploy all your bundles including any required 'infrastructure' bundles (e.g Camel, ActiveMQ)
at the same time and you will have the guarantee when using Spring Dynamic Modules or Blueprint that the Spring context will not be
created without all the required services installed.

h4. Bundle 'stop/start'

The OSGI specification allows for installing a bundle without starting it. To use this functionality, simply add the following attribute in your <bundle> definition

{code:xml}
  <feature name='my-project' version='1.0.0'>
    <feature version='2.4.0'>camel-spring</feature>
    <bundle start-level='80' start='false'>mvn:com.mycompany.myproject/myproject-dao</bundle>    
    <bundle start-level='85' start='false'>mvn:com.mycompany.myproject/myproject-service</bundle>
    <bundle start-level='85' start='false'>mvn:com.mycompany.myproject/myproject-camel-routing</bundle>
  </feature> 
{code}

h4. Bundle 'dependency'

A bundle can be flagged as being a dependency.  Such information can be used by resolvers to compute the full list of bundles to be installed.

h3. Dependent features

Dependent features are useful when a given feature depends on another feature to be installed.  Such a dependency can be expressed easily in the feature definition:
{code:lang=xml}
<feature name="jbi">
  <feature>nmr</feature>
  ...
</feature>
{code}

The effect of such a dependency is to automatically install the required {{nmr}} feature when the {{jbi}} feature is installed.

A version range can be specified on the feature dependency:
{code:lang=xml}
<feature name="spring-dm">
  <feature version="[2.5.6,4)">spring</feature>
  ...
</feature>
{code}
In such a case, if no matching feature is already installed, the feature with the highest version available in the range will be installed.  If a single version is specified, this version will be chosen.  If nothing is specified, the highest available will be installed.

h3. Configurations

The configuration section allows for declaring deployment configuration of the OSGi Configuration Admin service along a set of bundles.
Here is an example of such a configuration:

{code:lang=xml}
<config name="com.foo.bar">
  myProperty = myValue
</config>
{code}

The {{name}} attribute of the {{configuration}} element will be used as the ManagedService PID for the configuration set in the Configuration Admin service.  When using a ManagedServiceFactory, the {{name}} attribute is _servicePid_-_aliasId_, where _servicePid_ is the PID of the ManagedServiceFactory and _aliasId_ is a label used to uniquely identify a particular service (an alias to the factory generated service PID).

Deploying such a configuration has the same effect as dropping a file named {{com.foo.bar.cfg}} into the {{etc}} folder.

The content of the {{configuration}} element is set of properties parsed using the [standard java property mechanism|http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html#load(java.io.InputStream)].

Such configuration as usually used with Spring-DM or Blueprint support for the Configuration Admin service, as in the following example, but using plain OSGi APIs will of course work the same way:

{code:lang=xml}
<bean ...>
    <property name="propertyName" value="${myProperty}" />
</bean>

<osgix:cm-properties id="cmProps" persistent-id="com.foo.bar">
    <prop key="myProperty">myValue</prop>
</osgix:cm-properties>
<ctx:property-placeholder properties-ref="cmProps" />
{code}

There may also be cases where you want to make the properties from multiple configuration files available to your bundle context. This is something you may
want to do if you have a multi-bundle application where there are application properties used by multiple bundles, and each bundle has its own specific
properties. In that case, {{<ctx:property-placeholder>}} won't work as it was designed to make only one configuration file available to a bundle context.
 To make more than one configuration file available to your bundle-context you would do something like this:

{code:lang=xml}
<beans:bean id="myBundleConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfig">
    <beans:property name="ignoreUnresolvablePlaceholders" value="true"/>
    <beans:property name="propertiesArray">
        <osgix:cm-properties id="myAppProps" persistent-id="myApp.props"/>
        <osgix:cm-properties id="myBundleProps" persistent-id="my.bundle.props"/>
    </beans:property>
</beans:bean>
{code}

In this example, we are using SpringDM with osgi as the primary namespace. Instead of using ctx:context-placeholder we are using the "PropertyPlaceholderConfig"
class. Then we are passing in a beans array and inside of that array is where we set our osgix:cm-properties elements. This element "returns" a properties bean.

For more information about using the Configuration Admin service in Spring-DM, see the [Spring-DM documentation|http://static.springframework.org/osgi/docs/1.2.0-m2/reference/html/compendium.html#compendium:cm:props].

h3. Configuration files

In certain cases it is needed not only to provide configurations for the configuration admin service but to add additional
configuration files e.g. a configuration file for jetty (jetty.xml). It even might be helpful to deploy a configuration
file instead of a configuration for the config admin service since. To achieve this the attribute {{finalname}} shows the
final destination of the {{configfile}}, while the value references the Maven artifact to deploy.

{code}
<configfile finalname="/etc/jetty.xml">mvn:org.apache.karaf/apache-karaf/${project.version}/xml/jettyconfig</configfile>
{code}


h3. Feature resolver

The resolver attribute on a feature can be set to force the use of a given resolver instead of the default resolution process.  A resolver will be use to obtain the list of bundles to actually install for a given feature.
The default resolver will simply return the list of bundles provided in the feature description.
The OBR resolver can be installed and used instead of the standard one.  In that case, the resolver will use the OBR service
to determine the list of bundles to install (bundles flagged as dependency will only be used as possible candidates to solve
various constraints).

h2. Commands

h3. Repository management

The following commands can be used to manage the list of descriptors known by Karaf.  They use URLs pointing to features descriptors.  These URLs can use any protocol known to the Apache Karaf, the most common ones being http, file and mvn.

{code}
features:addUrl      Add a list of repository URLs to the features service
features:removeUrl   Remove a list of repository URLs from the features service
features:listUrl     Display the repository URLs currently associated with the features service.
features:refreshUrl  Reload the repositories to obtain a fresh list of features
{code}

Karaf maintains a persistent list of these repositories so that if you add one URL and restart Karaf, the features will still be available.

The {{refreshUrl}} command is mostly used when developing features descriptors: when changing the descriptor, it can be
handy to reload it in the Kernel without having to restart it or to remove then add the URL again.

h3. Features management

{code}
features:install
features:uninstall
features:list
{code}

h3. Examples

1. Install features using mvn handler
{code}
features:addUrl mvn:org.apache.servicemix.nmr/apache-servicemix-nmr/1.0.0-m2/xml/features
features:install nmr
{code}

2. Use file handler to deploy features file
{code}
features:addUrl file:base/features/features.xml
{code}

Note: The path is relative to the Apache Karaf installation directory

3. Deploy bundles from file system without using Maven

As we can use file:// as protocol handler to deploy bundles, you can use the following syntax to deploy bundles when they are 
located in a directory which is not available using Maven

{code:xml}
<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
   <feature name="spring-web" version="2.5.6.SEC01">
      <bundle>file:base/bundles/spring-web-2.5.6.SEC01.jar</bundle>
   </feature>
</features>
{code}

Note: The path is relative to the Apache Karaf installation directory

h2. Service configuration

A simple configuration file located in {{\[FELIX:karaf\]/etc/org.apache.karaf.features.cfg}} can be modified to customize the behavior when starting the Kernel for the first time.
This configuration file contains two properties:
* {{featuresBoot}}: a comma separated list of features to install at startup
* {{featuresRepositories}}: a comma separated list of feature repositories to load at startup

This configuration file is of interest if you plan to distribute a customized Karaf distribution having pre-installed features.  Such a process is detailed in the [6.2. Building custom distributions] section.


