Tracking specific Bundles in OSGi - java

I'm new using OSGi, I have a doubt about tracking Bundles. I'm using BundleTracker because I want specific bundles, and I want to know which bundle I am using by their IDs. Some Bundles (3) implement the same interface. I want to track just those bundles that implement that interface. How can I do this?

If you want to select a specific service you can use service properties for that. This is completely agnostic of bundles. What that means is that you register your service-implementations with specific properties (this is what the Dictionary-argument in BundleContext.registerService is for).
Then you can use BundleContext.getServiceReferences and specify a filter-expression (the syntax is described here) that only selects the service with the correct property. You could set this up so that you always get an array or collection with at most one element.
This all becomes much easier if you use declarative services, because then you can just specify the property and the filter in the service-descriptor of the providing and consuming component respectively. You can also make one or both ends of it configurable via the configuration admin (properties in the configuration of a service-component are propagated as properties of the exposed services or consumed references). I would really suggest you check out declarative services before starting any serious work in OSGi.
Note that you should be careful to not implement a hard-coded wiring this way, because that would kill modularity.

Related

How to let a consumer select specific 3party provider

What could be a good osgi implementation of the scenario below ?
I have a general algorithm which is divided in multiple modules. The idea is that each module could be extended by third party with specific configuration needs. My main algorithm is configured by a user mainly to select which module to include. As this configuration file could be difficult to write, I want to create a workbench that help him to do that.
My first idea was to consider my main algorithm as a consumer of multiple module providers using DS. The use case is: the user configure the main algorithm and the submodules he want to use; then when he runs the algorithm I want that the workbench creates the main algorithm service with the good configuration. But if I understand, services in osgi are designed to be provider independent. Does services are useful in my case?
Doing what you want they way you just described will cause you much heartache and issues. Instead I'd suggest you use a more hands-on approach:
Define interfaces in your bundles that define the ways that your algorithm can be extended
Use the service layer of OSGi to collect the implementations of the interfaces (DS can help you here)
Have a configuration class/object that defines which of the above are selected/activated for a specific instance
When you algorithm is executed, look up the necessary services from the service layer and use them.
Also, if you are going to have a full workbench, you could directly use extensions and extension points that help coordinate a bit.

OSGi User Admin Service User Objects

I wanted to use the OSGi User Admin service for security but I could not get enough resource about it.
I want to authenticate certain bundles that will be installed in the system and represent them by User-Objects after authentication. So that I can later use these User-Object for authorization.
I have 2 questions:
Since I have more than one user, how can I know which bundle is calling a secured method? (I don't want to pass the user object as a parameter to every method I want to control).
How can I relate the bundles with the User-Object representing them?
I want to have one bundle as an entry point that will authenticate all these other bundles and have control over them. But I couldn't even find anyone mentioning using User Admin service. Is there another option for OSGi security besides CPA? I would like to use this to secure my console as well.
That's quite a few questions rolled into one. Let me try to answer them all.
First of all, the UserAdmin service is specified in the OSGi compendium. There, it explains how users, roles, etc are defined and how you can use the service to answer questions like "does this user have role X"? What that does not tell you is how to use this service as part of a security solution. That's up to you.
Regarding question 1, which is not an OSGi related problem (but rather a generic one in Java applications), there traditionally have been a few methods of passing on a "context" to a method:
Making it an argument to each method (which you do not want to do).
Storing it in the ThreadLocal context (which is fairly popular in JavaEE, but has its downsides if your application delegates work to threadpools that might or might not pass on such a context correctly).
If this is all about security for services that you implement yourself (and not third-party ones) you could use the ServiceFactory pattern in OSGi to give each client bundle it's own context (and embed the User object in there; for examples look at the LogService implementation in Felix, which uses that mechanism to add a bundle.id to each log message).
Sometimes it also makes sense to embed the context not in an extra parameter to your methods, but as part of some existing object (so effectively you are then associating the context with specific objects, which might or might not make sense depending on your domain).
Another option would be to use the Apache Felix Dependency Manager to intercept the services you want to secure (with an aspect) and, in the aspect, figure out what bundle is calling, and do the proper security checks (probably requires a more detailed answer if you want to give that a go).
Regarding question 2, bundles have a symbolic name that identifies them. You could use that to associate a bundle with a User. There are other options, but this is the most obvious one.
Regarding your question about options for OSGi security, I would say ConditionalPermissionAdmin (and the older PermissionAdmin) is the only solution to address security within the OSGi framework itself, if you want to specify what specific bundles can and cannot do in terms of importing packages, using services, accessing the filesystem, etc. You would have to write your own custom permissions if you want to integrate this with UserAdmin.
Finally, the secure console is yet another thing you need to address yourself. You might be able to find some building blocks as I know there have been people implementing some role based access (David Bosschaert comes to mind). However, the console is a complex and powerful thing, so answering this question alone takes more than a simple SO question because it depends what and how fine grained you want to implement this.

How do you properly handle logging in OSGi while separating service components?

I am working with OSGi and declarative services (DS) and am currently thinking of how to handle the logging properly. Since i'm working with DS anyways, it seems natural to use the LogService specified by the OSGi service compendium as a mandatory service reference. I have been reading a lot on the net at ekkes corner and nogunners's blog, but something is still unclear to me:
How do I make a proper distinction of different service components (or different service component instances when using factored components)?
If I look at nogunners implementation of the LogListener using Logback, he uses the Bundle-Id form the bundlecontext to differentiate those. Ok so far. But how would I differentiate the service components? The LogService object contains a reference to the BundleContext naturally, but (looking into the LogService interface) a ServiceReference must be given by the user (the one who actually logs something) itself? This seems fragile to me. Why can't the framework deliver this as it delivers the BundleContext?
And while I'm at it, why does the OSGi spec use the verbose logger.log(LogService.LOG_INFO,...) instead of the quasi-standard logger.info(...), logger.warn(..) etc.? Is there some specific reason for that?
There is no standard way to log the component id, you will have to embed this in the message.
The OSGi log service is 14 years old ... It was decided not to upgrade it because there were already so (too) many logging systems around.
Look at http://team.ops4j.org/wiki/display/paxlogging/Pax+Logging, they integrate popular loggers with OSGi (both ways).

Calling of <aop:aspectj-autoproxy /> multiple times when loading spring context

Let's say I am defining a custom aspect and to enable proxying I am using aop:aspectj-autoproxy. Now I am also importing another third-party spring context in the application that also happens to call aop:aspectj-autoproxy (ofcourse I won't know about it upfront unless I pore over the context xml contents extracted from the JAR). Potentially there can be many such contexts. Here I see that the beans matching the pointcut get proxied over and over i.e. proxy of a proxy. Is there a way that one can avoid such a proxy of a proxy? Also feel free to point out any anti-patterns that may be at play here.
Thanks in advance.
From Spring documentation:
http://static.springsource.org/spring/docs/3.0.6.RELEASE/spring-framework-reference/html/aop.html#aop-proxying
Note Multiple sections are collapsed into a single
unified auto-proxy creator at runtime, which applies the strongest
proxy settings that any of the sections (typically from
different XML bean definition files) specified. This also applies to
the tx:annotation-driven and aop:aspectj-autoproxy elements.
To be clear: using 'proxy-target-class="true"' on
, or
elements will force the use of CGLIB proxies for all three of them
I believe the problem mainly relates to
Now I am also importing another third-party spring context in the application that also happens to call aop:aspectj-autoproxy
Instead of directly importing the app ctx provided by 3rd party lib (which is, in most case, provided for ease of initial development or for small project), try to manage those 3rd party beans in your own app ctx, and make sure you do not have multiple aop:aspectj-autoproxy (There are lots of bean post-processor etc in spring that is not safe in multiple declaration.)

How to modularize a JSF/Facelets/Spring application with OSGi?

I'm working with very large JSF/Facelets applications which use Spring for DI/bean management.
My applications have modular structure and I'm currently looking for approaches to standardize the modularization.
My goal is to compose a web application from a number of modules (possibly depending on each other). Each module may contain the following:
Classes;
Static resources (images, CSS, scripts);
Facelet templates;
Managed beans - Spring application contexts, with request, session and application-scoped beans (alternative is JSF managed beans);
Servlet API stuff - servlets, filters, listeners (this is optional).
What I'd like to avoid (almost at all costs) is the need to copy or extract module resources (like Facelets templates) to the WAR or to extend the web.xml for module's servlets, filters, etc. It must be enough to add the module (JAR, bundle, artifact, ...) to the web application (WEB-INF/lib, bundles, plugins, ...) to extend the web application with this module.
Currently I solve this task with a custom modularization solution which is heavily based on using classpath resources:
Special resources servlet serves static resources from classpath resources (JARs).
Special Facelets resource resolver allows loading Facelet templates from classpath resources.
Spring loads application contexts via the pattern classpath*:com/acme/foo/module/applicationContext.xml - this loads application contexts defined in module JARs.
Finally, a pair of delegating servlets and filters delegate request processing to the servlets and filters configured in Spring application contexts from modules.
Last days I read a lot about OSGi and I was considering, how (and if) I could use OSGi as a standardized modularization approach. I was thinking about how individual tasks could be solved with OSGi:
Static resources - OSGi bundles which want to export static resources register a ResourceLoader instances with the bundle context. A central ResourceServlet uses these resource loaders to load resources from bundles.
Facelet templates - similar to above, a central ResourceResolver uses services registered by bundles.
Managed beans - I have no idea how to use an expression like #{myBean.property} if myBean is defined in one of the bundles.
Servlet API stuff - use something like WebExtender/Pax Web to register servlets, filters and so on.
My questions are:
Am I inventing a bicycle here? Are there standard solutions for that? I've found a mentioning of Spring Slices but could not find much documentation about it.
Do you think OSGi is the right technology for the described task?
Is my sketch of OSGI application more or less correct?
How should managed beans (especially request/session scope) be handled?
I'd be generally grateful for your comments.
What you're aiming to do sounds doable, with a few caveats:
The View Layer: First, your view layer sounds a little overstuffed. There are other ways to modularize JSF components by using custom components that will avoid the headaches involved with trying to create something as dramatic as late-binding managed beans.
The Modules Themselves: Second, your modules don't seem particularly modular. Your first bullet-list makes it sound as if you're trying to create interoperable web apps, rather than modules per se. My idea of a module is that each component has a well-defined, and more or less discrete, purpose. Like how ex underlies vi. If you're going down the OSGi route, then we should define modular like this: Modular, for the sake of this discussion, means that components are hot-swappable -- that is, they can be added and removed without breaking the app.
Dependencies: I'm a little concerned by your description of the modules as "possibly depending on each other." You probably (I hope) already know this, but your dependencies ought to form a directed acyclic graph. Once you introduce a circular dependency, you're asking for a world of hurt in terms of the app's eventual maintainability. One of the biggest weaknesses of OSGi is that it doesn't prevent circular dependencies, so it's up to you to enforce this. Otherwise your dependencies will grow like kudzu and gradually choke the rest of your system's ecosystem.
Servlets: Fuhgeddaboudit. You can't late-bind servlets into a web app, not until the Servlet 3.0 spec is in production (as Pascal pointed out). To launch a separate utility servlet, you'll need to put it into its own app.
OK, so much for the caveats. Let's think about how this might work:
You've defined your own JSF module to do... what, exactly? Let's give it a defined, fairly trivial purpose: a login screen. So you create your login screen, late-bind it using OSGi into your app and... then what? How does the app know the login functionality is there, if you haven't defined it in your .jspx page? How does the app know to navigate to something it can't know is there?
There are ways to get around this using conditional includes and the like (e.g., <c:if #{loginBean.notEmpty}>), but, like you said, things get a little hairy when your managed loginBean exists in another module that may not have even been introduced to the app yet. In fact, you'll get a servlet exception unless that loginBean exists. So what do you do?
You define an API in one of your modules. All the managed beans that you intend to share between modules must be specified as interfaces in this API layer. And all your modules must have default implementations of any of these interfaces that they intend to use. And this API must be shared between all interoperable modules. Then you can use OSGi and Spring to wire together the specified beans with their implementation.
I need to take a moment to point out that this is not how I would approach this problem. Not at all. Given something like as simple as a login page, or even as complicated as a stock chart, I'd personally prefer to create a custom JSF component. But if the requirement is "I want my managed beans to be modular (i.e., hot-swappable, etc)," this is the only way I know to make it work. And I'm not even entirely sure it will work. This email exchange suggests that it's a problem that JSF developers have only just started to work on.
I normally consider managed beans to be part of the view layer, and as such I use them only for view logic, and delegate everything else to the service layer. Making managed beans late-binding is, to my mind, promoting them out of the view layer and into the business logic. There's a reason why all those tutorials are so focused on services: because most of the time you want to consider what it would take for your app to run "headless," and how easy it would be to "skin" your view if, for instance, you wanted it to run, with all its functionality, on an Android phone.
But it sounds like a lot of what you're working with is itself view logic -- for instance, the need to swap in a different view template. OSGi/Spring should be able to help, but you'll need something in your app to choose between available implementations: pretty much what OSGi's Service Registry was built to do.
That leaves static resources. You can modularize these, but remember, you'll need to define an interface to retrieve these resources, and you'll need to provide a default implementation so your app doesn't choke if they're absent. If i18n is a consideration, this could be a good way to go. If you wanted to be really adventurous, then you could push your static resources into JNDI. That would make them completely hot-swappable, and save you the pain of trying to resolve which implementation to use programmatically, but there are some downsides: any failed lookup will cause your app to throw a NamingException. And it's overkill. JNDI is normally used in web apps for app configuration.
As for your remaining questions:
Am I inventing a bicycle here? Are there standard solutions for that?
You are, a little. I've seen apps that do this kind of thing, but you seem to have stumbled into a fairly unique set of requirements.
Do you think OSGi is the right technology for the described task?
If you need the modules to be hot-swappable, then your choices are OSGi and the lighter-weight ServiceLocator interface.
Is my sketch of OSGI application more or less correct?
I can't really tell without knowing more about where your component boundaries are. At the moment, it sounds like you may be pushing OSGi to do more than it is capable of doing.
But don't take my word for it. I found other reading material in these places.
And since you ask about Spring Slices, this should be enough to get you started. You'll need a Git client, and it looks like you'll be training yourself on the app by looking through the source code. And it's very early prototype code.
I am facing the same problems in my current project. In my opinion, OSGi is the best and cleanest solution in terms of standards and future support, but currently you may hit some problems if you try using it in a web application:
there is no well integrated solution between a Web Container and the OSGi platform yet.
OSGi may be too much for a custom build web application that is just searching for a simple modularized architecture. I would consider OSGi if my project needs to support third party extensions that are not 100% under our control, if the project needs hot redeployments, strict access rules between plugins, etc.
A custom solution based on class loaders and resource filters seems very appropriate for me.
As an example you can study the Hudson source code or Java Plug-in Framework (JPF) Project(http://jpf.sourceforge.net/).
As about extending the web.xml, we may be lucky with the Servlet 3.0 specification(http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html#pluggability-and-extensibility).
The "web module deployment descriptor fragment" (aka web-fragment.xml) introduced by the Servlet 3.0 specification would be nice here. The specification defines it as:
A web fragment is a logical
partitioning of the web app in such a
way that the frameworks being used
within the web app can define all the
artifacts without asking devlopers to
edit or add information in the
web.xml.
Java EE 6 is maybe not an option for you right now though. Still, it would to be the standardized solution.
Enterprise OSGi is a fairly new domain so dont think you will get a solution that directly satisfies your need. That said one of the things I found missing from Equinox (osgi engine behind eclipse and hence one with largest user base!) is a consistent configuration / DI service. In my project recently we had some similar needs and ended building a simple configuration osgi service.
One of the problems which will be inherent to modular applications would be around DI, as the module visibility could prevent class access in some cases. We got around this using a registered-buddy policy, which is not too ideal but works.
Other than configuration, you can take a look at the recently released Equinox book for guidance on using OSGi as base for creating modular applications. The examples may be specific to Equinox, but the principles would work with any OSGi framework. Link - http://equinoxosgi.org/
You should look into Spring DM Server (it's being transitioned to Eclipse Virgo but that's not been released yet). There's a lot of good things in the recent OSGi enterprise spec which has also just been released.
Some of the Spring DM tutorials will help, I'd imagine. But yes, it's possible to have both resources and classes loaded from outside the web bundle using standard modularity. In that, it's a good fit.
As for the session context - it gets handled as you would expect in a session. However, you might run into problems with sharing that session between web bundles to the extent that in not sure if it's even possible.
You could also look to have a single web bundle and then use e.g. the Eclipse extension registry to extend the capabilities of you web app.

Categories