3.4. Define a Feature for the Application

Why do you need a feature?

An OSGi bundle is not a convenient unit of deployment to use with the Red Hat JBoss Fuse container. Applications typically consist of multiple OSGi bundles and complex applications may consist of a very large number of bundles. Usually, you want to deploy or undeploy multiple OSGi bundles at the same time and you need a deployment mechanism that supports this.
Apache Karaf features are designed to address this problem. A feature is essentially a way of aggregating multiple OSGi bundles into a single unit of deployment. When defined as a feature, you can simultaneously deploy or undeploy a whole collection of bundles.

What to put in a feature

At a minimum, a feature should contain the basic collection of OSGi bundles that make up the core of your application. In addition, you might need to specify some of the dependencies of your application bundles, in case those bundles are not predeployed in the container.
Ultimately, the decision about what to include in your custom feature depends on what bundles and features are predeployed in your container. Using a standardised container like Red Hat JBoss Fuse makes it easier to decide what to include in your custom feature.

Deployment options

You have a few different options for deploying features, as follows:
  • Hot deploy—the simplest deployment option; just drop the XML features file straight into the hot deploy directory, InstallDir/deploy.
  • Add a repository URL—you can tell the Red Hat JBoss Fuse container where to find your features repository file using the features:addUrl console command (see Add the local repository URL to the features service). You can then install the feature at any time using the features:install console command.
  • Through a Fuse Fabric profile—you can use the management console to deploy a feature inside a Fuse Fabric profile.
For more details about the feature deployment options, see Deploying Into Apache Karaf, Deploying Features.

Features and Fuse Fabric

It turns out that a feature is a particularly convenient unit of deployment to use with Fuse Fabric. A Fuse Fabric profile typically consists of a list of features and a collection of related configuration settings. Hence, a Fuse Fabric profile makes it possible to deploy a completely configured application to any container in a single atomic operation.

Create a custom features repository

Create a sub-directory to hold the features repository. Under the get-started project directory, create all of the directories in the following path:
features/src/main/resources/
Under the get-started/features/src/main/resources directory, use a text editor to create the get-started.xml file and add the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<features name="get-started">
  <feature name="get-started-basic">
    <bundle>mvn:org.fusesource.example/cxf-basic/1.0-SNAPSHOT</bundle>
    <bundle>mvn:org.fusesource.example/camel-basic/1.0-SNAPSHOT</bundle>
  </feature>
  <feature name="get-started-cxf">
    <bundle>mvn:org.fusesource.example/cxf-basic/1.0-SNAPSHOT</bundle>
  </feature>
</features>
Under the get-started/features/ directory, use a text editor to create the Maven POM file, pom.xml, and add the following contents to it:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://maven.apache.org/POM/4.0.0
        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>org.fusesource.example</groupId> 
    <artifactId>get-started</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    
    <name>Getting Started Feature Repository</name>

    <build>
      <plugins>
      <!-- Attach the generated features file as an artifact,
           and publish to the maven repository -->
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>build-helper-maven-plugin</artifactId>
          <version>1.5</version>
          <executions>
            <execution>
              <id>attach-artifacts</id>
              <phase>package</phase>
              <goals>
                <goal>attach-artifact</goal>
              </goals>
              <configuration>
                <artifacts>
                  <artifact>
                    <file>target/classes/get-started.xml</file>
                    <type>xml</type>
                    <classifier>features</classifier>
                  </artifact>
                </artifacts>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>

</project>

Install the features repository

You need to install the features repository into your local Maven repository, so that it can be located by the Red Hat JBoss Fuse container. To install the features repository, open a command prompt, change directory to get-started/features, and enter the following command:
cd features
mvn install

Deploy the custom feature

To deploy the get-started-basic feature into the container, perform the following steps:
  1. If the cxf-basic and camel-basic bundles are already installed in the JBoss Fuse container, you must first uninstall them. At the console prompt, use the list command to discover the bundle IDs for the cxf-basic and camel-basic bundles, and then uninstall them both using the console command, uninstall BundleID.
  2. Before you can access features from a features repository, you must tell the container where to find the features repository. Add the features repository URL to the container, by entering the following console command:
    JBossFuse:karaf@root> features:addurl mvn:org.fusesource.example/get-started/1.0-SNAPSHOT/xml/features
    You can check whether the container knows about the new features by entering the console command features:list. If necessary, you can use the features:refreshurl console command, which forces the container to re-read its features repositories.
  3. To install the get-started-basic feature, enter the following console command:
    JBossFuse:karaf@root> features:install get-started-basic
  4. After waiting a few seconds for the bundles to start up, you can test the application as described in the section called “Test the route with the WS client”.
  5. To uninstall the feature, enter the following console command:
    JBossFuse:karaf@root> features:uninstall get-started-basic