Sharing custom service between bundles

asked 2016-06-01 07:39:04 -0700

medvedmike gravatar image

updated 2016-06-01 07:43:35 -0700

I trying to create my own service and share it between two bundles but have some problems. There are two bundles A and B. Service interface defined in bundle A. Bundle B implements service and define it in own yang model and in xml configuration. Bundle A starts first. I want to detect moment when bundle B starts and get service from it in bundle A. In bundle A module factory there is subscription for bundle events and moment of loading B detecting fine. But in provided services list there is no target service interface (only odl ModuleFactory)

Bundle A service interface:

public interface SomeCustomService  {/*...*/}

Bundle A yang module:

identity some-custom-service {
    base "config:service-type";
    config:java-class "foo.bar.SomeCustomService";
}
identity a-impl {
    base config:module-type;
    config:java-name-prefix A;
}

Bundle B service implementation:

public class SomeCustomServiceImpl implements SomeCustomService, AutoCloseable { /*...*/ }

Bundle B yang module:

identity b-identity {
    base config:module-type;
    config:provided-service a-prefix:some-custom-service;
    config:java-name-prefix B;
}

Bundle B configuration:

<snapshot>
    <configuration>
        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                <module>
                    <type xmlns:prefix="urn:b-module">prefix:a-module</type>
                    <name>b-module</name>
                </modules>
            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                <service>
                    <type xmlns:a="urn:a-module">a:some-custom-service</type>
                    <instance>
                        <name>b-some-custom-service</name>
                        <provider>/modules/module[type='b-module'][name='b-module']</provider>
                    </instance>
                </service>
            </services>
        </data>
    </configuration>

    <required-capabilities>
        <capability>urn:a-module?module=a-module&revision=2016-04-27</capability>
        <capability>urn:b-module?module=b-module&revision=2016-04-27</capability>
    </required-capabilities>
</snapshot>

Bundle A module factory implementation:

public class AModuleFactory extends foo.bar.AbstractAModuleFactory {

    private BundleListener bundleListener = event -> {
        try {
            switch (event.getType()) {
                case BundleEvent.STARTED:
                    log.info("Bundle {} started", event.getBundle().getSymbolicName());
                    break;
            }
        } catch (Exception e) {
            log.warn("Notification handling error", e);
        }
    };

    @Override
    public AModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
                                                    BundleContext bundleContext) {
        AModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
        bundleContext.addBundleListener(bundleListener); 
        return module;
    }
}

In case BundleEvent.STARTED: case label call of method event.getBundle().getRegisteredServices() return array with only one service interface ModuleFactory instead both ModuleFactory and SomeCustomService.

edit retag flag offensive close merge delete

Comments

Does anyone have any ideas?

medvedmike ( 2016-06-02 00:33:01 -0700 )edit