You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@karaf.apache.org by Christian Schneider <ch...@die-schneider.net> on 2016/02/18 13:09:34 UTC

[Discuss] How to handle config dependent service references using DS?

I am currently working on the migration of decanter to DS: 
https://issues.apache.org/jira/browse/KARAF-4344

Most of the modules translate to DS quite naturally.  We have two module 
though that are a bit special - the jms and jdbc appenders.

Lets take jms:
The connection factory is specified in the config as 
"connection.factory.name" with a default of "jms/decanter".

In the Activator a ServiceTracker is created that tries to bind the 
ConnectionFactory service using a filter of:
"(&(" + Constants.OBJECTCLASS + "=" + ConnectionFactory.class.getName() 
+ ")(|(osgi.jndi.service.name=" + cfName + ")(name=" + cfName + 
")(service.id=" + cfName + ")))";
where cfName is the config value specified above.

These kinds of configuration dependent references are difficult to 
implement in both blueprint and declarative services.

I see two ways to implement this:

1. Create a ServiceTracker inside the activate method of the DS 
component with a fitler determined by the config.
This allows to keep the config format as is but the solution is quite 
verbose and completely skips the DS mechanisms.
So for example the component will be active even if the 
ConnectionFactory service is not found. Inside it would then do a 
special internal processing to only really activate itself
when the service is present.

2. Use a generic DS feature to override a target filter
In this case we reference the ConnectionFactory service using standard 
annoations:
  @Reference(target="(osgi.jndi.service.name=jms/decanter)")
     public void setConnectionFactory(ConnectionFactory 
connectionFactory) ...
Target allows to set the default OSGi filter.
DS then allows to override this filter using a configuration property 
name like the method + ".target".
ConnectionFactory.target=(name=myjms)
This approach needs a change in the way the module is configured but is 
much simpler to implement.
It also allows to use the scr:details command to see what service the 
Component is looking for. So this makes the system easier to diagnose by 
the administrator.

I prefer the solution 2. The change in the configuration format should 
be ok in a minor release if we properly announce it in the release notes.
I implemented it in a branch so you can look into it:
https://git-wip-us.apache.org/repos/asf?p=karaf-decanter.git;h=8c3e004

I am open to other solutions of course.

Christian




-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Re: [Discuss] How to handle config dependent service references using DS?

Posted by Achim Nierbeck <bc...@googlemail.com>.
Hi,

finally had the time to take a closer look at it.
Solution 2 sound good to me.
Regarding, the question if this change is ok for a minor release.
>From my point of view it's ok, as long as an old configuration still would
work, even though
an old entry might not be respected. It shouldn't fail on starting
decanter.

regards, Achim







2016-02-18 13:38 GMT+01:00 Jean-Baptiste Onofré <jb...@nanthrax.net>:

> Hi Christian,
>
> As discussed on IRC, I'm in favour of 2.
>
> Yes it introduces a difference with previous cfg file content (but it's
> not a big deal as we changed version from 1.0.x to 1.1.x), maybe not as
> easier to read for users as "plain" name, but very convenient.
>
> Regards
> JB
>
>
> On 02/18/2016 01:09 PM, Christian Schneider wrote:
>
>> I am currently working on the migration of decanter to DS:
>> https://issues.apache.org/jira/browse/KARAF-4344
>>
>> Most of the modules translate to DS quite naturally.  We have two module
>> though that are a bit special - the jms and jdbc appenders.
>>
>> Lets take jms:
>> The connection factory is specified in the config as
>> "connection.factory.name" with a default of "jms/decanter".
>>
>> In the Activator a ServiceTracker is created that tries to bind the
>> ConnectionFactory service using a filter of:
>> "(&(" + Constants.OBJECTCLASS + "=" + ConnectionFactory.class.getName()
>> + ")(|(osgi.jndi.service.name=" + cfName + ")(name=" + cfName +
>> ")(service.id=" + cfName + ")))";
>> where cfName is the config value specified above.
>>
>> These kinds of configuration dependent references are difficult to
>> implement in both blueprint and declarative services.
>>
>> I see two ways to implement this:
>>
>> 1. Create a ServiceTracker inside the activate method of the DS
>> component with a fitler determined by the config.
>> This allows to keep the config format as is but the solution is quite
>> verbose and completely skips the DS mechanisms.
>> So for example the component will be active even if the
>> ConnectionFactory service is not found. Inside it would then do a
>> special internal processing to only really activate itself
>> when the service is present.
>>
>> 2. Use a generic DS feature to override a target filter
>> In this case we reference the ConnectionFactory service using standard
>> annoations:
>>   @Reference(target="(osgi.jndi.service.name=jms/decanter)")
>>      public void setConnectionFactory(ConnectionFactory
>> connectionFactory) ...
>> Target allows to set the default OSGi filter.
>> DS then allows to override this filter using a configuration property
>> name like the method + ".target".
>> ConnectionFactory.target=(name=myjms)
>> This approach needs a change in the way the module is configured but is
>> much simpler to implement.
>> It also allows to use the scr:details command to see what service the
>> Component is looking for. So this makes the system easier to diagnose by
>> the administrator.
>>
>> I prefer the solution 2. The change in the configuration format should
>> be ok in a minor release if we properly announce it in the release notes.
>> I implemented it in a branch so you can look into it:
>> https://git-wip-us.apache.org/repos/asf?p=karaf-decanter.git;h=8c3e004
>>
>> I am open to other solutions of course.
>>
>> Christian
>>
>>
>>
>>
>>
> --
> Jean-Baptiste Onofré
> jbonofre@apache.org
> http://blog.nanthrax.net
> Talend - http://www.talend.com
>



-- 

Apache Member
Apache Karaf <http://karaf.apache.org/> Committer & PMC
OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer &
Project Lead
blog <http://notizblog.nierbeck.de/>
Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>

Software Architect / Project Manager / Scrum Master

Re: [Discuss] How to handle config dependent service references using DS?

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
Hi Christian,

As discussed on IRC, I'm in favour of 2.

Yes it introduces a difference with previous cfg file content (but it's 
not a big deal as we changed version from 1.0.x to 1.1.x), maybe not as 
easier to read for users as "plain" name, but very convenient.

Regards
JB

On 02/18/2016 01:09 PM, Christian Schneider wrote:
> I am currently working on the migration of decanter to DS:
> https://issues.apache.org/jira/browse/KARAF-4344
>
> Most of the modules translate to DS quite naturally.  We have two module
> though that are a bit special - the jms and jdbc appenders.
>
> Lets take jms:
> The connection factory is specified in the config as
> "connection.factory.name" with a default of "jms/decanter".
>
> In the Activator a ServiceTracker is created that tries to bind the
> ConnectionFactory service using a filter of:
> "(&(" + Constants.OBJECTCLASS + "=" + ConnectionFactory.class.getName()
> + ")(|(osgi.jndi.service.name=" + cfName + ")(name=" + cfName +
> ")(service.id=" + cfName + ")))";
> where cfName is the config value specified above.
>
> These kinds of configuration dependent references are difficult to
> implement in both blueprint and declarative services.
>
> I see two ways to implement this:
>
> 1. Create a ServiceTracker inside the activate method of the DS
> component with a fitler determined by the config.
> This allows to keep the config format as is but the solution is quite
> verbose and completely skips the DS mechanisms.
> So for example the component will be active even if the
> ConnectionFactory service is not found. Inside it would then do a
> special internal processing to only really activate itself
> when the service is present.
>
> 2. Use a generic DS feature to override a target filter
> In this case we reference the ConnectionFactory service using standard
> annoations:
>   @Reference(target="(osgi.jndi.service.name=jms/decanter)")
>      public void setConnectionFactory(ConnectionFactory
> connectionFactory) ...
> Target allows to set the default OSGi filter.
> DS then allows to override this filter using a configuration property
> name like the method + ".target".
> ConnectionFactory.target=(name=myjms)
> This approach needs a change in the way the module is configured but is
> much simpler to implement.
> It also allows to use the scr:details command to see what service the
> Component is looking for. So this makes the system easier to diagnose by
> the administrator.
>
> I prefer the solution 2. The change in the configuration format should
> be ok in a minor release if we properly announce it in the release notes.
> I implemented it in a branch so you can look into it:
> https://git-wip-us.apache.org/repos/asf?p=karaf-decanter.git;h=8c3e004
>
> I am open to other solutions of course.
>
> Christian
>
>
>
>

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com