
= OSGi Integration

{page-component-title} uses the https://www.osgi.org/resources/what-is-osgi/[OSGi] framework in a https://karaf.apache.org/manual/latest/[Karaf] container.
This section explains how to integrate a Maven module (OSGi bundle) in your {page-component-title} instance.

== Add Maven module

New Maven modules are usually distributed in the form of a bundle (a JAR file and OSGi metadata).
After you create a Maven module, add this plugin to `pom.xml` to create the necessary metadata:

[source, xml]
----
    <packaging>bundle</packaging>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-RequiredExecutionEnvironment>JavaSE-1.8</Bundle-RequiredExecutionEnvironment>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>

                    <!-- <Export-Package>org.foo.myproject.api</Export-Package>--> <1>
                    <!-- <Import-Package>org.foo.myproject.api.dependencies</Import-Package>--> <2>
                    <!-- <Private-Package>org.foo.myproject.impl</Private-Package>--> <3>
                    <!-- <Karaf-Commands>*</Karaf-Commands>--> <4>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
----
<1> (Optional) Define packages that can be exported.
<2> (Optional) Define packages to import from dependent modules.
<3> (Optional) Define private packages that should not be exported.
<4> Include this only when the module is intended for adding Karaf commands.

== Add Karaf feature

A feature is a set of bundles that can be installed in Karaf.
For any given module, all of its dependencies must be specified in a feature.
Sometimes, there are runtime dependencies that will run only when you actually use the feature.

.Example feature definition
[source, xml]
----
   <feature name="scv-api" version="${project.version}" description="Secure Credentials Vault">
        <bundle>mvn:org.opennms.features.scv/org.opennms.features.scv.api/${project.version}</bundle>
    </feature>
    <feature name="scv-jceks-impl" version="${project.version}" description="Secure Credentials Vault JCEKS Impl">
        <feature>scv-api</feature>
        <bundle dependency="true">mvn:commons-codec/commons-codec/${commonsCodecVersion}</bundle>
        <bundle dependency="true">mvn:com.google.guava/guava/${guavaVersion}</bundle>
        <bundle>mvn:org.opennms.features.scv/org.opennms.features.scv.jceks-impl/${project.version}</bundle>
    </feature>
----

You can define features by editing the files located in `container/features/src/main/resources/`:

* `features.xml`: All features specific to {page-component-title} and those common to Minion and Sentinel.
* `features-minion.xml`: All features specific to Minion.
* `features-sentinel.xml`: All features specific to Sentinel.

To make a feature available in the Karaf container, add the feature and any appropriate dependencies to the following files:

* *{page-component-title}:* `opennms-full-assembly/pom.xml`
* *Minion:* `features/minion/repository/pom.xml` (feature and Maven dependencies)
* *Sentinel:* `features/sentinel/repository/pom.xml` (feature and Maven dependencies)

=== Install feature by default

To install a new feature by default, edit the following files:

* *{page-component-title}:* Add the feature in `container/karaf/src/main/filtered-resources/etc/org.apache.karaf.features.cfg`.
* *Minion:* Add the feature in `features/minion/repository/src/main/resources/features.boot`.
* *Sentinel:* Add the feature in `features/container/sentinel/src/main/filtered-resources/etc/org.apache.karaf.features.cfg`.

== Spring Maven modules

If a Maven module should be loaded in Spring by default, you must include it in `opennms-base-assembly/pom.xml`.
All of the modules that are loaded in Spring will be made available in `${opennms.target}/opennms/lib`.

Some modules are defined only in Spring (legacy RPC modules, such as `opennms-services`).
These are loaded in the default classloader.

You can add Spring beans to the OSGi service registry by exposing the beans as `<onmsgi:service>`.

=== Add package to custom.properties

Packages added to `custom.properties` are loaded in the default classloader, even when loaded in OSGi.
You must use `custom.properties` to export packages that are loaded in Spring, but are also accessed through OSGi.

== Health check

The health check command is available in all Karaf containers:

[source, shell]
opennms:health-check

It validates whether all features are enabled and running without issue in your {page-component-title} environment.
If you see any bundle-related failures, you can use `bundle:diag id` to retrieve more specific information.

== Dynamically reload module for debugging

You can use the `bundle:watch *` command to dynamically reload a module.
This lets you watch the module for behaviors that may be of interest during the debugging process.

You can also use `bundle:watch~` in the Karaf container to watch for any updates in the local m2 repository.

To update a specific module in your local Karaf repository, use `mvn clean install` in the appropriate directory.

== Disable Karaf SSH host key check

To disable the host key check function for SSH in your Karaf container, add the following code to `.ssh/config`:

[source, ]
----
Host localhost
    HostKeyAlgorithms +ssh-dss
    StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
----
