Open Service Gateway Initiative (OSGi) is a popular standard that begun in embedded systems, expanded to mobile platforms, and is now actively adopted in the Java world. OSGi characteristics such as modularity, service orientation, reuse, dynamic updates and component versioning allow it to overcome the factors that limit the scope of the Java platform. For its part, Java is working towards OSGi-style functionality by including JSRs like JSR 294, 291, and 277 the upcoming Java 7 release.
OSGi has already made waves in the software industry with many established products such as Spring dm server, Oracle (formerly known as BEA) WebLogic, IBM WebShere, JBoss, and Eclipse IDE adopting the OSGi architecture for its modularity and flexibility. Even now, efforts are under way to develop distributed OSGi solutions (at the Apache CXF Distributed OSGi subproject, for example), which will enable efficient communication between multiple OSGi containers.
In this article, we provide a brief overview of OSGi and its advantages before presenting a demo use case where a few of the OSGi features would enable improved applications, especially in terms of modularity and reusability. The use case involves developing a thick client, and we will explain how OSGi and the Eclipse plug-in framework are a perfect option for developers to build modular and reusable components.
An OSGi Overview
The core of the OSGi specification is a framework that defines:
- An application lifecycle management model
- A service registry
- An execution environment
- An atomic part of the application that is composed of modules or components
These definitions standardize how you define modules or components and how you manage the lifecycle of these components.
The non-proprietary OSGi platform spans:
- Mobile phones
- Embedded systems
- Desktop software
- High-end servers
The beauty of the OSGi runtime is that you can install, update, or remove components on the fly—without interrupting existing operations. This feature makes OSGi ideal for domains where component/module provisioning must occur without interruptions to the existing operations (e.g., grid and cloud computing).
Largely because it allows multiple components to interact efficiently and securely in a Java Virtual Machine (JVM), OSGi claims the title: “The Dynamic Module System for Java.” With its rich security model, OSGi allows each component to run in its own secured environment. However, by setting the proper permissions, you can enable OSGi components to reuse other components, a capability that differentiates OSGi from other containers. This is what makes the OSGi framework lightweight and reusable.
OSGi also can expose Plain Old Java Object (POJO) services at each component level, a service-oriented way for components to communicate with each other. While binding occurs at the interface level, this feature will not bind components at the implementation level. So, at any time a service provider can change the implementation without changing and interrupting the service consumer. Designers utilize this SOA aspect of the OSGi framework to build loosely coupled applications. In fact, OSGi brings SOA to core Java-based applications without complexity.
OSGi in the Real World (Hypothetically): A Case Study
The demo application is a user login component centered on implementing user authentication for access to back-end resources. This example will allow us to explore reusability and size reduction of individual bundles, as well as how features such as OSGi services and Eclipse plug-in extension points like Splash Handler and preference pages fit perfectly for the application’s requirements.
Here are the use case details:
- Tim, an architect for StarTrek Company, leads a software team who need to build a Java-based, thick-client application.
- The application must provide users with a rich user interface (UI) and experience.
- The application must interact with many back-end applications, some of which expose web services, some are database storage, and others could be socket servers.
- These back-end applications are intranet based and located inside the company’s network. They give access only to valid StarTrek Company users.
- For security purposes, before allowing users to access the back-end applications, a login component will verify their credentials against the company’s LDAP or database.
So, this StarTrek project calls for Tim’s team to validate against LDAP and ensure that henceforth intranet-based applications are integrated using NTLM authentication, in the same way that all the database- and socket-based systems are authenticated using the same LDAP system.
First, Tim evaluated the available technologies for building the thick-client application. He finally chose the Eclipse Equinox implementation of OSGi because of this open source framework’s maturity and features. He also liked the active support from the open source community. The other open source OSGi implementations, Apache Felix and knopflerfish, weren’t as popular as Equinox largely because the Eclipse IDE itself uses the Equinox container.
The Design of the User Login Solution
The architecture for the user login solution is composed of two layers, Layer1 and Layer2 (see Figure 1). Each layer contains a bundle/component. One bundle comprises the UI part (UserLoginUI) and the other provides the required services (UserLoginServices) for the solution.
Figure 1. Architecture for User Login Solution: The architecture for the user login solution is composed of two layers.
Services are consumed by the UI bundle and can be directly consumed by the client bundles as well. The service bundle accesses a security and user authentication system like LDAP, which is outside the OSGi container and abstracted from the service consumer. (The details of these bundles are explained in the next section.)
Before continuing with the User Login solution, it is worth discussing how you can use OSGi technology for SOA-based architecture and design. SOA requires many features, including packaged services, loose coupling, and flexibility. OSGi provides all these and many others with less complexity than other SOA technologies. In fact, OSGi provides SOA features in a bundle composed of only a JAR file, which is deployed in an OSGi container.
So with OSGi, you don’t need a separate container specification for SOA-based applications the way you do with SOAP. OSGi’s versioning services, which update services dynamically using the OSGi packaging model, also give you flexibility.
Now, returning to the User Login solution, the diagram in Figure 2 shows a component-based design for the application.
Figure 2. Component-Based Design: Here is a component-based design for the User Login application.
The Bundles of the User Login Solution
This section details the bundles Tim’s team will use for their login solution: UserLoginServices and UserLoginUI.
The UserLoginServices bundle is a non-UI bundle of the OSGi container that acts as a service provider bundle/component for this reusable solution. Tim decided to make this bundle a separate component from the UserAdminUI bundle for two reasons:
- To reduce the size of the UserAdminUI bundle – because the responsibility of this bundle is to provide user login features to other bundles and abstract the validation part
- To factor out services in a separate bundle from the UI bundle – this makes the bundle a reusable component for other bundles, as well as providing an SOA flavor to this solution (which is required for validation and caching)
These are the services listed in the UserLoginServices bundle:
- IValidateService: This service validates the user credentials (username and password) with a user management system such as LDAP.
- IContextDataService: This user cache service caches the user credentials in JVM memory. Single sign-on solutions work by using this service in conjunction with IValidateService. After validation, the client layer should call this service to persist the user credential for that particular session.
Because the client API of IValidateService is coupled only with the interface, Tim is free to modify the implementation of the authentication algorithm any time during the software development lifecycle (SDLC) without affecting the client code or even interrupting the running client code.
As for IContextDataService, Tim has designed it to expose two operations:
- Saving the user credential in local cache
- Getting the user credential from local cache
Tim’s use of cache service for user management is similar to user management using the HttpSession web application. In a web application, whenever a valid user logs in, the system normally maintains the user’s credentials in an HttpSession object that is available across application layers and across requests for that application. In the same way, Tim’s User Login solution will save user credentials for a valid user (authenticated by IValidatedService) using IContextDataService in the local cache, which can be used by all the bundles in that Eclipse instance. The scope of this ContextData (that is userCredential) after storing in IContextDataService will become global to all the client bundles who have imported and used CommonUserServices bundles.
The UserLoginUI bundle provides the UI classes to cater the user login requirements for three different use cases. It also delegates validation and caching requests to the UserLoginService bundle.
These are the main UI abstractions for Tim’s User Login solution:
- Login Screen: When the user starts the client application or launches his/her Eclipse IDE, this bundle pops up a login screen to input the login credentials. The user can set credentials or resume without providing data. The Splash Handler Eclipse plug-in extension point is required for this.
- Preference Page: The user can change credentials after he or she has logged in using the splash screen property or enter them anew if the user has not done so previously.
- Login Popup screen: If the user has not provided credentials, credentials will be required when the user tries to connect to network resources. For this scenario, the UI bundle has a class that helps in popping up a screen like the splash login screen to take username and password input from the user.
These are the Eclipse plug-in extension points that Tim uses in the UserLoginUI bundle in more detail:
- Splash Handler: Splash is a concept that you use for the startup of an application. This startup work could be a login, a progress bar for the bootstrapping process, and so on. Eclipse provides Splash Handler as a way to manage the custom behavior of the splash screens that appear at the startup of the Eclipse IDE.
- Preference Page: Eclipse Workbench has a general preference page that you use for preference settings. Using the Preference Page extension point allows you to manage this preferences dialog.
Ready to Build
With these components in place within the previously discussed architecture, Tim’s team is ready to develop their User Login solution based on the Eclipse Equinox implementation of OSGi and validation against the StarTrek’s LDAP or databases.
In an upcoming follow-up to this article, we will walk through the steps for developing such a login solution for OSGi.