Dynamic target queries in OSGi with DS

百般思念 提交于 2019-12-05 07:45:33

You can always use the target attribute of the reference to peform a first level filter. The if your bind method has the signature

void <method-name>(<parameter-type>, Map);

Then you can run any dynamic filter over the Map which contains the services properties. If the filter does not match, you can ignore that component (for the time being.)

In the alternate, since the component's configuration can contain the reference's target filter, you can modify the component's configuration to alter the target filter.

I use the following trick. If you specify a "target" attribute on the service reference but leave its value as the empty string, then a component property with the same name but a ".target" suffix will be used at runtime.

In the example below, I select my JDBC source dynamically via a .cfg file in my Karaf container. The "datasourcefactory.target" property is injected automatically into the "target" attribute of the "datasourcefactory" reference.

Caveat: I don't actually know if this trick is officially supported or just a Felix SCR feature. I've been meaning to look this up in the spec to see if it's mentioned... +1 to any comment that clarifies its legality!

    @Component(
            name = "...",
            specVersion = "1.1",
            policy = ConfigurationPolicy.REQUIRE,
            metatype = true
    )
    @Property(name = "dataSourceFactory.target",
            value = "",
            label = "dataSourceFactory target",
            description = "An OSGi service filter to select the data source provider. "+
                    "For example: '(&(osgi.jdbc.driver.name=derby)(objectClass=org.osgi.service.jdbc.DataSourceFactory))' where 'derby' is the important bit and the rest is boilerplate. "+
                    "See DataSourceFactory.OSGI_JDBC_DRIVER_(NAME,CLASS,VERSION)."
    )
    @Reference(
            name = "dataSourceFactory",
            referenceInterface = org.osgi.service.jdbc.DataSourceFactory.class,
            cardinality = ReferenceCardinality.MANDATORY_UNARY,
            target = "", // must be overwritten by configuration property named "dataSourceFactory.target"
            bind = "bindDataSourceFactory",
            unbind = "unbindDataSourceFactory"
    )
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!