Valid ways to interrupt an OSGi component from being activated - osgi

I have an OSGi component:
#Component(immediate=true)
public class SomeComponent implements SomeInterface {...}
Note that the component is immediate. Also, since the component class is implementing an interface, I understand that a service will be registered automatically upon (as part of the) activation of the component.
Now, I would like to do be able to dynamically interrupt the component activation and service registration if certain conditions are met. Throwing a 'ComponentException' in a component activator doesn't seem to do the job:
#Activate
public void activate() {
if (notReady)
throw new ComponentException("Component not ready");
}
Any suggestions? Thanks!

You cannot preempt the service registration which happens before activation. You would be better off with two components. One which is immediate with no service which decides whether to enable or disable the second component which has the service. This second component can be disabled by default.

Related

Why does the ConfigurationAdmin specification use its own eventing mechanism, as opposed to the EventAdmin?

I want to understand why the ConfigurationAdmin specification defines its own mechanism for dispatching events, instead of using the EventAdmin specification, which is also defined in the OSGi Compendium.
The ConfigurationAdmin specification mentions that it will send ConfigurationEvents to ConfigurationListeners registered in the service registry.
Listener for Configuration Events. When a ConfigurationEvent is fired, it is asynchronously delivered
to all ConfigurationListeners.
ConfigurationListener objects are registered with the Framework service registry and are notified
with a ConfigurationEvent object when an event is fired.
ConfigurationListener objects can inspect the received ConfigurationEvent.
This seems like it would be a fine candidate for the EventAdmin, given that the properties of the ConfigurationEvent are all primitive.
val event: Event = Event(Hashtable(mapOf<String, Any>(
"type" to CM_UPDATED,
"service.factoryPid" to "someFactoryPid.guid",
"service.pid" to "somePid.guid"
)))
#Component
class ConfigurationListener : EventHandler {
override fun handleEvent(event: Event) {
// ...
}
}
I'm designing some services which would make use of some sort of event handling mechanism. The choices I think I have are using the EventAdmin (provided in the Compendium), and rolling my own (like the ConfigurationAdmin).
I'd like to know what design decision was made that led the OSGi Alliance to create a separate event mechanism for the ConfigurationAdmin, instead of the already created event mechanism, provided by the EventAdmin, and if I need to consider the same factors when selecting my event mechanism.
It seems like duplicated work.
The EventAdmin can send events synchronously or asynchronously (sendEvent and postEvent), and already provides an interface to responding to events (EventHandler).
The ConfigurationAdmin sends ConfigurationEvents asynchronously or synchronously depending on the the interface used to respond to the event(ConfigurationListener, SynchronousConfigurationListener), rather than the method called.
One possibility I'd considered was that the OSGi Alliance didn't want to make the services defined in the Compendium, depend on other Compendium services, based on the fact that the ConfigurationAdmin has no problem depending on the Service registry, which is defined in Core.
This seems to line up in my mind with the understanding that services are not guaranteed to exist at runtime; therefore making ConfigurationAdmin depend on EventAdmin would equate to "You cannot use this optional service (ConfigurationAdmin) unless this other optional service (EventAdmin) is guaranteed to be in the runtime as well" which is kind of contradictory.
There are several reasons:
Configuration Admin was designed before Event Admin
A type safe event interface like Configuration Admin is easier to use than using properties
As you figured out, it is not nice if services depend on each other. Implementations should be able to freely chose services and not be artificially constrained.

JAX-RS: How to run a method on start (without servlets)

I have a JAX-RS (Jersey) server with which I register and bind my stuff.
I want to print a banner when the server starts up. I want to do this using the JAX-RS framework not the web server's platform (i.e., no Jetty, Netty, Thorntail, etc hooks).
I saw the following which mentions the tried and true Servlet way of doing things:
Jax rs: How can I run a method automatically everytime my server restarts? , but that does not work because I am not running a servlet container in my server so that lifecycle call is never made.
I figured there must be a JCA-ish type object that I can register with Application/ResourceConfig that has such a lifecycle call, but I am unable to even find any kind of list of the things you can actually register.
Not to complain (but I will), but I cannot decide if this is so difficult because when they moved the project to eclipse, they broke every hyperlink to the old official documentation or that it is simply so implicit, like Spring, that it only works by github'ing other people's code and realizing, 'oh, I did not know you could do that'.
Jersey has Event Listeners. You'll want to use the ApplicationEventListener and the ApplicationEvent.Type you'll probably want to listen for to print the banner is the INITIALIZATION_FINISHED
public class MyApplicationEventListener
implements ApplicationEventListener {
#Override
public void onEvent(ApplicationEvent event) {
switch (event.getType()) {
case INITIALIZATION_FINISHED:
printBanner();
break;
}
}
#Override
public RequestEventListener onRequest(RequestEvent requestEvent) {
return null;
}
}

Dependency Injection Android

I am not sure how to use Dependency Injection on Xamarin Android project solution. Currently my Android solution holds a reference to another class library solution. I have used Unity on my service layer and registered the container via WebApiConfig.cs.
My question is, how do i go about using Unity on Android side in order to run on start up, would be grateful if code was included. I dont want to new-up the container through main activity of Android. I want the container to register behind the process i.e. AppStart or Global asax where it does it for you for MVC apps. Is there a way to do it for Android? Also I noticed on Main Activity I am unable to create constructor. I guess this isnt possible but how do I go about holding object reference to my Class Library solution ? example that i attempted to do:
private IExample _ex;
MainActivity(IExample ex){
_ex = ex; //depedency Injection rather than newing it up
}
public void DoSomething(){
_ex.HelloWorld();
}
Is there a way to do it via Attribute ? Also for each of my layer do I need to install and create container in order to resolve current solution dependency ? or can I use container from android which would resolve all dependency in each layer as DDD architecture goes from outer to inner ?
In terms of setting up DI at startup you can create a custom Application implementation like so:
// Must include this attribute so that Android knows we want to use this as our Application implementation
[Application(Icon = "#drawable/Icon", Label = "#string/ApplicationName")]
public class MyApplication : Application
{
public override void OnCreate()
{
base.OnCreate();
// Do your DI initialization/registration here
}
}
I'm not sure exactly what you mean by not being able to create a constructor on the main activity. You can create constructors for any activity you feel like. You don't always see it though because people tend to put their initialization logic in OnCreate.

conditional disposing of objects using DI framework (Ninject)

I have the following code
public class MyService : IMyService
{
private readonoly IUnitOfWork _unitOfWork;
public MyService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
}
//This code is used by web client
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IMyService>().To<MyService>();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
}
I have a web and windows service client both use the "MyService" class. I want to dispose the "unit of work" at the end of HTTP request if the client is web, where as if the client is a windows service, I want to dispose the unit of work after every database call. how to achieve that? can I add an extra flag to the MyService constructor, to identify the client, but then how to modify the above code to pass a hardcoded value to that parameter when mapping the concrete types to the interfaces?
You will probably have some sort of MyServiceRunner in yourr Windows service that calls your MyService. This class is Windows service specific and this would be the place to explicitly control the lifetime of the IUnitOfWork. Or you can write a decorator for MyService that controls the unit of work.
A few things to note. Although you can reuse the IUnitOfWork on a per-web-request basis, DO NOT Commit the unit of work at the end of the web request, but explicitly do this after a service (succesfully) executed. Since the scope of your IUnitOfWork is very different in the Windows Service, you probably need some explicit code or explicit registration to handle this. However, make sure that your MyService is oblivious to this: It shouldn't need to care.
If you have many services that you want to call in the Windows Service, you might want to think about applying the command/handler pattern for handling business logic. You can read more about it here.

OSGi: Is it valid to register services within a declarative service component activation method?

This is a duplicate of another question, but copying from the other one:
I've run into an issue with Felix SCR where I get the message:
ServiceFactory.getService() resulted in a cycle
The reason this appers to be occuring is because within an activation method, call it ServiceAImpl (which provides ServiceA), the service registers another service, call it ServiceB.
I have another service component, call it ServiceCImpl, which depends on both ServiceA and ServiceB. By ServiceAImpl registering ServiceB, ServiceCImpl has become satisfied and within the same call to activate ServiceAImpl, the ServiceCImpl binding methods are called. When the binding method for ServiceA is called, the cycle is detected and the component fails to initialize.
Maybe there is a way to allow the SCR to wait to bind the ServiceCImpl or maybe I need to be registering ServiceB differently?
I guess what doesn't make sense is why the Felix SCR will activate ServiceCImpl within the activation method of ServiceAImpl. I wouldn't think that ServiceCImpl would be considered satisfied until after the activation method has exited. Perhaps this is an issue of using declarative services while still registering services directly with the framework?
Haven't tried other SCR implementations, like Equinox's version, but I might try that to see if there is a difference, but maybe somebody knows if this is a OSGi thing or a Felix thing?
Additional Info: As to why ServiceB is not a service component...ServiceA actually has a service reference of 0..n for another service, call it ServiceD. Everytime a ServiceD interface is provided by a component, a ServiceB is registered using the same service object. Normally the same provider of ServiceD could provide ServiceB, but the idea is to make the overall interface for developers more simplistic so they don't have to provide multiple service interfaces (also, ServiceB has some properties that are set automatically that would have to be done manually and possibly could be done incorrectly).
The reason this appears to be happening is that ServiceAImpl is a delayed component that has already been loaded so ServiceA is in fact already resgistered before the component is activated. However, when another component comes along that needs ServiceA, this causes ServiceAImpl to be activated. Part of the activation process of ServiceAImpl is to register ServiceB which immediately causes ServiceCImpl to be activated. A change was made in FELIX-2368 to immediately activate a component by making most SCR operations synchronous.
A workaround is to make ServiceAImpl an immediate component which isn't desired as it shouldn't be activated if nothing needs the service. In this case, the activation method is completed when the component is loaded and by the time it is needed and bound to another component there is no problem.
I've tried to recreate this scenario with a small set of test bundles and the ProSyst OSGi FW.
However, if I register a service with DS, I am not able to register an other service from within the activate() method. If I just use DS to obtain services, I can register services as usual. So there is probably really a problem with DS/SCR...
Example:
public class ServiceAImpl implements ServiceA, ServiceB, ManagedService {
public void activate(ComponentContext _context) {
_context.getBundleContext().registerService(
ManagedService.class.getName(),
this,
null);
_context.getBundleContext().registerService(
ServiceB.class.getName(),
this,
null);
}
#Override
public void doA() {
System.out.println("Doing A Stuff");
}
#Override
public void doB() {
System.out.println("Doing B Stuff");
}
#Override
public void updated(Dictionary arg0) throws ConfigurationException {
}
}
This class will register 2 Services (ServiceB, ManagedService) with this bnd. file:
Private-Package: org.test.impl
Service-Component: org.test.impl.ServiceAImpl
Bundle-Category: test
but only 1 service (ServiceA) with this sample:#
Private-Package: org.test.impl
Service-Component: org.test.impl.ServiceAImpl;provide:=org.test.ServiceA
Bundle-Category: test
So probably you should/have to try to register the services either via DS/SCR or the "classic way" via bundle context.

Resources