Umesh Rajani
Umesh Rajani

Reputation: 139

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.

Upvotes: 1

Views: 1279

Answers (2)

BJ Hargrave
BJ Hargrave

Reputation: 9374

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.

Upvotes: 1

Frank Lee
Frank Lee

Reputation: 2748

I think the problem is that, because those components are optional, they may be present at activation and they may not, if an optional reference changes it won't be re-activated.

I'd say try to implement the registration code in the bind / unbind methods of the components, in this case that is the only place where you can 'notice' the change.

Upvotes: 1

Related Questions