Search code examples
osgiapache-felixdeclarative-servicesosgi-ds

OSGi-DS: Optional reference to required service in DS Component, is not really dynamically updatable


I want to start DS component which has many services are optional, if some service is not up then these component is not getting activated. So I set cardinality of these optional service as Optional so if these optional service is not available then also target component can be activated.

But now problem is if I change configuration of any of these optional service to valid and so service becomes available but it won't reflect in that target component

@Component(immediate = true, configurationPolicy = ConfigurationPolicy.IGNORE,name="directory.comp")
public class DirectoryControllers
{
    @Reference(policy=ReferencePolicy.DYNAMIC)
        private volatile IZimbra zimbra;
        @Reference(policy=ReferencePolicy.DYNAMIC,cardinality=ReferenceCardinality.OPTIONAL)
        private volatile IOpenDJ opendj;
        @Reference(policy=ReferencePolicy.DYNAMIC,cardinality=ReferenceCardinality.OPTIONAL)
        private volatile IOpenIDM openidm;

        private ServletRegistration _registration;

        @Activate void activate(BundleContext bc) throws ServletException, NamespaceException
        {
             AppProvisioners provisioners=new AppProvisioners(zimbra,openidm,opendj);
            _registration = ServletRegistration.register(
                bc, _httpService, "/middleware",
                new ProvisioningController(_db,provisioners), 
                new UserEnrollmentController(_db,provisioners)
            );
        }
}

Here, zimbra component is not optional so whenever I change configuration it will be affected in DirectoryControllers component, but same is not true for openidm,opendj component, of course it is optional but on changing their configuration valid, it is not affected in DirectoryControllers component

I have also tried bind/unbind:

private volatile IOpenIDM openidm;

@Reference(name = "openidm.service", service = IOpenIDM.class, cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC, unbind = "unbindOpenIDMService")
public void bindOpenIDMService(IOpenIDM openidm) {
        this.openidm = openidm;
}

public void unbindOpenIDMService(IOpenIDM openidm) {
        this.openidm = null;
}

Am I missing anything which leads to this issue?

Thank you.


Solution

  • I think you need to set the policyOption for the reference to ReferencePolicyOption.GREEDY. The default for policyOption is ReferencePolicyOption.RELUCTANT which will not reactivate the component when the optional service becomes available.