How can i call service from another in OSGI - service

I started developping an OSGI bundle base application. I created a bundle A that consumes service from bundle B, wich in its turn must consume service from bundle C.
But i dont see how get a service inside the code of another. The servicetracker needs the bundlecontext and i don't have a bundlecontext in my service code.
Thanks in advance,

In your service B code you should have a setter for the interface of service C.
You then start the ServiceTracker from the bundle Activator in bundle B. When the service C is added you create service B, when it is remove your remove it.
If you do not want to do this by hand you can look into declarative services, blueprint or ipojo. All these all you to specify these dependencies declaratively.

Related

Microservices with Karaf hot code replacement

I have a need to write a microservice and planning to use Karaf. I understand that Karaf is an OSGi based container for microservices to provide modularity. Now, my question is
Suppose I write a REST-based/ extends BundleActivator service and deploy the Java code
As a bundle into Karaf. And say later when I make changes to service and deploy it again
Will it continue without any downtime? Will, it Hot deploy the java code/ module without any downtime?
Will it have support for one module to invoke another as an API/service call?
Thanks

Initializing Fabric on multiple targets

I have a module layer (embeds a framework) within my application to serve as a generic logging service to several services like Fabric, Mixpanel etc.
This module has a target dependency with the main app target.
I am initializing Fabric in the main app target's AppDelegate and later making calls to the Module layer for sending custom logs of this sort:
`CLSLogv("%#", getVaList("Some Log"))`
This however does not work unless I explicitly initialize Fabric in the Module layer
`Fabric.with([Crashlytics.self()])`
(The same way I've done it in the AppDelegate.)
I have NOT added a run script phase for Fabric in the Module target.
My question is, is this needed really since the module is a target dependency to the main app target and it already initializes Fabric in its app delegate?
If it is needed, is this going to cause any issues?

osgi multiple versions of service

i have osgi services service-1.0.0.jar and service-1.1.0.jar they are implementation of service-api-1.0.0.jar
both these service-1.0.0.jar and service-1.1.0.jar have same service name and packages.
service are registered by bundle-activator
lets assume bundle activator is com.abc.xyz.MyActivator - 1.0.0 and 1.1.0
issue I am facing is when I deploy these services and lookup using service tracker and filter on version I want, I always get same implementation regardless of what version chosen.
this makes me believe that what i am trying to achieve is not doable.
I need multiple implementation of service packaged in separate bundles with difference of version and be able to choose dynamically at runtime.
I am trying this in jboss-6.1.1 eap
if i keep different package name in versions looks like it is able to understand that these are 2 different services but when package names are same i get same service implementation.
am i doing something wrong? has anybody tried this?
is it correct that OSGI allow you to deploy multiple versions of service?
UPDATE After using unique package names for MyActivator in 1.0.0 and 1.1.0 looks like the services are able to maintain the uniqueness.
Does that mean Activators has to unique across bundles?
I assume that service-api-1.0.0.jar exports the package which defines the service interface. In that case, it sounds like you have two implementations of the same version of the service. Not different implementations of different versions of the service. So from a service user point of view, the services are that same: they are from the same service api package version.
I think you are using the OSGi services in a strange way. As a client you should not look into the implemention bundles to determine versions or other informations.
Instead you should use the service interface and service properties to distinguish between services.
So for example you can have a property version and publish the first service with version=1 and the second with version=2. Then you can filter for this property to get a specific service.
Using reflection is also a rather unusual thing. Better try to provide classes in the interface package that you use to exchange data between client and service. This will make the client less dependent on the service impl.
If you have multiple implementations of the same service API, and a client queries for an implementation of the service API, it could get any of the implementations. And that's good because the client shouldn't care.
Say for example you have a Greeting interface with multiple implementations registered as services, possibly by multiple bundles. If a client asks OSGi for a Greeting service then OSGi will simply pick one. After all, if you just ask for a Greeting without specifying anything else then you should accept any implementation. Clients certainly shouldn't care which particular bundle the service comes from: this is the nature of decoupling.
Incidentally, when this happens OSGi normally chooses the implementation that was registered first (actually the one with the lowest service.id, which is an ever-incrementing number, so it's effectively the same thing). This is probably why you see OSGi consistently choosing one particular service.
If your client needs to distinguish between service implementations then you can add properties to the published services and filter on those services. For example one bundle could publish a Greeting service with property language=en_US (i.e. US English) and another could publish a Greeting service with language=de. If your client only wants greetings in English then it can use a filter like (language=en*).

Is there a way to know when and in what plug-in Eclipse service is registered?

It's nice that Eclipse uses service oriented architecture more and more, but am I only the developer who sees the lack of knowledge of by what plug-in and at what stage service is registered as a problem?
Consider example:
IServiceLocator someServiceLocator = ...
SomeService someService = (SomeService)someServiceLocator.getService(SomeService.class);
// oops, someService is null
Possible reasons to why someService is null are:
Some plug-in that registers this service doesn't present or not loaded
Service wasn't registered yet
How should one resolve this? Are there any tools?
Thanks.
The short answer: there are no tools available.
For the complete list of services and where they are registered do "Call Hierarchy" on ServiceLocator.registerService(Class api, Object service).
For a good list of the available global services, look at Workbench.initializeDefaultServices(). There are some additional services that are only available at the window or workbench part level.
If you want to know what plugins are installed and started, you can use the OSGI console and see the state of the plugins.
So if you are looking for a service "XService", find the plugin which contains the service and look for the plugin state on the OSGI console.
Start you application with -console option and type ss on the osgi console. This is not straight forward but works.

OSGi : How can a Service auto discover client bundles deployed at runtime?

I have a scenario where during the system install time, a few services were deployed on to the OSGi container and these services will be listening for other bundles that provide data and are dynamically installed and uninstalled at runtime.
These data providers do not expose any services and should not even invoke services; my idea is to enable the pre-deployed services to listen for the event of installation of these data provider bundles and if the pattern matches, then process and persist the data into the data store.
For example I have a WidgetService which will listen for installation or uninstallation event of Widget data provider bundles, ShppingCartService that will listen for the installation/uninstallation events from ShoppableItem data provider bundles, etc.
This helps me to keep the processing and persisting logic be centralized and my data providers need not write any code to make their data processed. All that is expected from the data provider bundles is the Service Name/id, Service Version,PreRequisites, and the data that they need to publish.
I have read several articles on OSGi that explain dynamic pluggability of services and the clients able to discover or discard services based on their availabity; however, those are all talking about scenarios where clients are to be intelligent to discover and execute the services they are interested in.
My intention is to make client completely unaware of any service discovery, for that matter any code. All that the client passes is the info about the service the client is interseted in, the dependencies, and the data; the client should be completely dumb.
Is this possible in OSGi? I'm ready to consider this architecture even at the cost of extending a few of the OSGi core framework classes!
I have found some what, may be, remotely related question on stack overflow at :
Discovering Bundle MetaData with out installing the bundle
However, I want a hook or an event that will call my respective service when one or more data provider bundles have been installed. These data provider bundles can be interested in any of the services that are installed in the system. I'm even ready to write a central bunle repository manager/listener kind of stuff that will listen to any bundle installation and invoke my Service facade that will decide which service to execute based on the meta data provided by the data provider bundle.
I'm just starting OSGi, so need a little direction on how to move forward...
I'll be really thankful to you guys/girls :) if you can help me achieve this!
I have a doubt deep in my mind that this may not be readily available in OSGi, and even if that is true I'm ready to spend time and extend the framework to achieve this. All I need is a few guidelines and a clear direction. Who knows, if OSGi is really lacking this functionality, then it would be a very useful add-on to a future OSGi spec.
You might have a look at section 4.7 (Events) of the OSGi Core spec. The Framework raises BundleEvents when there is a change in the lifecycle of a bundle, e.g. when it is installed or uninstalled. What you need to do is to implement a BundleListener, which then will receive the events, so your service can react on the changes.
I have described a design pattern that I call "OSGi Mediator", which may be a solution to your problem.
The items you want to mediate would only require to register with the service registry; all the dependencies could be managed by your mediator implementation.