Dynamic Target Requests in OSGi with DS

When I use a link in DS, I can specify a goal that will allow me to narrow down which instance of the service I want. The problem is that all the examples show static queries that must be executed during code execution. Is there a way to make a dynamic request (maybe pull a property from Configuration Admin)?

If DS does not support this, is there another OSGi dependency injection infrastructure (plan, iPojo, etc.) that will support this?

+6
source share
2 answers

You can always use the target link attribute to form the first level filter. If your binding method has a signature

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

Then you can run any dynamic filter on the map that contains the properties of the services. If the filter does not match, you can ignore this component (for now).

Alternatively, since the configuration of the component may include a target filter, you can change the configuration of the component to modify the target filter.

+7
source

I am using the following trick. If you specify the โ€œtargetโ€ attribute in the service link, but leave it as an empty string, then the component property with the same name but the suffix โ€œ.targetโ€ will be used at runtime.

In the example below, I select the JDBC source dynamically through the .cfg file in the Karaf container. The "datasourcefactory.target" property is automatically entered into the "target" attribute of the "datasourcefactory" link.

Caveat: I really don't know if this trick is officially supported or just the SCR Felix feature. I meant to look at it in the specification to see if it is mentioned ... +1 to any comment that clarifies its validity!

  @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" ) 
+5
source

Source: https://habr.com/ru/post/914370/


All Articles