Programmatically adding declarative services - osgi

Is it possible to add declarative services using some kind of api?
A little background:
I have a server application based on dynamic scripts (they can be added, edited or removed at any time).
Those scripts have dependencies to OSGi services and possibly each other. Whenever a script gets
edited, the script gets compiled to javascript, and its dependencies are detected.
At that point, I'd like to (re)register it as a declarative service, so it will be activated / deactivated when its
dependencies come and go.
Is this even possible? Or is there something major I'm missing?
If it isn't possible with an OSGi standard, is there a specific solution for Felix or Equinox?
Can you do that in the other frameworks, like iPojo or blueprint?

There is no API to imperatively add declarative services. You can use the normal OSGi api to register and use services. Perhaps that is what you want?
You may want to checkout the Dependency Manager which may provide an API model giving you the dependency support you want.

Related

How do you call an OSGi application from a non-OSGi application, and vice versa

I am considering writing a new set of applications using OSGi, but they will need to interact heavily with existing non-OSGi applications.
To clarify, the new applications will need to call into existing non-OSGi code bases maintained by other teams (usually propriety services of varying protocols), and new non-OSGi applications will need to call the new OSGi services.
I am not seeing much documentation for how to do this.
Can someone please point me to the correct steps
It sounds like you want to embed OSGi into a larger application. A good starting point for this is a blog post I wrote some time ago: http://njbartlett.name/2011/07/03/embedding-osgi.html
The trick to creating visibility between OSGi bundles and the objects "outside" OSGi is to publish and/or consume services using the system bundle's BundleContext. The embedding code must be aware of the objects from the outer application that you want to make visible into OSGi, and it should publish them as services. Be aware that you need to export the service interface packages via the system bundle exports -- how to do this is described in the blog post.
OSGi services are only for communications inside the same JVM process. So I guess you want to communicate between processes. In this case you have all the usual remoting protocols like SOAP, Rest, RMI. On the OSGi side you can bridge from OSGi services to offering SOAP or REST endpoints using Distributed OSGi (DOSGi).

Is it possible to disable an OSGi component programmatically in CQ?

Rather than manually making configuration changes to OSGi components in Felix, it's good practice to create sling:OsgiConfig nodes in the JCR to make sure that the settings are version controlled, applied the same across environments, etc.
Similarly, I want to disable an out-of-the-box component on each environment. Is there any way to achieve this via configuration? Rather than going to system/console/components and disabling it there?
Anything I've read about this has mentioned making changes internally within the bundle, but since it's one that I don't own, I'd need some external configuration to do this.
You can do this with the ScrService, which is published by the SCR runtime bundle. API documentation is here.
Note that ScrService is not "standard", i.e. it doesn't come from the OSGi specification. However it is supported by Felix and Equinox and Knopflerfish, so it's pretty much a de facto standard. In fact this service is used by the Web Console when you go to system/console/components.
Try to use attribute policy=ConfigurationPolicy.REQUIRE on #Component.
Then you could prepare a set of packages with configurations for each environment as part of the build. This is also a good practice for having different OSGI configurations for each environment.
So for some of enironments you could just simply not provide a configuration for a particular component. Such component would not run - it would have unsatisfied status.
I believe I've seen this approach in AEM itself.
You can also create a filter to remove current configurations but it still would require to disable the Component at least once. And this solution will work only if this component has mentioned policy.
The other way around is to prepare a Service that would be responsible for disabling other components - it could be configurable. But it doesn't sound like a good solution to me.

Restlet converter registration in OSGI environment

We run Restlet 2.1 in an OSGi environment (Equinox) as bundle (ie. not as library within a bundle). The problem is that the Restlet Engine does not detect helpers (like converters) that are provided by Restlet extensions. Specifically, the EngineClassLoader#getResources() call does not return any result. The extensions are also deployed as OSGi bundles in the target platform.
Is automatic converter registration actually supposed to work within OSGi environments?
In fact, Restlet supports such feature thanks to a dedicated activator (see the Activator class in the package org.restlet.engine.internal).
This activator introspects bundles to find out the following things:
servers corresponding to registered servers
servers corresponding to registered clients
authenticators corresponding to registered clients
converters
Be aware that to use this feature, we must use the OSGi edition of Restlet since it's the only that has the MANIFEST file of the org.restlet bundle with the activator class specified. Otherwise you don't have to care about the bundle loading order...
Hope it helps you.
Thierry
Unless the Restlet-bundle explicitly imports the packages that contain the extensions (and I doubt it does, and it shouldn't), it wouldn't be able to load them, because bundles have isolated class-spaces.
A possible solution would be to provide the extensions as fragments attached to the Restlet-bundle. Thus, if you make it use the bundle-classloader (the documentation says this can be done by setting the Engines classloader), it would be able to load classes from the fragments.
Indeed it doesn't quite work for OSGi, as it depends on the ability to see the entire class space.
The way to do this in OSGi would be to use the service registry for the extensions, but that only works for OSGi aware libraries.
There is some help on the way: In the recently released OSGi 5 (Service Loader Mediator) there will be support to 'bridge' META-INF/services (I don't know if Restlet uses those, though) onto OSGi services, so 'legacy' libraries should work well within OSGi.
There is an implementation in Apache Aries called Spi-Fly. I looked at it briefly a while back. It might do the trick for you, it might not.

How to dynamically manage project dependancies

We are writing a new set of services and have decided to make them share a common interface... calling it a BaseService. The idea is that whenever anyone wants to develop a new service in our organization, they should be just able to extend and use this BaseService.
We have written a few other classes which also form a part of this base jar, it does things like handle transactions and connect to database using hibernate etc.
Right now all the services that extend the BaseService are a part of the same project (Eclipse + Maven), and some of the services are dependent on each other, but because they are in the same project we don't have a problem with dependencies.However, we expect 40-50 services to be written which would extend base service and would also be interdependent.
I am worried that the size of the base project would be huge and that just because when someone has to use one service they might have to depend on my base jar which has 50 services.
Is there a way that we can make some projects dynamically dependent on others?
Lets say I have a service A which depends on service B, when I build/compile Service A,it should be able to realize that it has a dependency on service B and automatically use the Service B jar.
I have heard of OSGi, will it solve my problem or is there a way I can do it with Maven or is there a simpler solution ?
Sorry about the long post !
Thanks in advance for your suggestions
It doesn't make any sense to "dynamically" manage project dependencies, since build dependencies are by definition not dynamic.
Your question, at least for the moment, seems to be entirely about how to build your code rather than about how to run it. If you are interested in creating a runtime system in which new service implementations can be dynamically added then OSGi may be the solution to look at. An extra advantage here would be that you could enforce the separation of API from implementation, and prevent the implementing services from invalidly depending on parts of your core module that you do not want them to have visibility of.
You could also use OSGi to manage evolution of your core service API through versioning; for example how do you communicate the fact that a non-breaking change has been made to the API versus a breaking change etc.
I would say there are two options depending if i understand your question correct. First one. You have already defined an interface (java term) and now you have different implementations of that. The simple solution for Maven would be to a have a module which is called for example: service-api and than this will be released and can be used by others as dependencies. On their side they simply implement the interface. No problem with the dependencies. If you are more talking about OSGi than you should take a look to maven-tycho.

Is an OSGi service still "OSGi managed" when it's obtained by non-OSGi code?

As an OSGi newbie, I'm trying to wrap my head around the boundaries of the OSGi runtime. My app, which is not build on OSGi, i.e. it's not running in an OSGi container, starts an OSGi container into which we deploy OSGi bundles at run time. Some of these bundles register services. Later, in our non-OSGi code, we obtain those services and use them.
I'm having trouble wrapping my feeble mind around the OSGi boundaries here. To be specific, when I obtain a service and invoke one of its methods, can I assume that all of the subsequent execution is executing within the OSGi container (Felix)? In other words, are dependencies in that code resolved via the OSGi modularity mechanisms? Or did I lose that OSGi management because I am using the service from non-OSGi code?
If my question seems founded in obvious mistaken assumptions about OSGi, please feel free to point them out.
Chad, to more effectively answer your question, I'd like to know a few things:
1) How exactly are you getting the service reference from an external application?
2) Is the external application a stand-alone application, or is it inside of a different container? If so, there are ways to make that happen.
The question you pose is interesting. Lets put it into a context. Lets assume you are able to get a reference to an OSGi service from Felix by an external application. When you use this service, you will be interacting with it via an interface. In that interface in OSGi, you will have import statements referenced which will be used in the method signatures of the interface and also in any final attributes. These import statements will have thier matching dependant libraries defined in your pom.xml file.
In order to use the service by an external application, you will need to publish an API ".jar" file that will contain the interface, and will reference the interfaces' dependancies. Your external application will need to use that API, and will likely have it assembled into your .war, .jar, or .ear file's lib directory. Because of this, none of your external application's dependancies can conflict with your API dependancies.
As long as you can use the API, then you're right, none of the SPI's dependencies matter. You can use Spring 3.0.4.RELEASE in your external app and still use Spring 2.5.6.SNAPSHOT in your OSGi application. As long as the API doesn't have any dependancies that conflict with the external application, you should be ok. The trick here is that you need to put your interfaces into a minimal .jar file as your API, and then put your implementation details into an SPI. Your external ap will use the API, and inside OSGI, you will use both the API and SPI.
Please let me know if this helps.
If you can get the service, then the dependencies are satisfied by definition, because bundles cannot provide services unless their dependencies are satisfied. Executing services on the outside doesn't really change anything.

Resources