I have OSGi bundle in which One service class is used by two clients. both the clients using the same version of service class say 1.0, now i have made some changes in service class and updating the version of service class say 1.1, now my problem is I want both the versions of the service class means one client can use 1.0 version and another client can use 1.1 how can achieve this? If any sample can provide me for dynamic versioning its really helpfull for me.
Thanks.
The version of a service is the version of the interface it implements, which comes from the version of the exported package that that interface exists in.
The service implementation class version is irrelevant because the consumer of the service has no knowledge of the implementation class. Therefore if you register multiple services with the same interface, they will all be visible to the consumer.
I don't think OSGi has a real notion of service versions, but you can use any key/value pair you like when registering a service. The Knopflerfish tutorial is pretty good I think.
For example, when registering a service:
Hashtable props = new Hashtable();
props.put("version", "1.0");
bundleContext.registerService(ServiceInterface.class.getName(), impl, props);
Then, when consuming a service, you can use those attributes to require certain attributes.
Having multiple versions of this service is very easy, the tricky part is how the service consumers deal with it.
If you have two consumers using version 1.0, and 1.1 appears (for example when a new bundle has been started), should the consumers stop using 1.0 and start using 1.1? In your example, one of the consumers should ignore this, while the other should rewire to 1.1. This gets especially complicated when one consumer consumes multiple services.
I recommend looking into Declarative services, it can make this a lot easier and keep your code cleaner, I'd say start here
Related
I'm trying to create a service such that once it is created it only allows itself to be held by a single consumer/bundle at any one time. (If this is against the philosophy/specification of OSGi then that obviously provides a quick answer but reference to the OSGi specs. stating this would be appreciated.)
To implement such a requirement I implemented the ServiceFactory interface thinking that whenever there was a requirement for the service the getService(Bundle bundle, ServiceRegistration<S> registration) method would be called and it would be where I could determine if the Bundle was a new consumer or not and act accordingly.
It appears that this is not the case in the scenario I have tested this in.
Using a Apache Karaf and instantiating a consumer of the Service via Blueprint it would seem that the getService method is never called. Instead the consumer's binding method for the service is called directly but injecting a proxy service object.
While I understand that Blueprint uses proxies surely there is still the obligation of the ServiceFactory contract to fulfil even if it's a proxy object consuming the service?
Why do I want to do this?
I am attempting to wrap JavaFX and the Stage class and because JavaFX isn't OSGi friendly I am attempting to co-ordinate access to the Stage object. I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
It depends what you mean by a consumer. ServiceFactory does give you the chance to create a separate instance of a service per bundle that calls getService on your service. It's not clear from your question but I suspect you weren't seeing the getService invoked multiple times because you were fetching the service from the same consumer bundle. In this case, ServiceFactory simply returns the same object repeatedly.
As for your general question about restricting access to a single consumer, no that really goes against the OSGi philosophy. I'm sorry I don't have a spec reference for you but the clue is in the name: it's a service that is available to all.
I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
Please note that the layout of Drombler FX applications is pluggable so you can provide your own implementation tailored to your needs. This allows you to get the most out of Drombler FX and JavaFX.
While this feature is available for some time, there is now a new tutorial trail explaining it in more detail.
I am bit confused about following things. I understand #Service and #Component annotations are main annotations when we define a component or a service in OSGi. I am referring to http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html and What is the difference between OSGi Components and Services
Questions:
A service can not be created without #Component annotation, why is that?
I understand once we define a service its life-cycle is managed by OSGi differently but what are the advantages of doing so?
How do we use class defined as #Component as service can be accessed via sling.getService(ServiceName.class)
A service can be published without a #Component annotation, but you have to do it programmatically. If you use the annotation then you benefit from the automatic metadata generation in the build tool, and also from the Declarative Services runtime framework. This simplifies a lot of things. If you want to do it with low-level code you have to write an implementation of BundleActivator, declare that with the Bundle-Activator manifest header, call context.registerService etc. Bottom line: just use the #Component annotation!
Simple: laziness. When a component is a service then it can be instantiated lazily "on-demand", i.e. only when consumer first tries to use the service. Non-service components, on the other hand, usually do other kinds of things inside themselves, e.g. running a web server or a GUI or a polling thread, whatever. These need to be running all the time, rather than on-demand.
3. I didn't understand this question.
A component that is not published as a service cannot be accessed from outside the bundle. If you want it to be accessible then it has to be a service. In case you think this is useless, consider a component that creates an HTTP server. It opens port 80 and responds to network requests from the outside world. So it does something useful even though it's not a service and not accessible from other bundles. This kind of component is like a bridge between your application and the outside world; whereas services are a bridge between one part of your application and another part.
OSGi is the one where bundles are installed and manages. Everything that needs to be there in OSGi has to be a component be it simple component, a service or servlet. That is why we need to use #Component with service also.
Services are singleton. Everything that needs to be managed for Singleton class and using reference of service is done by OSGi. Nothing has to be done from our side. So everything is automatically managed.
You dont access components like that. Components are independently used. Quoting example from different post:
Suppose you want to a write Server component that sits on socket and responds to requests over TCP/IP. When the component starts, it opens the socket and creates the thread(s) required to serve clients. When it stops, it closes the thread(s) and socket
I am a beginner to OSGI and I am wondering if someone can enlighten me about the difference between creating OSGI service vs singleton pattern. For example, suppose I have a bundle core which provides IService, and multiple bundles that needs to access this. I can:
register a service in the core-bundle, in which the plugins can access
provide a singleton class, which provides the service
Using OSGI service seems to be quite cumbersome; and since the plugins have to depend on Core anyways (to get the interface), what's the advantage of using OSGI service?
Services are the connections between independent modules. Having modules depend on services (with their specification packages) can significantly reduce coupling between modules and thus provide much of the benefits of modularity.
I think the singleton pattern is used in two different ways: you just want a single object be shared between a set of users (e.g. a Log Service) or you can really only have one instance (e.g. there is only one piece of hardware). In general, I see that most people in the enterprise software world talk about the former. However, experience shows that when projects grow, singletons become less singleton but more a shared object, or at least an appearing to be shared object.
The nice thing in OSGi is that you can model both and the clients of the "singleton" are oblivious of it, nor does it require some central configuration. The reason is that OSGi relies on modules in charge, registering a service is a local decision as is listening to a service.
The power of services are not in its dynamics (they are cool though, especially during development), the essence of service is that they provide full local control inside the module without central configuration. Once you understand how powerful this is, there is no way back :-)
Last, OSGi services are not cumbersome, not since we have DS with annotations. Registering a service is now much simpler than creating a Spring bean, no xml, no central configuration:
// A component registered as a ISingleton service
#Component
public class MyImpl implements ISingleton {
void doSingle() { ... }
}
// A component that uses the ISingleton component
#Component
public class MyConsumer {
#Reference
void setISingleton(ISingleton is) { ... }
}
... And the dynamics come largely for free ...
Short answer: if you don't -- and won't -- need the benefit of an OSGi service (e.g., dynamically-managed service implementations and service searches), then you don't need an OSGi service.
But there is more to consider here than whether or not the service would be cumbersome. Heck, OSGi itself can be considered cumbersome. Will another bundle need to provide an implementation of that class? Maybe not. Will the Core bundle ever shut down or otherwise be unable to provide an implementation on demand? Maybe.
To determine if a service is right for the class in question, read the run-down of the specific benefits of a service on the OSGi Alliance's What Is OSGi page. They have a very good explanation of how your singleton class may become more cumbersome than a service.
Good luck.
My OSGi Threading Model 's poc is resulted into believing me that, every service is a singleton for a service consumer. As the only one service object get registered into the osgi service registry. (but you can override this behavior also). So as far as programming is considered, the behavior of a singleton class and an OSGi service is the same. Your class level variables are shared among the various service consumer calls.
I will say OSGI Service is Singleton++
But there are also differences.
OSGi gives you a separate class-loader for each service which is not possible in a singleton. All {singleton} classes are loaded by a single classloader. We can't have two classes with the same name (fully qualified name) in a singleton but this is possible in OSGi.
In certain situations we must be confirmed that a class should be loaded only once (making hibernate session factory, hdfc service initialization, POJO creations which are heavy initializations required only once). Now if you are living in a Java EE scenario some times your singleton class gets loaded twice by two different classloaders. So this results into two times the execution of a static block; an unnecessary job.
Such classloader problems are easily handled by OSGi (as you are a beginner I feel classloading itself is a problem for you in the next few days).
Another great feature provided by OSGi is updating a bundle.
Consider you changed the code in your singleton class. Now you need to deploy this updated class in your running application. You essentially need to restart the system, so that every singleton class loader updates the new instance of the singleton. This is not required in OSGi, just update the bundle.
I will say if you're going to design for larger applications (enterprise scale), or if you need to design code for a limited hardware capacity (low memory constraints, low computing power) then go for OSGi, it is best for the extreme ends. For all others your normal java coding will work perfectly.
You can manage the life cycle (deploy new version of the service, concurrently run multiple versions etc) of a service but you can't manage the life cycle of singleton without restarting the JVM (even with restart you can just have 1 version available at any point of time).
We have to support at least 2 versions of functionality at the same time. It can be in the web side or services, meaning we'll have different layout for different users in the web or service implementation will be different for different users. We should be able to route the users based on their login to the right version of the web application / bundle.
We thought of something like this (please see bigger picture here http://i.stack.imgur.com/6NxhF.png).
Also is it possible to have multiple web applications / bundles deployed as one EBA? If yes, is it possible to share the session between these web apps / bundles? As we are new to OSGi, looking forward to any suggestion on the design we have chosen. Appreciate any help / suggestions on this.
Thanks,
Bab.
OSGi could be right for you. In my last project we had something equivalent to your approach. We've developed a backend system with OSGi where we had a backend connector as a starting point for different other bundles who wants to use functionalities of the backend. In your case the backend is your shared bundle context. We then had a SOAP webservice, several servlets and webpages (which should be OSGi based as well) which sends requests to the backend connector. Of course you can send request directly to internal bundles like your manager, but I would propose a layered architecture. In case of shared sessions: The question is which component is responsible for handling sessions? If you want to have not only web applications in your environment, you can manage sessions via a database or an inmemory approach. A 'SessionManager' bundle in your shared context is then responsible for creating user sessions (sessionid for identification), relating sessionid and temp data, getting data for sessionid and deleting temp data for sessionid. With this approach each client request should send the sessionid, which will be validate somewhere in your shared context. Then you dont need the web sessions. The created sessionid could be stored in a specific HTTP header entry of Request/Response for the communication. But thats only one approach.
Hopefully, all above makes sence to you. If not send me an email and we can discuss it more in depth. :) Sometimes pictures say more as a lot of sentences and I could draw some if you want. ;)
Greetings.
Christian
Yes, OSGi can help you a lot with this.
The architecture you have chosen looks fine, I would suggest perhaps also adding a 'SessionManager' as suggested by Christian.
Regarding the OSGi specifics you will need for this:
If you have two different versions of the "Services" bundle, which are packaged in the same Java packages, you should definitely define package versions when exporting them in the manifests:
In Services V1:
Export-Package: com.acme.foo;version="1.24"
and in Services V2
Export-Package: com.acme.foo;version="2.3"
You can then control which package is imported in the Web bundles by defining restrictions, e.g. like this for whole intervals:
Import-Package: com.acme.foo;version="[1.23, 2)"
The beauty of this is that due to the modularity of OSGi and the separate classloaders of the bundles both versions of com.acme.foo can be installed and used in the same system. You cannot achieve this in the "usual" Java setup, because there there is only one classloader and one version of the package will shadow the other.
You can see OSGi demos and examples for example here
This was about the packages and libraries.
Now about the actual service objects:
You could also have two versions of the same service published in the OSGi Service Registry. The easiest way to differentiate between the two is to use service properties when registering the service:
Hashtable properties = new Hashtable();
properties.put( "service_flavour",
"advanced" );
context.registerService(
SomeService.class.getName(),
this, properties );
You can then use the props to lookup the correct service in the Web bundles:
ServiceTracker someServiceTracker = new ServiceTracker(bc, "(&(objectclass="+SomeService.class.getName()+")(service_flavour=advanced))", null);
someServiceTracker.open();
Regarding your question about EBA - I am not sure what you mean. You can install as many bundles as you want in any OSGi framework, and they can all register under different aliases in the OSGi HTTP service. As long as the aliases don't have a conflict with each other it is ok. You can also have one main servlet if you want, and distribute the handling of the different pages to other bundles without registering them as servlets too - your main web servlet could look them up in the OSGi service registry for example, and distribute the work. It all depends whether you expect more application logic/calculations etc, or is it more about formatting and representation of some existing data.
Hope this helps.
Search did not give me a hint, how can i behave with the following situation:
I'd love to have 2 OSGI implementations of the same interface: one is regular, the other should work (be active/present/whatever) on the given time period (f.e for Christmas weeks :))
The main goal is to call the same interface without specifying any flags/properties/without manual switching of ranking. Application should somehow switch implementation for this special period, doing another/regular job before and after :)
I'm a newbie, maybe i do not completely understand OSGI concept somewhere, sorry for that of give me a hint or link, sorry for my English.
Using Felix/Equinox with Apache Aries.
The publisher of a service can register and unregister that service whenever it likes using the normal API. If it chooses then it can do so according to some regular schedule.
If there is another service instance that is available continuously, then the consumer of the service will sometimes see two instances of the service and sometimes see one. When there is only one instance available then it is trivial to get only that instance. When there are two instances then you need a way to ensure you get your "preferred" instance. The SERVICE_RANKING property is a way to do this. The getService method of a normal ServiceTracker will always return the higher ranked service, so this would appear to satisfy your requirement.
I have yet to see an OSGI container that at a framework level supports date/time based availability of services.
If I were you I would simply drop a proxy service in front of the two interface implementations and put the service invocation based on date logic in there.
I don't believe there is any framework support for what you are asking for.
If you are intent on avoiding service filters, you might try this.
Implement a PolicyService. This service is in charge of deciding which instance of your service should be registered at a given point in time. When its time for the policy service to switch implementations, it just uses the register/unregister apis as usual. You policy service implementation can read in a config file that specifies the date range to service implementation mapping. This will allow you to add new behavior by modifying your config file and installing a new bundle with the new service.
I agree with Neil that a service should only publish itself if it can actually be invoked. My solution to this problem would be to have all service producers be dependent on a "time constraint dependency". Whilst such a dependency is not available in the standard dependency frameworks (like Declarative Services, Blueprint, iPOJO) it is easily implemented with the Apache Felix Dependency Manager, which allows you to create your own types of dependencies. Note that writing such a new dependency once is some work, but if this is a core piece of your application I think it's worth it. Service consumers would not require any special logic, they would simply invoke the service that was there.
Ok, what i have finally done...
Implemented a common dispatcher bundle - and call any of services only thru it (therefore cron is not needed, when call is on-demand)
When dispatcher obtains request - it searches for interface in its own cache and -
When there are >1 service with the same ranking and both are equal (registered) - then
Dispatcher resolves needed service via own written #TimigPolicy annotation with "from" and "to" fields
For the given server new datetime() - dispatcher returns proper service instance
Much work, i should say :) But works nearly perfect :)
Thanks everybody for giving me hints, it was really helpful!!!