//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

=== OBR

The goal of OBR (OSGi Bundle Repository) is:

. to simplify deploying and using bundles
. to encourage independent bundle development.

OBR achieves the first goal by providing a service that can automatically install a bundle, with its deployment dependencies,
from a bundle repository. This makes it easier for people to experiment with existing bundles.

The second goal is achieved by raising the visibility of the available bundles in a repository.

OBR is an optional Apache Karaf feature. You have to install the `obr` feature to use OBR service:

----
karaf@root()> feature:install obr
----

The OBR feature turns Apache Karaf into an OBR client. It means that Apache Karaf can use a OBR repository for the installation
of the bundles, and during the installation of the features.

The installation of the `obr` feature adds in Apache Karaf:

* the OBR service
* the features OBR resolver
* the `obr:*` commands
* the JMX ObrMBean

The OBR repository contains all bundles. The OBR service knows all requirements and capabilities of each bundle on an
OBR repository (it's the OBR metadata).

Thanks to that, when you install ("deploy" in OBR wording) a bundle using the OBR service, it looks for all bundles
providing the capabilities matching the bundle requirements.
It will automatically install the bundles needed for the bundle.

==== Features OBR resolver

If the feature specifies `obr` in the `resolver` attribute, Apache Karaf can use the OBR service to construct the list
of bundles to install with the features.

The feature default resolver just consider the bundles described in the feature itself.

Using the OBR resolver, Apache Karaf can extend the bundle list at the feature installation time using the OBR service.

==== Commands

===== `obr:url-add`

The `obr:url-add` command registers the OBR repository at a given URL in the OBR service.

Basically, an OBR repository is described by a `repository.xml` file.

The `obr:url-add` command expects an `url` argument. The `url` argument is the URL to the OBR repository `repository.xml` file.
Any URL described in the [Artifacts repositories and URLs section|urls] is supported.

For instance:

----
karaf@root()> obr:url-add file:///user/.m2/repository/repository.xml
----

===== `obr:url-list`

The `obr:url-list` command lists the OBR repository (with URL) registered in the OBR service:

----
karaf@root()> obr:url-list
Index | OBR URL
---------------------------------------------------------
0     | file:/user/.m2/repository/repository.xml
----

===== `obr:url-refresh`

The `obr:url-refresh` command refreshes an OBR repository (reloading the URL).

The OBR service doesn't take "on the fly" the changes performed on an OBR repository `repository.xml`. You have to
reload the `repository.xml` URL to take the changes. It's the purpose of the `obr:url-refresh` command.

Without argument, the `obr:url-refresh` command refreshes all repositories:

----
karaf@root()> obr:url-refresh
----

You can refresh only one repository by specifying the URL as argument:

----
karaf@root()> obr:url-refresh file:/user/.m2/repository/repository.xml
----

Instead of using the URL, you can use the repository index as displayed by the `obr:url-list` command.
To do so, you have to use the `-i` option:

----
karaf@root()> obr:url-refresh -i 0
----

===== `obr:url-remove`

The `obr:url-remove` command removes an OBR repository from the OBR service.

The `obr:url-remove` command expects the repository URL as argument:

----
karaf@root()> obr:url-remove file:/user/.m2/repository/repository.xml
----

Instead of using the URL, you can use the repository index as displayed by the `obr:url-list` command.
To do so, you have to use the `-i` option:

----
karaf@root()> obr:url-remove -i 0
----

===== `obr:list`

The `obr:list` command lists all bundles available on the registered OBR repositories:

----
karaf@root()> obr:list|more
Name                                                                         | Symbolic Name                                                             | Version
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
activemq-blueprint                                                           | org.apache.activemq.activemq-blueprint                                    | 5.12.0.SNAPSHOT
activemq-camel                                                               | org.apache.activemq.activemq-camel                                        | 5.12.0.SNAPSHOT
activemq-karaf                                                               | activemq-karaf                                                            | 5.12.0.SNAPSHOT
activemq-osgi                                                                | org.apache.activemq.activemq-osgi                                         | 5.12.0.SNAPSHOT
Apache Aries Application API                                                 | org.apache.aries.application.api                                          | 1.0.1.SNAPSHOT
...
----

===== `obr:info`

The `obr:info` command displays the details about bundles available on the OBR service. Especially, it provides details about
capabilities and requirements of bundles.

The `obr:info` command expects a bundle symbolic name as argument:

----
karaf@root()> obr:info org.apache.karaf.wrapper.core
-------------------------------
Apache Karaf :: Wrapper :: Core
-------------------------------
id: org.apache.karaf.wrapper.core/4.0.0
description: Core implementation and integration of the Java Service Wrapper.        It provides a complete integration of Karaf with your Operating System.
documentation: http://www.apache.org/
symbolicname: org.apache.karaf.wrapper.core
presentationname: Apache Karaf :: Wrapper :: Core
license: http://www.apache.org/licenses/LICENSE-2.0.txt
uri: file:/user/.m2/repository/org/apache/karaf/wrapper/org.apache.karaf.wrapper.core/4.0.0/org.apache.karaf.wrapper.core-4.0.0.jar
size: 1281352
version: 4.0.0
Requires:
   service:(&(service=org.apache.aries.blueprint.NamespaceHandler)(osgi.service.blueprint.namespace=http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0))
   package:(&(package=javax.management))
   package:(&(package=org.apache.karaf.wrapper))
   package:(&(package=org.apache.karaf.wrapper.management))
   package:(&(package=org.fusesource.jansi)(version>=1.11.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.framework)(version>=1.7.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.framework.launch)(version>=1.1.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.framework.startlevel)(version>=1.0.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.service.blueprint)(version>=1.0.0)(!(version>=2.0.0)))
   package:(&(package=org.slf4j)(version>=1.7.0)(!(version>=2.0.0)))
Capabilities:
   bundle:{manifestversion=2, symbolicname=org.apache.karaf.wrapper.core, presentationname=Apache Karaf :: Wrapper :: Core, version=4.0.0}
   service:{service=org.apache.karaf.wrapper.WrapperService}
   package:{package=org.apache.karaf.wrapper, version=4.0.0}
   package:{package=org.apache.karaf.wrapper.management, uses:=javax.management, version=4.0.0}
----

The `obr:info` command uses the following syntax to identify the bundles: `symbolic_name,version` where `version` is optional.
It means that you have to use the following command to see the info about the wrapper core bundle with version 4.0.0:

----
karaf@root()> obr:info org.apache.karaf.wrapper.core,4.0.0
...
----

You can specific multiple bundles separated by space:

----
karaf@root()> obr:info org.apache.karaf.wrapper.core,4.0.0 org.apache.karaf.wrapper.command,4.0.0
...
----

===== `obr:source`

In addition of the bundles executable, the OBR service can also store the bundles sources.

The `obr:source` command check the source URL in the OBR metadata for a given bundle, and download the sources on a target folder:

----
karaf@root()> obr:source /tmp org.apache.karaf.wrapper.core
----

The `obr:source` command uses the following syntax to identify the bundles: `symbolic_name,version` where `version` is optional.
It means that you have to use the following command to download the source of wrapper core bundle with version 4.0.0:

----
karaf@root()> obr:source /tmp org.apache.karaf.wrapper.core,4.0.0
----

You can specify multiple bundles separated by space:

----
karaf@root()> obr:source /tmp org.apache.karaf.wrapper.core,4.0.0 org.apache.karaf.wrapper.command,4.0.0
...
----

===== `obr:resolve`

The `obr:resolve` command displays the resolution output for a given set of requirements. Actually, it show the bundles providing
the capabilities to match the requirements. It's what the OBR service does when executing `obr:deploy`.

Optionally, the `obr:resolve` command can deploy the bundles as the `obr:deploy` command does.

For instance, to know the OBR bundle resolving the `org.apache.karaf.wrapper` package requirement, you can do:

----
karaf@root()> obr:resolve package=org.apache.karaf.wrapper
Required resource(s):
---------------------
   Apache Karaf :: Wrapper :: Core (4.0.0)
----

===== `obr:find`

The `obr:find` command is similar to the `obr:resolve` one. It displays the bundles resolving the provided requirements, with details.

For instance, to find the OBR bundle providing the `org.apache.karaf.wrapper` package, you can do:

----
karaf@root()> obr:find package=org.apache.karaf.wrapper
-------------------------------
Apache Karaf :: Wrapper :: Core
-------------------------------
id: org.apache.karaf.wrapper.core/4.0.0
description: Core implementation and integration of the Java Service Wrapper.        It provides a complete integration of Karaf with your Operating System.
documentation: http://www.apache.org/
symbolicname: org.apache.karaf.wrapper.core
presentationname: Apache Karaf :: Wrapper :: Core
license: http://www.apache.org/licenses/LICENSE-2.0.txt
uri: file:/user/.m2/repository/org/apache/karaf/wrapper/org.apache.karaf.wrapper.core/4.0.0/org.apache.karaf.wrapper.core-4.0.0.jar
size: 1281352
version: 4.0.0
Requirements:
   service:(&(service=org.apache.aries.blueprint.NamespaceHandler)(osgi.service.blueprint.namespace=http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0))
   package:(&(package=javax.management))
   package:(&(package=org.apache.karaf.wrapper))
   package:(&(package=org.apache.karaf.wrapper.management))
   package:(&(package=org.fusesource.jansi)(version>=1.11.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.framework)(version>=1.7.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.framework.launch)(version>=1.1.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.framework.startlevel)(version>=1.0.0)(!(version>=2.0.0)))
   package:(&(package=org.osgi.service.blueprint)(version>=1.0.0)(!(version>=2.0.0)))
   package:(&(package=org.slf4j)(version>=1.7.0)(!(version>=2.0.0)))
Capabilities:
   bundle:{manifestversion=2, symbolicname=org.apache.karaf.wrapper.core, presentationname=Apache Karaf :: Wrapper :: Core, version=4.0.0}
   service:{service=org.apache.karaf.wrapper.WrapperService}
   package:{package=org.apache.karaf.wrapper, version=4.0.0}
   package:{package=org.apache.karaf.wrapper.management, uses:=javax.management, version=4.0.0}
----

===== `obr:deploy`

The `obr:deploy` command installs a bundle from the OBR repository, including all bundles required to satisfy the bundle requirements.

----
karaf@root()> obr:deploy org.ops4j.pax.web.samples.helloworld-hs
Target resource(s):
-------------------
   OPS4J Pax Web - Samples - Hello World - HttpService (4.0.0.SNAPSHOT)

Required resource(s):
---------------------
   Apache ServiceMix :: Specs :: Activation API 1.4 (2.3.0.SNAPSHOT)
   OPS4J Pax Web - Jetty Bundle (4.0.0.SNAPSHOT)

Deploying...done.
----

By default, the bundles are just installed, not started. You can use the `-s` option to start the bundles.

The `obr:deploy` command uses the following syntax to identify the bundles: `symbolic_name,version` where `version` is optional.
It means that you have to use the following command to deploy the wrapper core bundle with version 4.0.0:

----
karaf@root()> obr:deploy org.apache.karaf.wrapper.core,4.0.0
----

You can specify multiple bundles separated by space:

----
karaf@root()> obr:deploy org.apache.karaf.wrapper.core,4.0.0 org.apache.karaf.wrapper.command,4.0.0
...
----

==== `obr:start`

The `obr:start` command does the same as `obr:deploy -s` command. It installs the bundle (and all required bundles to
satisfy the requirements) and starts all installed bundles.

----
karaf@root()> obr:start org.ops4j.pax.web.samples.helloworld-hs
Target resource(s):
-------------------
   OPS4J Pax Web - Samples - Hello World - HttpService (4.0.0.SNAPSHOT)

Required resource(s):
---------------------
   Apache ServiceMix :: Specs :: Activation API 1.4 (2.3.0.SNAPSHOT)
   OPS4J Pax Web - Jetty Bundle (4.0.0.SNAPSHOT)

Deploying...done.
----

The `obr:start` command uses the following syntax to identify the bundles: `symbolic_name,version` where `version` is optional.
It means that you have to use the following command to deploy and start the wrapper core bundle with version 4.0.0:

----
karaf@root()> obr:start org.apache.karaf.wrapper.core,4.0.0
----

You can specify multiple bundles separated by space:

----
karaf@root()> obr:start org.apache.karaf.wrapper.core,4.0.0 org.apache.karaf.wrapper.command,4.0.0
...
----

==== JMX ObrMBean

On the JMX layer, Apache Karaf provides a MBean dedicated to the management of the OBR service: the ObrMBean.

The ObjectName to use is `org.apache.karaf:type=obr,name=*`.

===== Attributes

The `Urls` attribute provides the list of registered OBR repositories URLs.

The `Bundles` attribute provides a tabular data containing all bundles available on the registered OBR repositories.

===== Operations

* `addUrl(url)` registers the OBR repository using the `url` to the `repository.xml`.
* `removeUrl(url)` removes the OBR repository at the given `url`.
* `refreshUrl(url)` refreshes the OBR repository at the given `url`.
* `deployBundle(name)` deploys a bundle (and all bundles required to satisfy the requirements) using the OBR service. The bundles are not automatically started.
* `deployBundle(name, start, deployOptional)` deploys a bundle (and all bundles required to satisfy the requirements) using the OBR service.
 If `start` is `true`, the bundles are automatically started. If `deployOptional` is `true`, even the optional requirements will be resolved
 by the OBR service (meaning installing more bundles to satisfy the optional requirements).

The name to identify a bundle uses the following syntax: `symbolic_name,version` where version is optional.

==== Apache Karaf Cave

In addition of being an OBR client, Apache Karaf can act as an OBR repositories server, thanks to Apache Karaf Cave.

See the https://karaf.apache.org/projects.html for details.
