Use case: Deploying more than one modular application into the same framework

In OSGi the best practice is to split an application into several bundles that each cover a different business aspect of the application. So imagine an application for a service layer of a web shop with bundles for :

  • browsing articles
  • cart management
  • checkout
  • customer

Each of the above bundles would like to offer and consume 0..n cxf services. Still there would be common aspects. All of the services require basic auth with user / password from an ldap server, the requests / replies should be logged to a database.

So it would make sense to define the common aspects only once (either on servlet or cxf bus level).

At the same time we might have a second application that also provides some bundles but that has different common rules.

So we need a way to group the bundles together to one application so the common rules can be applied while distinguishing between the different applications.

This use case does not map well to the way cxf can be configured in OSGi.

Current solutions for the servlet transport in OSGi

In OSGi there are two ways to use the CXF servlet transport.

Using the default CXF servlet

This works by simply using an address like "/mypath". The endpoint will then be on /cxf/mypath. In this approach is that there is only one servlet for the OSGi framework. All endpoints defined in all bundles will only use this servlet. So does not work well if you have two applications that would like to configure the servlet with specially e.g in regard to security.

Using a web application bundle

Inside the web application bundle you can define a CXF servlet. The servlet endpoints defined in this bundle will then be available on the servlet. So this allows to define more than one servlet per OSGi framework. The CXFBlueprintServlet allows to connect the servlet to a blueprint context that defines the endpoints. The problem here is that it does not covert the case where several bundles of the application would like to define CXF endpoints.

Current solution for sharing rules

CXF will pick up all features that are exposed as an OSGi service. So this allows to define common rules but the rules apply to all bundles in the framework.

Idea: Define the CXF bus once per application as OSGi service

Currently the cxf bus in OSGi is defined per bundle. So if each bundle has one blueprint context then cxf will automatically create one bus per bundle.

So the idea is to define the cxf bus in one bundle and export it as an OSGi service with the name of the application as identifier. This already works by simply defining a <cxf:bus id="myapplication"/>. The bus is also automatically exposed as an OSGi service by cxf.

Each of the other bundles of the application could then refer to this bus and add its endpoints to it.I am not sure how this would work with the OSGi ifecycle where bundles can be added and removed at any time though.

The advantage would be that in the bundle defining the bus all the common rules could be applied. So the other bundles do not have to repeat that step.

Alternatively name the servlet in the endpoint

If we give each servlet a name then we could refer to this name in the endpoint. So the user could choose, which servlet to wire to. In the endpoint we could e.g. use the following uri syntax: servlet:servletname/path. The endpoint would then be published to the DestinationRegistry with the given name.

TODO: How to store the DestinationRegistries in non OSGi environments.