Saturday, March 22, 2014

OSGi Overview

What is OSGi?

OSGi (formerly Open Services Gateway initiative) refers to a Java based services platform that allows for remote management of a system, as well as adding life cycle management of internal components (bundles), allowing the dynamic install, delete, and updating of these components with minimal impact to the system. OSGi allows for the quick release and incorporation or interconnected components into an active system, and have them interact with no interruption to the active system.

The prime use of the technology seems geared at the ability to quickly replace bundles in an active system.

The OSGi alliance specification like EJB and servlet specification, defines two things.

1. A set of services an OSGi container must implement

2. A contract between the container and the application

 There are number of open source OSGi container implementations such as

Example

Imagine a risk calculation system that is attempting to handle all risk calculations for a bank. The system is designed with modularity in mind, and to be active 24/7. We implement a central node to handle risk calculation requests, and each instrument's calculation component is a separate module.
OSGi would facilitate this by implementing the central component and its many hooks as a bundle, followed by the implementation of each of the individual instrument risk calculators as services that implement a risk calculation interface. This would allow for these services to be added to the running system as they become available, register with the Service Registry, and thus allow the central node to find them as it receives requests to calculate those instruments. The version that is contained in the bundles allows OSGi to track which is the latest bundle, stop the current one and replace it with this later version.
Furthermore by having the calculation libraries as their own bundle it would allow for a quick update of those internal libraries without impacting the rest of the system.
OSGi allows the central node to request a particular risk calculator given a known string query and parameters, and OSGi would handle the returning of the appropriate calculator, or NULL if there is non available. It would allow for the rapid delivery of such a system, and its pre-defined modularity. It would also allow for updates of new code to be quickly accomplished. It also forces components of the system to be able to handle the case of a portion of the system being unavailable.

OSGi technology is the dynamic module system for Java.  Java provides the portability that is required to support products on many different platforms. The OSGi technology provides the standardized primitives that allow applications to be constructed from small, reusable and collaborative components. These components can be composed into an application and deployed.
The OSGi Service Platform provides the functions to change the composition dynamically on the device of a variety of networks, without requiring restarts. To minimize the coupling, as well as make these couplings managed, the OSGi technology provides a service-oriented architecture that enables these components to dynamically discover each other for collaboration. The OSGi Alliance has developed many standard component interfaces for common functions like HTTP servers, configuration, logging, security, user administration, XML and many more. Plug-compatible implementations of these components can be obtained from different vendors with different optimizations and costs. However, service interfaces can also be developed on a proprietary basis.
Apache Karaf is a small OSGi-based runtime which provides a lightweight container onto which various components and applications can be deployed.
Features:
1.    Hot deployment: Karaf supports hot deployment of OSGi bundles by monitoring jar files inside the $home/deploy directory. 
2.    Dynamic configuration: Services are usually configured through the ConfigurationAdmin OSGi service. Such configuration can be defined in Karaf using property files inside the $home/etc directory. These configurations are monitored and changes on the properties files will be propagated to the services.
3.    Logging System: using a centralized logging back end supported by Log4J
4.    Provisioning: Provisioning of libraries or applications can be done through a number of different ways, by which they will be downloaded locally, installed and started.
5.    Native OS integration: Karaf can be integrated into your own Operating System as a service
6.    Extensible Shell console: Karaf features a nice text console where you can manage the services, install new applications or libraries and manage their state. This shell is easily extensible by deploying new commands dynamically along with new features or applications.
7.    Remote access: use any SSH client to connect to Karaf and issue commands in the console
8.    Security framework based on JAAS

9.    Managing instances: Karaf provides simple commands for managing multiple instances. You can easily create, delete, start and stop instances of Karaf through the console.

Architecture

Frameworks that implement the OSGi standard provide an enviorment for the modularization of applications into small bundles. These bundles refer to tightly-coupled, dynamically loadable collections of classes, jars, and configurations. In other words, the OSGi standard looks to reduce applications into smaller components known as bundles. The primary requirement of these bundles is that they are entirely self-contained, so that they can be swapped in and out of the application as is necessary.


  • Bundles - Bundles are the OSGi components made by the developers.
  • Services - The services layer connects bundles in a dynamic way by offering a publish-find-bind model for plain old Java objects.
  • Life-Cycle - The API to install, start, stop, update, and uninstall bundles.
  • Modules - The layer that defines how a bundle can import and export code.
  • Security - The layer that handles the security aspects.
  • Execution Environment - Defines what methods and classes are available in a specific platform.

In Java terms, a bundle is a plain old JAR file. However, where in standard Java everything in a JAR is completely visible to all other JARs, OSGi hides everything in that JAR unless explicitly exported. A bundle that wants to use another JAR must explicitly import the parts it needs. By default, there is no sharing.

Though the code hiding and explicit sharing provides many benefits (for example, allowing multiple versions of the same library being used in a single VM), the code sharing was only there to support OSGi services model. The services model is about bundles that collaborate.

Bundles are deployed on an OSGi framework, the bundle runtime environment. This is not a container like Java Application Servers. It is a collaborative environment. Bundles run in the same VM and can actually share code. The framework uses the explicit imports and exports to wire up the bundles so they do not have to concern themselves with class loading. Another contrast with the application servers is that the management of the framework is standardized. A simple API allows bundles to install, start, stop, and update other bundles, as well as enumerating the bundles and their service usage. This API has been used by manymanagement agents to control OSGi frameworks. 

Normalized Message Router

The Normalized Message Router (NMR) is a general-purpose message bus used for communication between bundles in the OSGi container.
It's modeled after the Normalized Message Router (NMR) defined in the Java Business Integration (JBI) specification.

Role of OSGi in a SOA Runtime

1.       Pluggability – extend runtime with additional functionality – adding services, containers etc.
2.       Isolation – control packages exposed and consumed
3.       Dynamism – bundles have lifecycle independent of VM
4.       Dependency Management – dependency between services

Bundles can act as both simple libraries to be used and referred to by other bundles, or they can have an Activator, that will perform an action when it is started or stopped. Having an activator allows the creation of services, by registering objects into the Service Registry under a given interface. It also allows to define further parameters / properties to narrow down the case of collisions between service names.


//Simple activator
package osgi;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
    private BundleContext context;
    public void start(BundleContext context) throws Exception {
        log ("Starting: Hello World");
        this.context = context;
    }//end start
    public void stop(BundleContext context) throws Exception {
        log ("Stopping: Goodbye World");
        this.context = null;
    }//end stop
}


For more examples: http://www.knopflerfish.org/tutorials/osgi_tutorial.pdf 

Life Cycle

The life-cycle layer controls the activation and deactivation of bundles. It is responsible for starting, stopping, installing, and updating bundles, and making sure that other bundles that have dependencies are notified. This layer is also in charge of handling the class loading and the dependencies between bundles.

 Application life cycle management is implemented via APIs that allow for remote downloading of management policies. The service registry allows bundles to detect the addition of new services, or the removal of services, and adapt accordingly.

Security

The security layer is based on the standard Java 2 security model. It is a permission based model based by location and by signer. OSGi provides real time management of the security configuration of an application, and provides APIs for admin permission, and conditional admin permission. The way this works is as follows: An Operator grants Networking rights to Company X on their devices. Now every bundle that Company X signs and deploys can use Networking on the Operator's devices. Furthermore a specific bundle can be granted permission to handle the life-cycle of bundles deployed by Company X.


Modules

Modules define collections of bundles, and their interactions. Including how bundles import and export code. By default bundles do not share code, so in their manifests we need to define how they import / export different parts of the codebase to function. The module layer handles those interactions via the manifest files of each bundle.
Sample Manifest File
//Sample Manifest File
Bundle-Name: Hello World
Bundle-SymbolicName: com.rf.osgi
Bundle-Description: A Hello World bundle
Bundle-ManifestVersion: 2
Bundle-Version: 1.0.0
Bundle-Activator: com.rf.andres.osgi.Activator
Export-Package: com.rf.andres.osgi.helloworld;version="1.0.0"
Import-Package: org.osgi.framework;version="1.3.0"
Given that bundles define what exactly they export through their manifest, it is possible to restrict what classes inside a JAR are published for use by other bundles. Further, utilizing the Modules aspect of the architecture, it allows for multiple version of the JAR to coexist happily inside the system without wrecking total havoc.

Apache Karaf

Apache Karaf is a small OSGi based runtime which provides a lightweight container onto which various components and applications can be deployed.

Felix is just the OSGi core runtime. Karaf provides a "distribution" based on Felix by adding other features such as a console, an SSH remoting mechanism, a file deployer and more.
In this diagram of the Karaf architecture, Felix (or other OSGi implementation - currently Equinox is also supported) is the OSGi box, the other boxes are the features added by Karaf:
Karaf Architecture
Based on:
http://en.wikipedia.org/wiki/OSGi 

No comments:

Popular micro services patterns

Here are some popular Microservice design patterns that a programmer should know: Service Registry  pattern provides a  central location  fo...