You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Bengt Rodehav <be...@rodehav.com> on 2013/10/02 14:42:52 UTC

iPOJO and dynamic requires

I'm creating a dynamic processing component using iPOJO and Camel. The idea
is to dynamically specify (via config admin) a number of processor id's. In
runtime I want to find the matching processors (the processors are Camel
processors published as OSGi services) with the correct id.

E g if I specify a list of services to {A,B} (FileInstall recognizes this
as a list). I want to require those services in order for my iPojo instance
to become valid. It was much harder than I thought.

I've tried something like:

  @Property(name = "processors", mandatory = false, value = "")
  public void setProcessors(String[] theProcessorIds) {
    mProcessorIds = theProcessorIds;
    updateProcessorFilter();
  }

  @Requires
  private Processor[] mProcessors;

The idea is that whenever the configuration property "processors" is
updated, I dynamically update the ldap filter on the dependency
mProcessors. I've used this approach before and it has worked when using a
single dependency (not an array).

The problem is that I want to specifically require each specified
processor. In the example above, I require one processor with id=A AND one
processor with id=B. It's not enough with anyone of them since I want to
invoke them one after another.

Can I use a filter for this? I've been thinking of something like this:

(|(processorId=A)(processorId=B))

This would match both my processors but if one of them were missing my
instance would still become valid which I don't want.

/Bengt

Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
Aha, I had completely missed that. Thanks for the info, I now have a lot of
@Controller's that need to be changed to @ServiceController's.

/Bengt


2013/10/3 Clement Escoffier <cl...@gmail.com>

> Hi,
>
> On 3 oct. 2013, at 12:09, Bengt Rodehav <be...@rodehav.com> wrote:
>
> > OK - thanks. I can skip the @Modified then.
> >
> > I've had some more problems unfortunately. It seems like, although I use
> a
> > @Controller, which has the value "false", my instance still becomes
> valid.
> > Shortly thereafter it becomes invalid again but this "false start" gives
> me
> > problems.
> >
> > It's like the @Controller doesn't take effect immediately but only after
> a
> > while. Does this has anything to do with the fact that I set
> > "immediate=true" on my @Component?
> >
>
> You should use the service controller and set the default value to false.
> Thus, the service exposed by your instance will not be published until you
> assign the field to true. When, I say default value, I mean:
>
> @ServiceControler(value=false)
> private boolean m_controller;
>
>
> The @ServiceController controls the exposition of the services exposed by
> your instance without changing the instance state. The @Controller impacts
> the instance's state. It should only be used when something 'terrible'
> happen, and the instance cannot become valid again without a restart or a
> reconfiguration.
>
> Regards,
>
> Clement
>
>
>
>
> > /Bengt
> >
> >
> > 2013/10/3 Clement Escoffier <cl...@gmail.com>
> >
> >> Hi,
> >>
> >> On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:
> >>
> >>> A question related to my workaround Clement.
> >>>
> >>> To make sure that my lifecycle controller's value is up to date I need
> to
> >>> recalculate it every time the array of required services change. My
> code
> >>> for this looks as follows:
> >>>
> >>> @Requires(optional = true, id = "processors")
> >>> private IOrchestrationProcessor[] mProcessors;
> >>>
> >>> @Bind(id = "processors")
> >>> public void bindProcessors() {
> >>>   updateAggregateValid();
> >>> }
> >>>
> >>> @Unbind(id = "processors")
> >>> public void unbindProcessors() {
> >>>   updateAggregateValid();
> >>> }
> >>>
> >>> @Modified(id = "processors")
> >>> public void modifiedProcessors() {
> >>>   updateAggregateValid();
> >>> }
> >>>
> >>> The function updateAggregateValid() checks if all my configurable
> >>> requirements are met and then sets the controller value to true,
> >> otherwise
> >>> to false. I'm not sure when the @Modified method is called. At first it
> >>> seemed like @Modified would be the only callback I needed but it does
> not
> >>> seem to be called on "unbind". Now I suspect that it is enough with
> @Bind
> >>> and @Unbind - @Modified seems unnecessary.
> >>>
> >>> What callbacks do I need to handle in order to react on all changes to
> >> the
> >>> list of required services?
> >>>
> >>
> >> Bind and Unbind are covering your case. The modified callbacks mean that
> >> one service has been updated (its service properties have changed) but
> it
> >> still matches the filter. In your case, it's not relevant.
> >>
> >> Clement
> >>
> >> PS: `still matches the filter` means, from the interceptor perspective,
> >> has been accepted by all tracking interceptors, including the filter,
> >> managing the dependency.
> >>
> >>
> >>> /Bengt
> >>>
> >>>
> >>>
> >>>
> >>> 2013/10/2 Bengt Rodehav <be...@rodehav.com>
> >>>
> >>>> Thanks for your detailed response Clement!
> >>>>
> >>>> Sounds very interesting indeed although the fact that I can't change
> the
> >>>> optionality sounds like a show stopper to me. In my case the list of
> >>>> services to require can be >= 0. If, using config admin, I specify an
> >> empty
> >>>> list then the service dependency must be optional. If the list is
> >> non-empty
> >>>> then it must not be optional. I can't see how I can solve this using
> the
> >>>> interceptors (although I haven't read the documentation yet :-)).
> >>>>
> >>>> /Bengt
> >>>>
> >>>>
> >>>> 2013/10/2 clement escoffier <cl...@gmail.com>
> >>>>
> >>>>> Sent from my iPhone
> >>>>>
> >>>>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
> >>>>>>
> >>>>>> Interesting. Do you think it would also be possible to do an
> >>>>> all-or-nothing
> >>>>>> approach? E g if I want to require A and B, I could check if both A
> >> and
> >>>>> B
> >>>>>> are available. If not, I would make the list empty thus making my
> >>>>> instance
> >>>>>> invalid? Or can I just say that the dependency is unresolved without
> >>>>> having
> >>>>>> to change the list?
> >>>>>
> >>>>> Yes you can to that. I would say that the easiest way is to implement
> >>>>> a ranking interceptor that returns an empty array until both services
> >>>>> are there. When both are there, it returns both.
> >>>>>
> >>>>> Notice that returning an empty array invalidates the dependency. For
> >>>>> the instance it would just means : no services.
> >>>>>
> >>>>>>
> >>>>>> BTW I did experiment a little with dynamically changing the
> >> "optionable"
> >>>>>> property of the requires dependency using the dependency manager. I
> >>>>> never
> >>>>>> did get that to work. It always stayed at the same value it got
> >> through
> >>>>> the
> >>>>>> Requires annotation. Is that as designed or a bug?
> >>>>>>
> >>>>>
> >>>>> Optionality cannot be changed, however the filter can. I can't
> >>>>> remember the exact reason for that.
> >>>>>
> >>>>>> I currently did a workaround using the life cycle controller as
> >> adviced
> >>>>> by
> >>>>>> Richard. Whenever anything changes that could affect the validity of
> >> the
> >>>>>> instance I recalculate the life cycle controller value to reflect
> >> that.
> >>>>> For
> >>>>>> instance if the list of dependencies change I recalculate and check
> if
> >>>>> all
> >>>>>> my required services are in the list. If not I set the controller
> >> value
> >>>>> to
> >>>>>> false.
> >>>>>> It works but the code is not very nice and easy to understand. It'll
> >>>>> have
> >>>>>> to do for now.
> >>>>>>
> >>>>>
> >>>>> I did like this several times and was never happy of the result,
> >>>>> especially it may mix, in your component code, business logic with
> >>>>> higher-level rules and data. Very hard to maintain on the long term,
> >>>>> unclear ad likely spaghetti-like. That's one of the reason we came up
> >>>>> with the interceptors.
> >>>>>
> >>>>>
> >>>>>> Clement, is the 1.10.x version released? I'm on a pretty old version
> >> and
> >>>>>> should probably upgrade. Also, is there any documentation regarding
> >> the
> >>>>>> interceptors you mentioned?
> >>>>>
> >>>>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
> >>>>> complete, bug-fix complete, lacks some tests and documentation). We
> >>>>> plan to release it next week.
> >>>>>
> >>>>> The good news is that it includes the interceptor documentation.
> >>>>>
> >>>>> Clement
> >>>>>
> >>>>>
> >>>>>> /Bengt
> >>>>>>
> >>>>>>
> >>>>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
> >>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> Not sure it would meet your requirements, but in the 1.10.x, we
> added
> >>>>>>> service dependency interceptors. Interceptors are external entities
> >>>>>>> involved in the service resolution. We have 3 types on
> interceptors:
> >>>>>>>
> >>>>>>> - tracking interceptors allow hiding services, or selecting the set
> >> of
> >>>>>>> services seen by the service dependency (the LDAP filter is a
> >> tracking
> >>>>>>> interceptor)
> >>>>>>> - ranking interceptors can change the order of the services (the
> >>>>>>> comparator is a ranking interceptor)
> >>>>>>> - binding interceptors can change the injected service objects (to
> be
> >>>>> used
> >>>>>>> with caution ;-))
> >>>>>>>
> >>>>>>> You can, without too much effort, write an interceptor that will
> >> shape
> >>>>> the
> >>>>>>> processor list as you want.
> >>>>>>>
> >>>>>>> As said above, interceptors are external entities. Actually, they
> are
> >>>>>>> services with a special 'target' property indicating in which
> >>>>> dependencies
> >>>>>>> they want to be involved. So, an interceptor can select one very
> >>>>> specific
> >>>>>>> dependency, all dependencies of an instance, all dependencies
> >>>>> targeting a
> >>>>>>> specific interface…
> >>>>>>>
> >>>>>>> Unfortunately, there is a long overdue issue about interceptors:
> >>>>>>> FELIX-4136 Document service dependency interceptors.
> >>>>>>>
> >>>>>>> Best regards,
> >>>>>>>
> >>>>>>> Clement
> >>>>>>>
> >>>>>>>
> >>>>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com>
> wrote:
> >>>>>>>>
> >>>>>>>> Thanks for your reply Richard.
> >>>>>>>>
> >>>>>>>> I am using a lifecycle controller already to make it possible to
> >>>>>>>> enable/disable my services via a GUI. I'll see if I can use it for
> >>>>> this
> >>>>>>>> purpose.
> >>>>>>>>
> >>>>>>>> I've also tried the following approach: Keep track of all possible
> >>>>>>> services
> >>>>>>>> that expose the interface I'm intererested in as follows:
> >>>>>>>>
> >>>>>>>> @Requires(optional = true)
> >>>>>>>> private IOrchestrationProcessor[] mProcessors;
> >>>>>>>>
> >>>>>>>> In runtime, when my service is being activated (prior to creating
> >> the
> >>>>>>> camel
> >>>>>>>> route) I check to see if all required processors exist, if not I
> >>>>> throw an
> >>>>>>>> exception. Unfortunately I have no control of in what order the
> >>>>> services
> >>>>>>>> will be activated so its hard to ever get the camel route created
> >> this
> >>>>>>> way.
> >>>>>>>> A lot of the time a "required" services is activated a bit later.
> >>>>>>>>
> >>>>>>>> /Bengt
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
> >>>>>>>>>>
> >>>>>>>>>> I'm creating a dynamic processing component using iPOJO and
> Camel.
> >>>>> The
> >>>>>>>>>> idea
> >>>>>>>>>> is to dynamically specify (via config admin) a number of
> processor
> >>>>>>> id's.
> >>>>>>>>>> In
> >>>>>>>>>> runtime I want to find the matching processors (the processors
> are
> >>>>>>> Camel
> >>>>>>>>>> processors published as OSGi services) with the correct id.
> >>>>>>>>>>
> >>>>>>>>>> E g if I specify a list of services to {A,B} (FileInstall
> >> recognizes
> >>>>>>> this
> >>>>>>>>>> as a list). I want to require those services in order for my
> iPojo
> >>>>>>>>>> instance
> >>>>>>>>>> to become valid. It was much harder than I thought.
> >>>>>>>>>>
> >>>>>>>>>> I've tried something like:
> >>>>>>>>>>
> >>>>>>>>>> @Property(name = "processors", mandatory = false, value = "")
> >>>>>>>>>> public void setProcessors(String[] theProcessorIds) {
> >>>>>>>>>>  mProcessorIds = theProcessorIds;
> >>>>>>>>>>  updateProcessorFilter();
> >>>>>>>>>> }
> >>>>>>>>>>
> >>>>>>>>>> @Requires
> >>>>>>>>>> private Processor[] mProcessors;
> >>>>>>>>>>
> >>>>>>>>>> The idea is that whenever the configuration property
> "processors"
> >> is
> >>>>>>>>>> updated, I dynamically update the ldap filter on the dependency
> >>>>>>>>>> mProcessors. I've used this approach before and it has worked
> when
> >>>>>>> using a
> >>>>>>>>>> single dependency (not an array).
> >>>>>>>>>>
> >>>>>>>>>> The problem is that I want to specifically require each
> specified
> >>>>>>>>>> processor. In the example above, I require one processor with
> id=A
> >>>>> AND
> >>>>>>> one
> >>>>>>>>>> processor with id=B. It's not enough with anyone of them since I
> >>>>> want
> >>>>>>> to
> >>>>>>>>>> invoke them one after another.
> >>>>>>>>>>
> >>>>>>>>>> Can I use a filter for this? I've been thinking of something
> like
> >>>>> this:
> >>>>>>>>>>
> >>>>>>>>>> (|(processorId=A)(processorId=**B))
> >>>>>>>>>>
> >>>>>>>>>> This would match both my processors but if one of them were
> >> missing
> >>>>> my
> >>>>>>>>>> instance would still become valid which I don't want.
> >>>>>>>>>
> >>>>>>>>> I don't think there is anyway to do what you want. This is
> >>>>> essentially
> >>>>>>> an
> >>>>>>>>> "N cardinality" requirement, where you want to say that you
> require
> >>>>>>>>> specifically N of something. Such requirements had been discussed
> >>>>> over
> >>>>>>> the
> >>>>>>>>> years for Service Binder, Declarative Services, etc., but we
> could
> >>>>> never
> >>>>>>>>> agree on their usefulness or how to do them, so we just left it
> as
> >>>>> it is
> >>>>>>>>> now (i.e., optional, at least one...).
> >>>>>>>>>
> >>>>>>>>> Other than adding some sort of threshold to service
> dependencies, I
> >>>>>>> don't
> >>>>>>>>> see this happening. You could potentially create an iPOJO
> lifecycle
> >>>>>>>>> controller that would keep your component invalid until it
> matched
> >>>>> the
> >>>>>>>>> required number of services (if you can get this information in
> the
> >>>>>>>>> handler)...or perhaps write/extend the service dependency
> handler.
> >>>>>>>>>
> >>>>>>>>> -> richard
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>> /Bengt
> >>>>>>>
> >>>>>
> >>
> ------------------------------**------------------------------**---------
> >>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
> >>>>>>> users-unsubscribe@felix.apache.org>
> >>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>>
> >>>>>>>
> >>>>>>>
> ---------------------------------------------------------------------
> >>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>>
> >>>>>>>
> >>>>>
> >>>>> ---------------------------------------------------------------------
> >>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>
> >>>>>
> >>>>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: iPOJO and dynamic requires

Posted by Clement Escoffier <cl...@gmail.com>.
Hi,

On 3 oct. 2013, at 12:09, Bengt Rodehav <be...@rodehav.com> wrote:

> OK - thanks. I can skip the @Modified then.
> 
> I've had some more problems unfortunately. It seems like, although I use a
> @Controller, which has the value "false", my instance still becomes valid.
> Shortly thereafter it becomes invalid again but this "false start" gives me
> problems.
> 
> It's like the @Controller doesn't take effect immediately but only after a
> while. Does this has anything to do with the fact that I set
> "immediate=true" on my @Component?
> 

You should use the service controller and set the default value to false. Thus, the service exposed by your instance will not be published until you assign the field to true. When, I say default value, I mean:

@ServiceControler(value=false)
private boolean m_controller;


The @ServiceController controls the exposition of the services exposed by your instance without changing the instance state. The @Controller impacts the instance's state. It should only be used when something 'terrible' happen, and the instance cannot become valid again without a restart or a reconfiguration.

Regards,

Clement




> /Bengt
> 
> 
> 2013/10/3 Clement Escoffier <cl...@gmail.com>
> 
>> Hi,
>> 
>> On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:
>> 
>>> A question related to my workaround Clement.
>>> 
>>> To make sure that my lifecycle controller's value is up to date I need to
>>> recalculate it every time the array of required services change. My code
>>> for this looks as follows:
>>> 
>>> @Requires(optional = true, id = "processors")
>>> private IOrchestrationProcessor[] mProcessors;
>>> 
>>> @Bind(id = "processors")
>>> public void bindProcessors() {
>>>   updateAggregateValid();
>>> }
>>> 
>>> @Unbind(id = "processors")
>>> public void unbindProcessors() {
>>>   updateAggregateValid();
>>> }
>>> 
>>> @Modified(id = "processors")
>>> public void modifiedProcessors() {
>>>   updateAggregateValid();
>>> }
>>> 
>>> The function updateAggregateValid() checks if all my configurable
>>> requirements are met and then sets the controller value to true,
>> otherwise
>>> to false. I'm not sure when the @Modified method is called. At first it
>>> seemed like @Modified would be the only callback I needed but it does not
>>> seem to be called on "unbind". Now I suspect that it is enough with @Bind
>>> and @Unbind - @Modified seems unnecessary.
>>> 
>>> What callbacks do I need to handle in order to react on all changes to
>> the
>>> list of required services?
>>> 
>> 
>> Bind and Unbind are covering your case. The modified callbacks mean that
>> one service has been updated (its service properties have changed) but it
>> still matches the filter. In your case, it's not relevant.
>> 
>> Clement
>> 
>> PS: `still matches the filter` means, from the interceptor perspective,
>> has been accepted by all tracking interceptors, including the filter,
>> managing the dependency.
>> 
>> 
>>> /Bengt
>>> 
>>> 
>>> 
>>> 
>>> 2013/10/2 Bengt Rodehav <be...@rodehav.com>
>>> 
>>>> Thanks for your detailed response Clement!
>>>> 
>>>> Sounds very interesting indeed although the fact that I can't change the
>>>> optionality sounds like a show stopper to me. In my case the list of
>>>> services to require can be >= 0. If, using config admin, I specify an
>> empty
>>>> list then the service dependency must be optional. If the list is
>> non-empty
>>>> then it must not be optional. I can't see how I can solve this using the
>>>> interceptors (although I haven't read the documentation yet :-)).
>>>> 
>>>> /Bengt
>>>> 
>>>> 
>>>> 2013/10/2 clement escoffier <cl...@gmail.com>
>>>> 
>>>>> Sent from my iPhone
>>>>> 
>>>>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
>>>>>> 
>>>>>> Interesting. Do you think it would also be possible to do an
>>>>> all-or-nothing
>>>>>> approach? E g if I want to require A and B, I could check if both A
>> and
>>>>> B
>>>>>> are available. If not, I would make the list empty thus making my
>>>>> instance
>>>>>> invalid? Or can I just say that the dependency is unresolved without
>>>>> having
>>>>>> to change the list?
>>>>> 
>>>>> Yes you can to that. I would say that the easiest way is to implement
>>>>> a ranking interceptor that returns an empty array until both services
>>>>> are there. When both are there, it returns both.
>>>>> 
>>>>> Notice that returning an empty array invalidates the dependency. For
>>>>> the instance it would just means : no services.
>>>>> 
>>>>>> 
>>>>>> BTW I did experiment a little with dynamically changing the
>> "optionable"
>>>>>> property of the requires dependency using the dependency manager. I
>>>>> never
>>>>>> did get that to work. It always stayed at the same value it got
>> through
>>>>> the
>>>>>> Requires annotation. Is that as designed or a bug?
>>>>>> 
>>>>> 
>>>>> Optionality cannot be changed, however the filter can. I can't
>>>>> remember the exact reason for that.
>>>>> 
>>>>>> I currently did a workaround using the life cycle controller as
>> adviced
>>>>> by
>>>>>> Richard. Whenever anything changes that could affect the validity of
>> the
>>>>>> instance I recalculate the life cycle controller value to reflect
>> that.
>>>>> For
>>>>>> instance if the list of dependencies change I recalculate and check if
>>>>> all
>>>>>> my required services are in the list. If not I set the controller
>> value
>>>>> to
>>>>>> false.
>>>>>> It works but the code is not very nice and easy to understand. It'll
>>>>> have
>>>>>> to do for now.
>>>>>> 
>>>>> 
>>>>> I did like this several times and was never happy of the result,
>>>>> especially it may mix, in your component code, business logic with
>>>>> higher-level rules and data. Very hard to maintain on the long term,
>>>>> unclear ad likely spaghetti-like. That's one of the reason we came up
>>>>> with the interceptors.
>>>>> 
>>>>> 
>>>>>> Clement, is the 1.10.x version released? I'm on a pretty old version
>> and
>>>>>> should probably upgrade. Also, is there any documentation regarding
>> the
>>>>>> interceptors you mentioned?
>>>>> 
>>>>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
>>>>> complete, bug-fix complete, lacks some tests and documentation). We
>>>>> plan to release it next week.
>>>>> 
>>>>> The good news is that it includes the interceptor documentation.
>>>>> 
>>>>> Clement
>>>>> 
>>>>> 
>>>>>> /Bengt
>>>>>> 
>>>>>> 
>>>>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
>>>>>> 
>>>>>>> Hi,
>>>>>>> 
>>>>>>> Not sure it would meet your requirements, but in the 1.10.x, we added
>>>>>>> service dependency interceptors. Interceptors are external entities
>>>>>>> involved in the service resolution. We have 3 types on interceptors:
>>>>>>> 
>>>>>>> - tracking interceptors allow hiding services, or selecting the set
>> of
>>>>>>> services seen by the service dependency (the LDAP filter is a
>> tracking
>>>>>>> interceptor)
>>>>>>> - ranking interceptors can change the order of the services (the
>>>>>>> comparator is a ranking interceptor)
>>>>>>> - binding interceptors can change the injected service objects (to be
>>>>> used
>>>>>>> with caution ;-))
>>>>>>> 
>>>>>>> You can, without too much effort, write an interceptor that will
>> shape
>>>>> the
>>>>>>> processor list as you want.
>>>>>>> 
>>>>>>> As said above, interceptors are external entities. Actually, they are
>>>>>>> services with a special 'target' property indicating in which
>>>>> dependencies
>>>>>>> they want to be involved. So, an interceptor can select one very
>>>>> specific
>>>>>>> dependency, all dependencies of an instance, all dependencies
>>>>> targeting a
>>>>>>> specific interface…
>>>>>>> 
>>>>>>> Unfortunately, there is a long overdue issue about interceptors:
>>>>>>> FELIX-4136 Document service dependency interceptors.
>>>>>>> 
>>>>>>> Best regards,
>>>>>>> 
>>>>>>> Clement
>>>>>>> 
>>>>>>> 
>>>>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>>>>>>>> 
>>>>>>>> Thanks for your reply Richard.
>>>>>>>> 
>>>>>>>> I am using a lifecycle controller already to make it possible to
>>>>>>>> enable/disable my services via a GUI. I'll see if I can use it for
>>>>> this
>>>>>>>> purpose.
>>>>>>>> 
>>>>>>>> I've also tried the following approach: Keep track of all possible
>>>>>>> services
>>>>>>>> that expose the interface I'm intererested in as follows:
>>>>>>>> 
>>>>>>>> @Requires(optional = true)
>>>>>>>> private IOrchestrationProcessor[] mProcessors;
>>>>>>>> 
>>>>>>>> In runtime, when my service is being activated (prior to creating
>> the
>>>>>>> camel
>>>>>>>> route) I check to see if all required processors exist, if not I
>>>>> throw an
>>>>>>>> exception. Unfortunately I have no control of in what order the
>>>>> services
>>>>>>>> will be activated so its hard to ever get the camel route created
>> this
>>>>>>> way.
>>>>>>>> A lot of the time a "required" services is activated a bit later.
>>>>>>>> 
>>>>>>>> /Bengt
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>>>>>>>>>> 
>>>>>>>>>> I'm creating a dynamic processing component using iPOJO and Camel.
>>>>> The
>>>>>>>>>> idea
>>>>>>>>>> is to dynamically specify (via config admin) a number of processor
>>>>>>> id's.
>>>>>>>>>> In
>>>>>>>>>> runtime I want to find the matching processors (the processors are
>>>>>>> Camel
>>>>>>>>>> processors published as OSGi services) with the correct id.
>>>>>>>>>> 
>>>>>>>>>> E g if I specify a list of services to {A,B} (FileInstall
>> recognizes
>>>>>>> this
>>>>>>>>>> as a list). I want to require those services in order for my iPojo
>>>>>>>>>> instance
>>>>>>>>>> to become valid. It was much harder than I thought.
>>>>>>>>>> 
>>>>>>>>>> I've tried something like:
>>>>>>>>>> 
>>>>>>>>>> @Property(name = "processors", mandatory = false, value = "")
>>>>>>>>>> public void setProcessors(String[] theProcessorIds) {
>>>>>>>>>>  mProcessorIds = theProcessorIds;
>>>>>>>>>>  updateProcessorFilter();
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> @Requires
>>>>>>>>>> private Processor[] mProcessors;
>>>>>>>>>> 
>>>>>>>>>> The idea is that whenever the configuration property "processors"
>> is
>>>>>>>>>> updated, I dynamically update the ldap filter on the dependency
>>>>>>>>>> mProcessors. I've used this approach before and it has worked when
>>>>>>> using a
>>>>>>>>>> single dependency (not an array).
>>>>>>>>>> 
>>>>>>>>>> The problem is that I want to specifically require each specified
>>>>>>>>>> processor. In the example above, I require one processor with id=A
>>>>> AND
>>>>>>> one
>>>>>>>>>> processor with id=B. It's not enough with anyone of them since I
>>>>> want
>>>>>>> to
>>>>>>>>>> invoke them one after another.
>>>>>>>>>> 
>>>>>>>>>> Can I use a filter for this? I've been thinking of something like
>>>>> this:
>>>>>>>>>> 
>>>>>>>>>> (|(processorId=A)(processorId=**B))
>>>>>>>>>> 
>>>>>>>>>> This would match both my processors but if one of them were
>> missing
>>>>> my
>>>>>>>>>> instance would still become valid which I don't want.
>>>>>>>>> 
>>>>>>>>> I don't think there is anyway to do what you want. This is
>>>>> essentially
>>>>>>> an
>>>>>>>>> "N cardinality" requirement, where you want to say that you require
>>>>>>>>> specifically N of something. Such requirements had been discussed
>>>>> over
>>>>>>> the
>>>>>>>>> years for Service Binder, Declarative Services, etc., but we could
>>>>> never
>>>>>>>>> agree on their usefulness or how to do them, so we just left it as
>>>>> it is
>>>>>>>>> now (i.e., optional, at least one...).
>>>>>>>>> 
>>>>>>>>> Other than adding some sort of threshold to service dependencies, I
>>>>>>> don't
>>>>>>>>> see this happening. You could potentially create an iPOJO lifecycle
>>>>>>>>> controller that would keep your component invalid until it matched
>>>>> the
>>>>>>>>> required number of services (if you can get this information in the
>>>>>>>>> handler)...or perhaps write/extend the service dependency handler.
>>>>>>>>> 
>>>>>>>>> -> richard
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> /Bengt
>>>>>>> 
>>>>> 
>> ------------------------------**------------------------------**---------
>>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>>>>>>> users-unsubscribe@felix.apache.org>
>>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>> 
>>>>>>> 
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>> 
>>>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>> 
>>>>> 
>>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
Looking forward to it!

/Bengt


2013/10/3 Clement Escoffier <cl...@gmail.com>

>
> On 3 oct. 2013, at 20:08, Bengt Rodehav <be...@rodehav.com> wrote:
>
> > I just discovered https://issues.apache.org/jira/browse/FELIX-4129which is
> > fixed. Sounds like this would make it possible to change the optionality
> > dynamically like I needed - is that right?
> >
> > This fix plus interceptors then seem like the perfect fit for me.
>
> Oh right ! We changed that when initiating the major refactoring about the
> dependency management and the new introspection and interceptor model. So,
> yes, it's possible since the 1.10.1 (I even did the bug fix… getting old).
> About the interceptor, stay tuned, will release a first version of the
> documentation this weekend.
>
>
> Clement
>
> >
> > /Bengt
> >
> >
> > 2013/10/3 Bengt Rodehav <be...@rodehav.com>
> >
> >> OK - thanks. I can skip the @Modified then.
> >>
> >> I've had some more problems unfortunately. It seems like, although I
> use a
> >> @Controller, which has the value "false", my instance still becomes
> valid.
> >> Shortly thereafter it becomes invalid again but this "false start"
> gives me
> >> problems.
> >>
> >> It's like the @Controller doesn't take effect immediately but only
> after a
> >> while. Does this has anything to do with the fact that I set
> >> "immediate=true" on my @Component?
> >>
> >> /Bengt
> >>
> >>
> >> 2013/10/3 Clement Escoffier <cl...@gmail.com>
> >>
> >>> Hi,
> >>>
> >>> On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:
> >>>
> >>>> A question related to my workaround Clement.
> >>>>
> >>>> To make sure that my lifecycle controller's value is up to date I need
> >>> to
> >>>> recalculate it every time the array of required services change. My
> code
> >>>> for this looks as follows:
> >>>>
> >>>> @Requires(optional = true, id = "processors")
> >>>> private IOrchestrationProcessor[] mProcessors;
> >>>>
> >>>> @Bind(id = "processors")
> >>>> public void bindProcessors() {
> >>>>   updateAggregateValid();
> >>>> }
> >>>>
> >>>> @Unbind(id = "processors")
> >>>> public void unbindProcessors() {
> >>>>   updateAggregateValid();
> >>>> }
> >>>>
> >>>> @Modified(id = "processors")
> >>>> public void modifiedProcessors() {
> >>>>   updateAggregateValid();
> >>>> }
> >>>>
> >>>> The function updateAggregateValid() checks if all my configurable
> >>>> requirements are met and then sets the controller value to true,
> >>> otherwise
> >>>> to false. I'm not sure when the @Modified method is called. At first
> it
> >>>> seemed like @Modified would be the only callback I needed but it does
> >>> not
> >>>> seem to be called on "unbind". Now I suspect that it is enough with
> >>> @Bind
> >>>> and @Unbind - @Modified seems unnecessary.
> >>>>
> >>>> What callbacks do I need to handle in order to react on all changes to
> >>> the
> >>>> list of required services?
> >>>>
> >>>
> >>> Bind and Unbind are covering your case. The modified callbacks mean
> that
> >>> one service has been updated (its service properties have changed) but
> it
> >>> still matches the filter. In your case, it's not relevant.
> >>>
> >>> Clement
> >>>
> >>> PS: `still matches the filter` means, from the interceptor perspective,
> >>> has been accepted by all tracking interceptors, including the filter,
> >>> managing the dependency.
> >>>
> >>>
> >>>> /Bengt
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> 2013/10/2 Bengt Rodehav <be...@rodehav.com>
> >>>>
> >>>>> Thanks for your detailed response Clement!
> >>>>>
> >>>>> Sounds very interesting indeed although the fact that I can't change
> >>> the
> >>>>> optionality sounds like a show stopper to me. In my case the list of
> >>>>> services to require can be >= 0. If, using config admin, I specify an
> >>> empty
> >>>>> list then the service dependency must be optional. If the list is
> >>> non-empty
> >>>>> then it must not be optional. I can't see how I can solve this using
> >>> the
> >>>>> interceptors (although I haven't read the documentation yet :-)).
> >>>>>
> >>>>> /Bengt
> >>>>>
> >>>>>
> >>>>> 2013/10/2 clement escoffier <cl...@gmail.com>
> >>>>>
> >>>>>> Sent from my iPhone
> >>>>>>
> >>>>>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
> >>>>>>>
> >>>>>>> Interesting. Do you think it would also be possible to do an
> >>>>>> all-or-nothing
> >>>>>>> approach? E g if I want to require A and B, I could check if both A
> >>> and
> >>>>>> B
> >>>>>>> are available. If not, I would make the list empty thus making my
> >>>>>> instance
> >>>>>>> invalid? Or can I just say that the dependency is unresolved
> without
> >>>>>> having
> >>>>>>> to change the list?
> >>>>>>
> >>>>>> Yes you can to that. I would say that the easiest way is to
> implement
> >>>>>> a ranking interceptor that returns an empty array until both
> services
> >>>>>> are there. When both are there, it returns both.
> >>>>>>
> >>>>>> Notice that returning an empty array invalidates the dependency. For
> >>>>>> the instance it would just means : no services.
> >>>>>>
> >>>>>>>
> >>>>>>> BTW I did experiment a little with dynamically changing the
> >>> "optionable"
> >>>>>>> property of the requires dependency using the dependency manager. I
> >>>>>> never
> >>>>>>> did get that to work. It always stayed at the same value it got
> >>> through
> >>>>>> the
> >>>>>>> Requires annotation. Is that as designed or a bug?
> >>>>>>>
> >>>>>>
> >>>>>> Optionality cannot be changed, however the filter can. I can't
> >>>>>> remember the exact reason for that.
> >>>>>>
> >>>>>>> I currently did a workaround using the life cycle controller as
> >>> adviced
> >>>>>> by
> >>>>>>> Richard. Whenever anything changes that could affect the validity
> of
> >>> the
> >>>>>>> instance I recalculate the life cycle controller value to reflect
> >>> that.
> >>>>>> For
> >>>>>>> instance if the list of dependencies change I recalculate and check
> >>> if
> >>>>>> all
> >>>>>>> my required services are in the list. If not I set the controller
> >>> value
> >>>>>> to
> >>>>>>> false.
> >>>>>>> It works but the code is not very nice and easy to understand.
> It'll
> >>>>>> have
> >>>>>>> to do for now.
> >>>>>>>
> >>>>>>
> >>>>>> I did like this several times and was never happy of the result,
> >>>>>> especially it may mix, in your component code, business logic with
> >>>>>> higher-level rules and data. Very hard to maintain on the long term,
> >>>>>> unclear ad likely spaghetti-like. That's one of the reason we came
> up
> >>>>>> with the interceptors.
> >>>>>>
> >>>>>>
> >>>>>>> Clement, is the 1.10.x version released? I'm on a pretty old
> version
> >>> and
> >>>>>>> should probably upgrade. Also, is there any documentation regarding
> >>> the
> >>>>>>> interceptors you mentioned?
> >>>>>>
> >>>>>> The 1.10.1 was released in june. A 1.11 is under preparation
> (feature
> >>>>>> complete, bug-fix complete, lacks some tests and documentation). We
> >>>>>> plan to release it next week.
> >>>>>>
> >>>>>> The good news is that it includes the interceptor documentation.
> >>>>>>
> >>>>>> Clement
> >>>>>>
> >>>>>>
> >>>>>>> /Bengt
> >>>>>>>
> >>>>>>>
> >>>>>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
> >>>>>>>
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> Not sure it would meet your requirements, but in the 1.10.x, we
> >>> added
> >>>>>>>> service dependency interceptors. Interceptors are external
> entities
> >>>>>>>> involved in the service resolution. We have 3 types on
> interceptors:
> >>>>>>>>
> >>>>>>>> - tracking interceptors allow hiding services, or selecting the
> set
> >>> of
> >>>>>>>> services seen by the service dependency (the LDAP filter is a
> >>> tracking
> >>>>>>>> interceptor)
> >>>>>>>> - ranking interceptors can change the order of the services (the
> >>>>>>>> comparator is a ranking interceptor)
> >>>>>>>> - binding interceptors can change the injected service objects (to
> >>> be
> >>>>>> used
> >>>>>>>> with caution ;-))
> >>>>>>>>
> >>>>>>>> You can, without too much effort, write an interceptor that will
> >>> shape
> >>>>>> the
> >>>>>>>> processor list as you want.
> >>>>>>>>
> >>>>>>>> As said above, interceptors are external entities. Actually, they
> >>> are
> >>>>>>>> services with a special 'target' property indicating in which
> >>>>>> dependencies
> >>>>>>>> they want to be involved. So, an interceptor can select one very
> >>>>>> specific
> >>>>>>>> dependency, all dependencies of an instance, all dependencies
> >>>>>> targeting a
> >>>>>>>> specific interface…
> >>>>>>>>
> >>>>>>>> Unfortunately, there is a long overdue issue about interceptors:
> >>>>>>>> FELIX-4136 Document service dependency interceptors.
> >>>>>>>>
> >>>>>>>> Best regards,
> >>>>>>>>
> >>>>>>>> Clement
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com>
> wrote:
> >>>>>>>>>
> >>>>>>>>> Thanks for your reply Richard.
> >>>>>>>>>
> >>>>>>>>> I am using a lifecycle controller already to make it possible to
> >>>>>>>>> enable/disable my services via a GUI. I'll see if I can use it
> for
> >>>>>> this
> >>>>>>>>> purpose.
> >>>>>>>>>
> >>>>>>>>> I've also tried the following approach: Keep track of all
> possible
> >>>>>>>> services
> >>>>>>>>> that expose the interface I'm intererested in as follows:
> >>>>>>>>>
> >>>>>>>>> @Requires(optional = true)
> >>>>>>>>> private IOrchestrationProcessor[] mProcessors;
> >>>>>>>>>
> >>>>>>>>> In runtime, when my service is being activated (prior to creating
> >>> the
> >>>>>>>> camel
> >>>>>>>>> route) I check to see if all required processors exist, if not I
> >>>>>> throw an
> >>>>>>>>> exception. Unfortunately I have no control of in what order the
> >>>>>> services
> >>>>>>>>> will be activated so its hard to ever get the camel route created
> >>> this
> >>>>>>>> way.
> >>>>>>>>> A lot of the time a "required" services is activated a bit later.
> >>>>>>>>>
> >>>>>>>>> /Bengt
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
> >>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
> >>>>>>>>>>>
> >>>>>>>>>>> I'm creating a dynamic processing component using iPOJO and
> >>> Camel.
> >>>>>> The
> >>>>>>>>>>> idea
> >>>>>>>>>>> is to dynamically specify (via config admin) a number of
> >>> processor
> >>>>>>>> id's.
> >>>>>>>>>>> In
> >>>>>>>>>>> runtime I want to find the matching processors (the processors
> >>> are
> >>>>>>>> Camel
> >>>>>>>>>>> processors published as OSGi services) with the correct id.
> >>>>>>>>>>>
> >>>>>>>>>>> E g if I specify a list of services to {A,B} (FileInstall
> >>> recognizes
> >>>>>>>> this
> >>>>>>>>>>> as a list). I want to require those services in order for my
> >>> iPojo
> >>>>>>>>>>> instance
> >>>>>>>>>>> to become valid. It was much harder than I thought.
> >>>>>>>>>>>
> >>>>>>>>>>> I've tried something like:
> >>>>>>>>>>>
> >>>>>>>>>>> @Property(name = "processors", mandatory = false, value = "")
> >>>>>>>>>>> public void setProcessors(String[] theProcessorIds) {
> >>>>>>>>>>>  mProcessorIds = theProcessorIds;
> >>>>>>>>>>>  updateProcessorFilter();
> >>>>>>>>>>> }
> >>>>>>>>>>>
> >>>>>>>>>>> @Requires
> >>>>>>>>>>> private Processor[] mProcessors;
> >>>>>>>>>>>
> >>>>>>>>>>> The idea is that whenever the configuration property
> >>> "processors" is
> >>>>>>>>>>> updated, I dynamically update the ldap filter on the dependency
> >>>>>>>>>>> mProcessors. I've used this approach before and it has worked
> >>> when
> >>>>>>>> using a
> >>>>>>>>>>> single dependency (not an array).
> >>>>>>>>>>>
> >>>>>>>>>>> The problem is that I want to specifically require each
> specified
> >>>>>>>>>>> processor. In the example above, I require one processor with
> >>> id=A
> >>>>>> AND
> >>>>>>>> one
> >>>>>>>>>>> processor with id=B. It's not enough with anyone of them since
> I
> >>>>>> want
> >>>>>>>> to
> >>>>>>>>>>> invoke them one after another.
> >>>>>>>>>>>
> >>>>>>>>>>> Can I use a filter for this? I've been thinking of something
> like
> >>>>>> this:
> >>>>>>>>>>>
> >>>>>>>>>>> (|(processorId=A)(processorId=**B))
> >>>>>>>>>>>
> >>>>>>>>>>> This would match both my processors but if one of them were
> >>> missing
> >>>>>> my
> >>>>>>>>>>> instance would still become valid which I don't want.
> >>>>>>>>>>
> >>>>>>>>>> I don't think there is anyway to do what you want. This is
> >>>>>> essentially
> >>>>>>>> an
> >>>>>>>>>> "N cardinality" requirement, where you want to say that you
> >>> require
> >>>>>>>>>> specifically N of something. Such requirements had been
> discussed
> >>>>>> over
> >>>>>>>> the
> >>>>>>>>>> years for Service Binder, Declarative Services, etc., but we
> could
> >>>>>> never
> >>>>>>>>>> agree on their usefulness or how to do them, so we just left it
> as
> >>>>>> it is
> >>>>>>>>>> now (i.e., optional, at least one...).
> >>>>>>>>>>
> >>>>>>>>>> Other than adding some sort of threshold to service
> dependencies,
> >>> I
> >>>>>>>> don't
> >>>>>>>>>> see this happening. You could potentially create an iPOJO
> >>> lifecycle
> >>>>>>>>>> controller that would keep your component invalid until it
> matched
> >>>>>> the
> >>>>>>>>>> required number of services (if you can get this information in
> >>> the
> >>>>>>>>>> handler)...or perhaps write/extend the service dependency
> handler.
> >>>>>>>>>>
> >>>>>>>>>> -> richard
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>> /Bengt
> >>>>>>>>
> >>>>>>
> >>>
> ------------------------------**------------------------------**---------
> >>>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
> >>>>>>>> users-unsubscribe@felix.apache.org>
> >>>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>> ---------------------------------------------------------------------
> >>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>>>
> >>>>>>>>
> >>>>>>
> >>>>>>
> ---------------------------------------------------------------------
> >>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>
> >>>>>>
> >>>>>
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>> For additional commands, e-mail: users-help@felix.apache.org
> >>>
> >>>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: iPOJO and dynamic requires

Posted by Clement Escoffier <cl...@gmail.com>.
On 3 oct. 2013, at 20:08, Bengt Rodehav <be...@rodehav.com> wrote:

> I just discovered https://issues.apache.org/jira/browse/FELIX-4129 which is
> fixed. Sounds like this would make it possible to change the optionality
> dynamically like I needed - is that right?
> 
> This fix plus interceptors then seem like the perfect fit for me.

Oh right ! We changed that when initiating the major refactoring about the dependency management and the new introspection and interceptor model. So, yes, it's possible since the 1.10.1 (I even did the bug fix… getting old).
About the interceptor, stay tuned, will release a first version of the documentation this weekend. 


Clement

> 
> /Bengt
> 
> 
> 2013/10/3 Bengt Rodehav <be...@rodehav.com>
> 
>> OK - thanks. I can skip the @Modified then.
>> 
>> I've had some more problems unfortunately. It seems like, although I use a
>> @Controller, which has the value "false", my instance still becomes valid.
>> Shortly thereafter it becomes invalid again but this "false start" gives me
>> problems.
>> 
>> It's like the @Controller doesn't take effect immediately but only after a
>> while. Does this has anything to do with the fact that I set
>> "immediate=true" on my @Component?
>> 
>> /Bengt
>> 
>> 
>> 2013/10/3 Clement Escoffier <cl...@gmail.com>
>> 
>>> Hi,
>>> 
>>> On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:
>>> 
>>>> A question related to my workaround Clement.
>>>> 
>>>> To make sure that my lifecycle controller's value is up to date I need
>>> to
>>>> recalculate it every time the array of required services change. My code
>>>> for this looks as follows:
>>>> 
>>>> @Requires(optional = true, id = "processors")
>>>> private IOrchestrationProcessor[] mProcessors;
>>>> 
>>>> @Bind(id = "processors")
>>>> public void bindProcessors() {
>>>>   updateAggregateValid();
>>>> }
>>>> 
>>>> @Unbind(id = "processors")
>>>> public void unbindProcessors() {
>>>>   updateAggregateValid();
>>>> }
>>>> 
>>>> @Modified(id = "processors")
>>>> public void modifiedProcessors() {
>>>>   updateAggregateValid();
>>>> }
>>>> 
>>>> The function updateAggregateValid() checks if all my configurable
>>>> requirements are met and then sets the controller value to true,
>>> otherwise
>>>> to false. I'm not sure when the @Modified method is called. At first it
>>>> seemed like @Modified would be the only callback I needed but it does
>>> not
>>>> seem to be called on "unbind". Now I suspect that it is enough with
>>> @Bind
>>>> and @Unbind - @Modified seems unnecessary.
>>>> 
>>>> What callbacks do I need to handle in order to react on all changes to
>>> the
>>>> list of required services?
>>>> 
>>> 
>>> Bind and Unbind are covering your case. The modified callbacks mean that
>>> one service has been updated (its service properties have changed) but it
>>> still matches the filter. In your case, it's not relevant.
>>> 
>>> Clement
>>> 
>>> PS: `still matches the filter` means, from the interceptor perspective,
>>> has been accepted by all tracking interceptors, including the filter,
>>> managing the dependency.
>>> 
>>> 
>>>> /Bengt
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 2013/10/2 Bengt Rodehav <be...@rodehav.com>
>>>> 
>>>>> Thanks for your detailed response Clement!
>>>>> 
>>>>> Sounds very interesting indeed although the fact that I can't change
>>> the
>>>>> optionality sounds like a show stopper to me. In my case the list of
>>>>> services to require can be >= 0. If, using config admin, I specify an
>>> empty
>>>>> list then the service dependency must be optional. If the list is
>>> non-empty
>>>>> then it must not be optional. I can't see how I can solve this using
>>> the
>>>>> interceptors (although I haven't read the documentation yet :-)).
>>>>> 
>>>>> /Bengt
>>>>> 
>>>>> 
>>>>> 2013/10/2 clement escoffier <cl...@gmail.com>
>>>>> 
>>>>>> Sent from my iPhone
>>>>>> 
>>>>>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
>>>>>>> 
>>>>>>> Interesting. Do you think it would also be possible to do an
>>>>>> all-or-nothing
>>>>>>> approach? E g if I want to require A and B, I could check if both A
>>> and
>>>>>> B
>>>>>>> are available. If not, I would make the list empty thus making my
>>>>>> instance
>>>>>>> invalid? Or can I just say that the dependency is unresolved without
>>>>>> having
>>>>>>> to change the list?
>>>>>> 
>>>>>> Yes you can to that. I would say that the easiest way is to implement
>>>>>> a ranking interceptor that returns an empty array until both services
>>>>>> are there. When both are there, it returns both.
>>>>>> 
>>>>>> Notice that returning an empty array invalidates the dependency. For
>>>>>> the instance it would just means : no services.
>>>>>> 
>>>>>>> 
>>>>>>> BTW I did experiment a little with dynamically changing the
>>> "optionable"
>>>>>>> property of the requires dependency using the dependency manager. I
>>>>>> never
>>>>>>> did get that to work. It always stayed at the same value it got
>>> through
>>>>>> the
>>>>>>> Requires annotation. Is that as designed or a bug?
>>>>>>> 
>>>>>> 
>>>>>> Optionality cannot be changed, however the filter can. I can't
>>>>>> remember the exact reason for that.
>>>>>> 
>>>>>>> I currently did a workaround using the life cycle controller as
>>> adviced
>>>>>> by
>>>>>>> Richard. Whenever anything changes that could affect the validity of
>>> the
>>>>>>> instance I recalculate the life cycle controller value to reflect
>>> that.
>>>>>> For
>>>>>>> instance if the list of dependencies change I recalculate and check
>>> if
>>>>>> all
>>>>>>> my required services are in the list. If not I set the controller
>>> value
>>>>>> to
>>>>>>> false.
>>>>>>> It works but the code is not very nice and easy to understand. It'll
>>>>>> have
>>>>>>> to do for now.
>>>>>>> 
>>>>>> 
>>>>>> I did like this several times and was never happy of the result,
>>>>>> especially it may mix, in your component code, business logic with
>>>>>> higher-level rules and data. Very hard to maintain on the long term,
>>>>>> unclear ad likely spaghetti-like. That's one of the reason we came up
>>>>>> with the interceptors.
>>>>>> 
>>>>>> 
>>>>>>> Clement, is the 1.10.x version released? I'm on a pretty old version
>>> and
>>>>>>> should probably upgrade. Also, is there any documentation regarding
>>> the
>>>>>>> interceptors you mentioned?
>>>>>> 
>>>>>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
>>>>>> complete, bug-fix complete, lacks some tests and documentation). We
>>>>>> plan to release it next week.
>>>>>> 
>>>>>> The good news is that it includes the interceptor documentation.
>>>>>> 
>>>>>> Clement
>>>>>> 
>>>>>> 
>>>>>>> /Bengt
>>>>>>> 
>>>>>>> 
>>>>>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
>>>>>>> 
>>>>>>>> Hi,
>>>>>>>> 
>>>>>>>> Not sure it would meet your requirements, but in the 1.10.x, we
>>> added
>>>>>>>> service dependency interceptors. Interceptors are external entities
>>>>>>>> involved in the service resolution. We have 3 types on interceptors:
>>>>>>>> 
>>>>>>>> - tracking interceptors allow hiding services, or selecting the set
>>> of
>>>>>>>> services seen by the service dependency (the LDAP filter is a
>>> tracking
>>>>>>>> interceptor)
>>>>>>>> - ranking interceptors can change the order of the services (the
>>>>>>>> comparator is a ranking interceptor)
>>>>>>>> - binding interceptors can change the injected service objects (to
>>> be
>>>>>> used
>>>>>>>> with caution ;-))
>>>>>>>> 
>>>>>>>> You can, without too much effort, write an interceptor that will
>>> shape
>>>>>> the
>>>>>>>> processor list as you want.
>>>>>>>> 
>>>>>>>> As said above, interceptors are external entities. Actually, they
>>> are
>>>>>>>> services with a special 'target' property indicating in which
>>>>>> dependencies
>>>>>>>> they want to be involved. So, an interceptor can select one very
>>>>>> specific
>>>>>>>> dependency, all dependencies of an instance, all dependencies
>>>>>> targeting a
>>>>>>>> specific interface…
>>>>>>>> 
>>>>>>>> Unfortunately, there is a long overdue issue about interceptors:
>>>>>>>> FELIX-4136 Document service dependency interceptors.
>>>>>>>> 
>>>>>>>> Best regards,
>>>>>>>> 
>>>>>>>> Clement
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>>>>>>>>> 
>>>>>>>>> Thanks for your reply Richard.
>>>>>>>>> 
>>>>>>>>> I am using a lifecycle controller already to make it possible to
>>>>>>>>> enable/disable my services via a GUI. I'll see if I can use it for
>>>>>> this
>>>>>>>>> purpose.
>>>>>>>>> 
>>>>>>>>> I've also tried the following approach: Keep track of all possible
>>>>>>>> services
>>>>>>>>> that expose the interface I'm intererested in as follows:
>>>>>>>>> 
>>>>>>>>> @Requires(optional = true)
>>>>>>>>> private IOrchestrationProcessor[] mProcessors;
>>>>>>>>> 
>>>>>>>>> In runtime, when my service is being activated (prior to creating
>>> the
>>>>>>>> camel
>>>>>>>>> route) I check to see if all required processors exist, if not I
>>>>>> throw an
>>>>>>>>> exception. Unfortunately I have no control of in what order the
>>>>>> services
>>>>>>>>> will be activated so its hard to ever get the camel route created
>>> this
>>>>>>>> way.
>>>>>>>>> A lot of the time a "required" services is activated a bit later.
>>>>>>>>> 
>>>>>>>>> /Bengt
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>>>>>>>>>>> 
>>>>>>>>>>> I'm creating a dynamic processing component using iPOJO and
>>> Camel.
>>>>>> The
>>>>>>>>>>> idea
>>>>>>>>>>> is to dynamically specify (via config admin) a number of
>>> processor
>>>>>>>> id's.
>>>>>>>>>>> In
>>>>>>>>>>> runtime I want to find the matching processors (the processors
>>> are
>>>>>>>> Camel
>>>>>>>>>>> processors published as OSGi services) with the correct id.
>>>>>>>>>>> 
>>>>>>>>>>> E g if I specify a list of services to {A,B} (FileInstall
>>> recognizes
>>>>>>>> this
>>>>>>>>>>> as a list). I want to require those services in order for my
>>> iPojo
>>>>>>>>>>> instance
>>>>>>>>>>> to become valid. It was much harder than I thought.
>>>>>>>>>>> 
>>>>>>>>>>> I've tried something like:
>>>>>>>>>>> 
>>>>>>>>>>> @Property(name = "processors", mandatory = false, value = "")
>>>>>>>>>>> public void setProcessors(String[] theProcessorIds) {
>>>>>>>>>>>  mProcessorIds = theProcessorIds;
>>>>>>>>>>>  updateProcessorFilter();
>>>>>>>>>>> }
>>>>>>>>>>> 
>>>>>>>>>>> @Requires
>>>>>>>>>>> private Processor[] mProcessors;
>>>>>>>>>>> 
>>>>>>>>>>> The idea is that whenever the configuration property
>>> "processors" is
>>>>>>>>>>> updated, I dynamically update the ldap filter on the dependency
>>>>>>>>>>> mProcessors. I've used this approach before and it has worked
>>> when
>>>>>>>> using a
>>>>>>>>>>> single dependency (not an array).
>>>>>>>>>>> 
>>>>>>>>>>> The problem is that I want to specifically require each specified
>>>>>>>>>>> processor. In the example above, I require one processor with
>>> id=A
>>>>>> AND
>>>>>>>> one
>>>>>>>>>>> processor with id=B. It's not enough with anyone of them since I
>>>>>> want
>>>>>>>> to
>>>>>>>>>>> invoke them one after another.
>>>>>>>>>>> 
>>>>>>>>>>> Can I use a filter for this? I've been thinking of something like
>>>>>> this:
>>>>>>>>>>> 
>>>>>>>>>>> (|(processorId=A)(processorId=**B))
>>>>>>>>>>> 
>>>>>>>>>>> This would match both my processors but if one of them were
>>> missing
>>>>>> my
>>>>>>>>>>> instance would still become valid which I don't want.
>>>>>>>>>> 
>>>>>>>>>> I don't think there is anyway to do what you want. This is
>>>>>> essentially
>>>>>>>> an
>>>>>>>>>> "N cardinality" requirement, where you want to say that you
>>> require
>>>>>>>>>> specifically N of something. Such requirements had been discussed
>>>>>> over
>>>>>>>> the
>>>>>>>>>> years for Service Binder, Declarative Services, etc., but we could
>>>>>> never
>>>>>>>>>> agree on their usefulness or how to do them, so we just left it as
>>>>>> it is
>>>>>>>>>> now (i.e., optional, at least one...).
>>>>>>>>>> 
>>>>>>>>>> Other than adding some sort of threshold to service dependencies,
>>> I
>>>>>>>> don't
>>>>>>>>>> see this happening. You could potentially create an iPOJO
>>> lifecycle
>>>>>>>>>> controller that would keep your component invalid until it matched
>>>>>> the
>>>>>>>>>> required number of services (if you can get this information in
>>> the
>>>>>>>>>> handler)...or perhaps write/extend the service dependency handler.
>>>>>>>>>> 
>>>>>>>>>> -> richard
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> /Bengt
>>>>>>>> 
>>>>>> 
>>> ------------------------------**------------------------------**---------
>>>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>>>>>>>> users-unsubscribe@felix.apache.org>
>>>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>>> 
>>>>>>>> 
>>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>> 
>>>>>> 
>>>>> 
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>> 
>>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
I just discovered https://issues.apache.org/jira/browse/FELIX-4129 which is
fixed. Sounds like this would make it possible to change the optionality
dynamically like I needed - is that right?

This fix plus interceptors then seem like the perfect fit for me.

/Bengt


2013/10/3 Bengt Rodehav <be...@rodehav.com>

> OK - thanks. I can skip the @Modified then.
>
> I've had some more problems unfortunately. It seems like, although I use a
> @Controller, which has the value "false", my instance still becomes valid.
> Shortly thereafter it becomes invalid again but this "false start" gives me
> problems.
>
> It's like the @Controller doesn't take effect immediately but only after a
> while. Does this has anything to do with the fact that I set
> "immediate=true" on my @Component?
>
> /Bengt
>
>
> 2013/10/3 Clement Escoffier <cl...@gmail.com>
>
>> Hi,
>>
>> On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:
>>
>> > A question related to my workaround Clement.
>> >
>> > To make sure that my lifecycle controller's value is up to date I need
>> to
>> > recalculate it every time the array of required services change. My code
>> > for this looks as follows:
>> >
>> >  @Requires(optional = true, id = "processors")
>> >  private IOrchestrationProcessor[] mProcessors;
>> >
>> >  @Bind(id = "processors")
>> >  public void bindProcessors() {
>> >    updateAggregateValid();
>> >  }
>> >
>> >  @Unbind(id = "processors")
>> >  public void unbindProcessors() {
>> >    updateAggregateValid();
>> >  }
>> >
>> >  @Modified(id = "processors")
>> >  public void modifiedProcessors() {
>> >    updateAggregateValid();
>> >  }
>> >
>> > The function updateAggregateValid() checks if all my configurable
>> > requirements are met and then sets the controller value to true,
>> otherwise
>> > to false. I'm not sure when the @Modified method is called. At first it
>> > seemed like @Modified would be the only callback I needed but it does
>> not
>> > seem to be called on "unbind". Now I suspect that it is enough with
>> @Bind
>> > and @Unbind - @Modified seems unnecessary.
>> >
>> > What callbacks do I need to handle in order to react on all changes to
>> the
>> > list of required services?
>> >
>>
>> Bind and Unbind are covering your case. The modified callbacks mean that
>> one service has been updated (its service properties have changed) but it
>> still matches the filter. In your case, it's not relevant.
>>
>> Clement
>>
>> PS: `still matches the filter` means, from the interceptor perspective,
>> has been accepted by all tracking interceptors, including the filter,
>> managing the dependency.
>>
>>
>> > /Bengt
>> >
>> >
>> >
>> >
>> > 2013/10/2 Bengt Rodehav <be...@rodehav.com>
>> >
>> >> Thanks for your detailed response Clement!
>> >>
>> >> Sounds very interesting indeed although the fact that I can't change
>> the
>> >> optionality sounds like a show stopper to me. In my case the list of
>> >> services to require can be >= 0. If, using config admin, I specify an
>> empty
>> >> list then the service dependency must be optional. If the list is
>> non-empty
>> >> then it must not be optional. I can't see how I can solve this using
>> the
>> >> interceptors (although I haven't read the documentation yet :-)).
>> >>
>> >> /Bengt
>> >>
>> >>
>> >> 2013/10/2 clement escoffier <cl...@gmail.com>
>> >>
>> >>> Sent from my iPhone
>> >>>
>> >>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
>> >>>>
>> >>>> Interesting. Do you think it would also be possible to do an
>> >>> all-or-nothing
>> >>>> approach? E g if I want to require A and B, I could check if both A
>> and
>> >>> B
>> >>>> are available. If not, I would make the list empty thus making my
>> >>> instance
>> >>>> invalid? Or can I just say that the dependency is unresolved without
>> >>> having
>> >>>> to change the list?
>> >>>
>> >>> Yes you can to that. I would say that the easiest way is to implement
>> >>> a ranking interceptor that returns an empty array until both services
>> >>> are there. When both are there, it returns both.
>> >>>
>> >>> Notice that returning an empty array invalidates the dependency. For
>> >>> the instance it would just means : no services.
>> >>>
>> >>>>
>> >>>> BTW I did experiment a little with dynamically changing the
>> "optionable"
>> >>>> property of the requires dependency using the dependency manager. I
>> >>> never
>> >>>> did get that to work. It always stayed at the same value it got
>> through
>> >>> the
>> >>>> Requires annotation. Is that as designed or a bug?
>> >>>>
>> >>>
>> >>> Optionality cannot be changed, however the filter can. I can't
>> >>> remember the exact reason for that.
>> >>>
>> >>>> I currently did a workaround using the life cycle controller as
>> adviced
>> >>> by
>> >>>> Richard. Whenever anything changes that could affect the validity of
>> the
>> >>>> instance I recalculate the life cycle controller value to reflect
>> that.
>> >>> For
>> >>>> instance if the list of dependencies change I recalculate and check
>> if
>> >>> all
>> >>>> my required services are in the list. If not I set the controller
>> value
>> >>> to
>> >>>> false.
>> >>>> It works but the code is not very nice and easy to understand. It'll
>> >>> have
>> >>>> to do for now.
>> >>>>
>> >>>
>> >>> I did like this several times and was never happy of the result,
>> >>> especially it may mix, in your component code, business logic with
>> >>> higher-level rules and data. Very hard to maintain on the long term,
>> >>> unclear ad likely spaghetti-like. That's one of the reason we came up
>> >>> with the interceptors.
>> >>>
>> >>>
>> >>>> Clement, is the 1.10.x version released? I'm on a pretty old version
>> and
>> >>>> should probably upgrade. Also, is there any documentation regarding
>> the
>> >>>> interceptors you mentioned?
>> >>>
>> >>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
>> >>> complete, bug-fix complete, lacks some tests and documentation). We
>> >>> plan to release it next week.
>> >>>
>> >>> The good news is that it includes the interceptor documentation.
>> >>>
>> >>> Clement
>> >>>
>> >>>
>> >>>> /Bengt
>> >>>>
>> >>>>
>> >>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
>> >>>>
>> >>>>> Hi,
>> >>>>>
>> >>>>> Not sure it would meet your requirements, but in the 1.10.x, we
>> added
>> >>>>> service dependency interceptors. Interceptors are external entities
>> >>>>> involved in the service resolution. We have 3 types on interceptors:
>> >>>>>
>> >>>>> - tracking interceptors allow hiding services, or selecting the set
>> of
>> >>>>> services seen by the service dependency (the LDAP filter is a
>> tracking
>> >>>>> interceptor)
>> >>>>> - ranking interceptors can change the order of the services (the
>> >>>>> comparator is a ranking interceptor)
>> >>>>> - binding interceptors can change the injected service objects (to
>> be
>> >>> used
>> >>>>> with caution ;-))
>> >>>>>
>> >>>>> You can, without too much effort, write an interceptor that will
>> shape
>> >>> the
>> >>>>> processor list as you want.
>> >>>>>
>> >>>>> As said above, interceptors are external entities. Actually, they
>> are
>> >>>>> services with a special 'target' property indicating in which
>> >>> dependencies
>> >>>>> they want to be involved. So, an interceptor can select one very
>> >>> specific
>> >>>>> dependency, all dependencies of an instance, all dependencies
>> >>> targeting a
>> >>>>> specific interface…
>> >>>>>
>> >>>>> Unfortunately, there is a long overdue issue about interceptors:
>> >>>>> FELIX-4136 Document service dependency interceptors.
>> >>>>>
>> >>>>> Best regards,
>> >>>>>
>> >>>>> Clement
>> >>>>>
>> >>>>>
>> >>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>> >>>>>>
>> >>>>>> Thanks for your reply Richard.
>> >>>>>>
>> >>>>>> I am using a lifecycle controller already to make it possible to
>> >>>>>> enable/disable my services via a GUI. I'll see if I can use it for
>> >>> this
>> >>>>>> purpose.
>> >>>>>>
>> >>>>>> I've also tried the following approach: Keep track of all possible
>> >>>>> services
>> >>>>>> that expose the interface I'm intererested in as follows:
>> >>>>>>
>> >>>>>> @Requires(optional = true)
>> >>>>>> private IOrchestrationProcessor[] mProcessors;
>> >>>>>>
>> >>>>>> In runtime, when my service is being activated (prior to creating
>> the
>> >>>>> camel
>> >>>>>> route) I check to see if all required processors exist, if not I
>> >>> throw an
>> >>>>>> exception. Unfortunately I have no control of in what order the
>> >>> services
>> >>>>>> will be activated so its hard to ever get the camel route created
>> this
>> >>>>> way.
>> >>>>>> A lot of the time a "required" services is activated a bit later.
>> >>>>>>
>> >>>>>> /Bengt
>> >>>>>>
>> >>>>>>
>> >>>>>>
>> >>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>> >>>>>>
>> >>>>>>>
>> >>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>> >>>>>>>>
>> >>>>>>>> I'm creating a dynamic processing component using iPOJO and
>> Camel.
>> >>> The
>> >>>>>>>> idea
>> >>>>>>>> is to dynamically specify (via config admin) a number of
>> processor
>> >>>>> id's.
>> >>>>>>>> In
>> >>>>>>>> runtime I want to find the matching processors (the processors
>> are
>> >>>>> Camel
>> >>>>>>>> processors published as OSGi services) with the correct id.
>> >>>>>>>>
>> >>>>>>>> E g if I specify a list of services to {A,B} (FileInstall
>> recognizes
>> >>>>> this
>> >>>>>>>> as a list). I want to require those services in order for my
>> iPojo
>> >>>>>>>> instance
>> >>>>>>>> to become valid. It was much harder than I thought.
>> >>>>>>>>
>> >>>>>>>> I've tried something like:
>> >>>>>>>>
>> >>>>>>>> @Property(name = "processors", mandatory = false, value = "")
>> >>>>>>>> public void setProcessors(String[] theProcessorIds) {
>> >>>>>>>>   mProcessorIds = theProcessorIds;
>> >>>>>>>>   updateProcessorFilter();
>> >>>>>>>> }
>> >>>>>>>>
>> >>>>>>>> @Requires
>> >>>>>>>> private Processor[] mProcessors;
>> >>>>>>>>
>> >>>>>>>> The idea is that whenever the configuration property
>> "processors" is
>> >>>>>>>> updated, I dynamically update the ldap filter on the dependency
>> >>>>>>>> mProcessors. I've used this approach before and it has worked
>> when
>> >>>>> using a
>> >>>>>>>> single dependency (not an array).
>> >>>>>>>>
>> >>>>>>>> The problem is that I want to specifically require each specified
>> >>>>>>>> processor. In the example above, I require one processor with
>> id=A
>> >>> AND
>> >>>>> one
>> >>>>>>>> processor with id=B. It's not enough with anyone of them since I
>> >>> want
>> >>>>> to
>> >>>>>>>> invoke them one after another.
>> >>>>>>>>
>> >>>>>>>> Can I use a filter for this? I've been thinking of something like
>> >>> this:
>> >>>>>>>>
>> >>>>>>>> (|(processorId=A)(processorId=**B))
>> >>>>>>>>
>> >>>>>>>> This would match both my processors but if one of them were
>> missing
>> >>> my
>> >>>>>>>> instance would still become valid which I don't want.
>> >>>>>>>
>> >>>>>>> I don't think there is anyway to do what you want. This is
>> >>> essentially
>> >>>>> an
>> >>>>>>> "N cardinality" requirement, where you want to say that you
>> require
>> >>>>>>> specifically N of something. Such requirements had been discussed
>> >>> over
>> >>>>> the
>> >>>>>>> years for Service Binder, Declarative Services, etc., but we could
>> >>> never
>> >>>>>>> agree on their usefulness or how to do them, so we just left it as
>> >>> it is
>> >>>>>>> now (i.e., optional, at least one...).
>> >>>>>>>
>> >>>>>>> Other than adding some sort of threshold to service dependencies,
>> I
>> >>>>> don't
>> >>>>>>> see this happening. You could potentially create an iPOJO
>> lifecycle
>> >>>>>>> controller that would keep your component invalid until it matched
>> >>> the
>> >>>>>>> required number of services (if you can get this information in
>> the
>> >>>>>>> handler)...or perhaps write/extend the service dependency handler.
>> >>>>>>>
>> >>>>>>> -> richard
>> >>>>>>>
>> >>>>>>>
>> >>>>>>>> /Bengt
>> >>>>>
>> >>>
>> ------------------------------**------------------------------**---------
>> >>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>> >>>>> users-unsubscribe@felix.apache.org>
>> >>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>> >>>>>
>> >>>>>
>> >>>>>
>> ---------------------------------------------------------------------
>> >>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> >>>>> For additional commands, e-mail: users-help@felix.apache.org
>> >>>>>
>> >>>>>
>> >>>
>> >>> ---------------------------------------------------------------------
>> >>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> >>> For additional commands, e-mail: users-help@felix.apache.org
>> >>>
>> >>>
>> >>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>

Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
OK - thanks. I can skip the @Modified then.

I've had some more problems unfortunately. It seems like, although I use a
@Controller, which has the value "false", my instance still becomes valid.
Shortly thereafter it becomes invalid again but this "false start" gives me
problems.

It's like the @Controller doesn't take effect immediately but only after a
while. Does this has anything to do with the fact that I set
"immediate=true" on my @Component?

/Bengt


2013/10/3 Clement Escoffier <cl...@gmail.com>

> Hi,
>
> On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:
>
> > A question related to my workaround Clement.
> >
> > To make sure that my lifecycle controller's value is up to date I need to
> > recalculate it every time the array of required services change. My code
> > for this looks as follows:
> >
> >  @Requires(optional = true, id = "processors")
> >  private IOrchestrationProcessor[] mProcessors;
> >
> >  @Bind(id = "processors")
> >  public void bindProcessors() {
> >    updateAggregateValid();
> >  }
> >
> >  @Unbind(id = "processors")
> >  public void unbindProcessors() {
> >    updateAggregateValid();
> >  }
> >
> >  @Modified(id = "processors")
> >  public void modifiedProcessors() {
> >    updateAggregateValid();
> >  }
> >
> > The function updateAggregateValid() checks if all my configurable
> > requirements are met and then sets the controller value to true,
> otherwise
> > to false. I'm not sure when the @Modified method is called. At first it
> > seemed like @Modified would be the only callback I needed but it does not
> > seem to be called on "unbind". Now I suspect that it is enough with @Bind
> > and @Unbind - @Modified seems unnecessary.
> >
> > What callbacks do I need to handle in order to react on all changes to
> the
> > list of required services?
> >
>
> Bind and Unbind are covering your case. The modified callbacks mean that
> one service has been updated (its service properties have changed) but it
> still matches the filter. In your case, it's not relevant.
>
> Clement
>
> PS: `still matches the filter` means, from the interceptor perspective,
> has been accepted by all tracking interceptors, including the filter,
> managing the dependency.
>
>
> > /Bengt
> >
> >
> >
> >
> > 2013/10/2 Bengt Rodehav <be...@rodehav.com>
> >
> >> Thanks for your detailed response Clement!
> >>
> >> Sounds very interesting indeed although the fact that I can't change the
> >> optionality sounds like a show stopper to me. In my case the list of
> >> services to require can be >= 0. If, using config admin, I specify an
> empty
> >> list then the service dependency must be optional. If the list is
> non-empty
> >> then it must not be optional. I can't see how I can solve this using the
> >> interceptors (although I haven't read the documentation yet :-)).
> >>
> >> /Bengt
> >>
> >>
> >> 2013/10/2 clement escoffier <cl...@gmail.com>
> >>
> >>> Sent from my iPhone
> >>>
> >>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
> >>>>
> >>>> Interesting. Do you think it would also be possible to do an
> >>> all-or-nothing
> >>>> approach? E g if I want to require A and B, I could check if both A
> and
> >>> B
> >>>> are available. If not, I would make the list empty thus making my
> >>> instance
> >>>> invalid? Or can I just say that the dependency is unresolved without
> >>> having
> >>>> to change the list?
> >>>
> >>> Yes you can to that. I would say that the easiest way is to implement
> >>> a ranking interceptor that returns an empty array until both services
> >>> are there. When both are there, it returns both.
> >>>
> >>> Notice that returning an empty array invalidates the dependency. For
> >>> the instance it would just means : no services.
> >>>
> >>>>
> >>>> BTW I did experiment a little with dynamically changing the
> "optionable"
> >>>> property of the requires dependency using the dependency manager. I
> >>> never
> >>>> did get that to work. It always stayed at the same value it got
> through
> >>> the
> >>>> Requires annotation. Is that as designed or a bug?
> >>>>
> >>>
> >>> Optionality cannot be changed, however the filter can. I can't
> >>> remember the exact reason for that.
> >>>
> >>>> I currently did a workaround using the life cycle controller as
> adviced
> >>> by
> >>>> Richard. Whenever anything changes that could affect the validity of
> the
> >>>> instance I recalculate the life cycle controller value to reflect
> that.
> >>> For
> >>>> instance if the list of dependencies change I recalculate and check if
> >>> all
> >>>> my required services are in the list. If not I set the controller
> value
> >>> to
> >>>> false.
> >>>> It works but the code is not very nice and easy to understand. It'll
> >>> have
> >>>> to do for now.
> >>>>
> >>>
> >>> I did like this several times and was never happy of the result,
> >>> especially it may mix, in your component code, business logic with
> >>> higher-level rules and data. Very hard to maintain on the long term,
> >>> unclear ad likely spaghetti-like. That's one of the reason we came up
> >>> with the interceptors.
> >>>
> >>>
> >>>> Clement, is the 1.10.x version released? I'm on a pretty old version
> and
> >>>> should probably upgrade. Also, is there any documentation regarding
> the
> >>>> interceptors you mentioned?
> >>>
> >>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
> >>> complete, bug-fix complete, lacks some tests and documentation). We
> >>> plan to release it next week.
> >>>
> >>> The good news is that it includes the interceptor documentation.
> >>>
> >>> Clement
> >>>
> >>>
> >>>> /Bengt
> >>>>
> >>>>
> >>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
> >>>>
> >>>>> Hi,
> >>>>>
> >>>>> Not sure it would meet your requirements, but in the 1.10.x, we added
> >>>>> service dependency interceptors. Interceptors are external entities
> >>>>> involved in the service resolution. We have 3 types on interceptors:
> >>>>>
> >>>>> - tracking interceptors allow hiding services, or selecting the set
> of
> >>>>> services seen by the service dependency (the LDAP filter is a
> tracking
> >>>>> interceptor)
> >>>>> - ranking interceptors can change the order of the services (the
> >>>>> comparator is a ranking interceptor)
> >>>>> - binding interceptors can change the injected service objects (to be
> >>> used
> >>>>> with caution ;-))
> >>>>>
> >>>>> You can, without too much effort, write an interceptor that will
> shape
> >>> the
> >>>>> processor list as you want.
> >>>>>
> >>>>> As said above, interceptors are external entities. Actually, they are
> >>>>> services with a special 'target' property indicating in which
> >>> dependencies
> >>>>> they want to be involved. So, an interceptor can select one very
> >>> specific
> >>>>> dependency, all dependencies of an instance, all dependencies
> >>> targeting a
> >>>>> specific interface…
> >>>>>
> >>>>> Unfortunately, there is a long overdue issue about interceptors:
> >>>>> FELIX-4136 Document service dependency interceptors.
> >>>>>
> >>>>> Best regards,
> >>>>>
> >>>>> Clement
> >>>>>
> >>>>>
> >>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
> >>>>>>
> >>>>>> Thanks for your reply Richard.
> >>>>>>
> >>>>>> I am using a lifecycle controller already to make it possible to
> >>>>>> enable/disable my services via a GUI. I'll see if I can use it for
> >>> this
> >>>>>> purpose.
> >>>>>>
> >>>>>> I've also tried the following approach: Keep track of all possible
> >>>>> services
> >>>>>> that expose the interface I'm intererested in as follows:
> >>>>>>
> >>>>>> @Requires(optional = true)
> >>>>>> private IOrchestrationProcessor[] mProcessors;
> >>>>>>
> >>>>>> In runtime, when my service is being activated (prior to creating
> the
> >>>>> camel
> >>>>>> route) I check to see if all required processors exist, if not I
> >>> throw an
> >>>>>> exception. Unfortunately I have no control of in what order the
> >>> services
> >>>>>> will be activated so its hard to ever get the camel route created
> this
> >>>>> way.
> >>>>>> A lot of the time a "required" services is activated a bit later.
> >>>>>>
> >>>>>> /Bengt
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
> >>>>>>
> >>>>>>>
> >>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
> >>>>>>>>
> >>>>>>>> I'm creating a dynamic processing component using iPOJO and Camel.
> >>> The
> >>>>>>>> idea
> >>>>>>>> is to dynamically specify (via config admin) a number of processor
> >>>>> id's.
> >>>>>>>> In
> >>>>>>>> runtime I want to find the matching processors (the processors are
> >>>>> Camel
> >>>>>>>> processors published as OSGi services) with the correct id.
> >>>>>>>>
> >>>>>>>> E g if I specify a list of services to {A,B} (FileInstall
> recognizes
> >>>>> this
> >>>>>>>> as a list). I want to require those services in order for my iPojo
> >>>>>>>> instance
> >>>>>>>> to become valid. It was much harder than I thought.
> >>>>>>>>
> >>>>>>>> I've tried something like:
> >>>>>>>>
> >>>>>>>> @Property(name = "processors", mandatory = false, value = "")
> >>>>>>>> public void setProcessors(String[] theProcessorIds) {
> >>>>>>>>   mProcessorIds = theProcessorIds;
> >>>>>>>>   updateProcessorFilter();
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> @Requires
> >>>>>>>> private Processor[] mProcessors;
> >>>>>>>>
> >>>>>>>> The idea is that whenever the configuration property "processors"
> is
> >>>>>>>> updated, I dynamically update the ldap filter on the dependency
> >>>>>>>> mProcessors. I've used this approach before and it has worked when
> >>>>> using a
> >>>>>>>> single dependency (not an array).
> >>>>>>>>
> >>>>>>>> The problem is that I want to specifically require each specified
> >>>>>>>> processor. In the example above, I require one processor with id=A
> >>> AND
> >>>>> one
> >>>>>>>> processor with id=B. It's not enough with anyone of them since I
> >>> want
> >>>>> to
> >>>>>>>> invoke them one after another.
> >>>>>>>>
> >>>>>>>> Can I use a filter for this? I've been thinking of something like
> >>> this:
> >>>>>>>>
> >>>>>>>> (|(processorId=A)(processorId=**B))
> >>>>>>>>
> >>>>>>>> This would match both my processors but if one of them were
> missing
> >>> my
> >>>>>>>> instance would still become valid which I don't want.
> >>>>>>>
> >>>>>>> I don't think there is anyway to do what you want. This is
> >>> essentially
> >>>>> an
> >>>>>>> "N cardinality" requirement, where you want to say that you require
> >>>>>>> specifically N of something. Such requirements had been discussed
> >>> over
> >>>>> the
> >>>>>>> years for Service Binder, Declarative Services, etc., but we could
> >>> never
> >>>>>>> agree on their usefulness or how to do them, so we just left it as
> >>> it is
> >>>>>>> now (i.e., optional, at least one...).
> >>>>>>>
> >>>>>>> Other than adding some sort of threshold to service dependencies, I
> >>>>> don't
> >>>>>>> see this happening. You could potentially create an iPOJO lifecycle
> >>>>>>> controller that would keep your component invalid until it matched
> >>> the
> >>>>>>> required number of services (if you can get this information in the
> >>>>>>> handler)...or perhaps write/extend the service dependency handler.
> >>>>>>>
> >>>>>>> -> richard
> >>>>>>>
> >>>>>>>
> >>>>>>>> /Bengt
> >>>>>
> >>>
> ------------------------------**------------------------------**---------
> >>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
> >>>>> users-unsubscribe@felix.apache.org>
> >>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>
> >>>>>
> >>>>> ---------------------------------------------------------------------
> >>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>
> >>>>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>> For additional commands, e-mail: users-help@felix.apache.org
> >>>
> >>>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: iPOJO and dynamic requires

Posted by Clement Escoffier <cl...@gmail.com>.
Hi,

On 3 oct. 2013, at 08:33, Bengt Rodehav <be...@rodehav.com> wrote:

> A question related to my workaround Clement.
> 
> To make sure that my lifecycle controller's value is up to date I need to
> recalculate it every time the array of required services change. My code
> for this looks as follows:
> 
>  @Requires(optional = true, id = "processors")
>  private IOrchestrationProcessor[] mProcessors;
> 
>  @Bind(id = "processors")
>  public void bindProcessors() {
>    updateAggregateValid();
>  }
> 
>  @Unbind(id = "processors")
>  public void unbindProcessors() {
>    updateAggregateValid();
>  }
> 
>  @Modified(id = "processors")
>  public void modifiedProcessors() {
>    updateAggregateValid();
>  }
> 
> The function updateAggregateValid() checks if all my configurable
> requirements are met and then sets the controller value to true, otherwise
> to false. I'm not sure when the @Modified method is called. At first it
> seemed like @Modified would be the only callback I needed but it does not
> seem to be called on "unbind". Now I suspect that it is enough with @Bind
> and @Unbind - @Modified seems unnecessary.
> 
> What callbacks do I need to handle in order to react on all changes to the
> list of required services?
> 

Bind and Unbind are covering your case. The modified callbacks mean that one service has been updated (its service properties have changed) but it still matches the filter. In your case, it's not relevant.

Clement

PS: `still matches the filter` means, from the interceptor perspective, has been accepted by all tracking interceptors, including the filter, managing the dependency.


> /Bengt
> 
> 
> 
> 
> 2013/10/2 Bengt Rodehav <be...@rodehav.com>
> 
>> Thanks for your detailed response Clement!
>> 
>> Sounds very interesting indeed although the fact that I can't change the
>> optionality sounds like a show stopper to me. In my case the list of
>> services to require can be >= 0. If, using config admin, I specify an empty
>> list then the service dependency must be optional. If the list is non-empty
>> then it must not be optional. I can't see how I can solve this using the
>> interceptors (although I haven't read the documentation yet :-)).
>> 
>> /Bengt
>> 
>> 
>> 2013/10/2 clement escoffier <cl...@gmail.com>
>> 
>>> Sent from my iPhone
>>> 
>>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
>>>> 
>>>> Interesting. Do you think it would also be possible to do an
>>> all-or-nothing
>>>> approach? E g if I want to require A and B, I could check if both A and
>>> B
>>>> are available. If not, I would make the list empty thus making my
>>> instance
>>>> invalid? Or can I just say that the dependency is unresolved without
>>> having
>>>> to change the list?
>>> 
>>> Yes you can to that. I would say that the easiest way is to implement
>>> a ranking interceptor that returns an empty array until both services
>>> are there. When both are there, it returns both.
>>> 
>>> Notice that returning an empty array invalidates the dependency. For
>>> the instance it would just means : no services.
>>> 
>>>> 
>>>> BTW I did experiment a little with dynamically changing the "optionable"
>>>> property of the requires dependency using the dependency manager. I
>>> never
>>>> did get that to work. It always stayed at the same value it got through
>>> the
>>>> Requires annotation. Is that as designed or a bug?
>>>> 
>>> 
>>> Optionality cannot be changed, however the filter can. I can't
>>> remember the exact reason for that.
>>> 
>>>> I currently did a workaround using the life cycle controller as adviced
>>> by
>>>> Richard. Whenever anything changes that could affect the validity of the
>>>> instance I recalculate the life cycle controller value to reflect that.
>>> For
>>>> instance if the list of dependencies change I recalculate and check if
>>> all
>>>> my required services are in the list. If not I set the controller value
>>> to
>>>> false.
>>>> It works but the code is not very nice and easy to understand. It'll
>>> have
>>>> to do for now.
>>>> 
>>> 
>>> I did like this several times and was never happy of the result,
>>> especially it may mix, in your component code, business logic with
>>> higher-level rules and data. Very hard to maintain on the long term,
>>> unclear ad likely spaghetti-like. That's one of the reason we came up
>>> with the interceptors.
>>> 
>>> 
>>>> Clement, is the 1.10.x version released? I'm on a pretty old version and
>>>> should probably upgrade. Also, is there any documentation regarding the
>>>> interceptors you mentioned?
>>> 
>>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
>>> complete, bug-fix complete, lacks some tests and documentation). We
>>> plan to release it next week.
>>> 
>>> The good news is that it includes the interceptor documentation.
>>> 
>>> Clement
>>> 
>>> 
>>>> /Bengt
>>>> 
>>>> 
>>>> 2013/10/2 Clement Escoffier <cl...@gmail.com>
>>>> 
>>>>> Hi,
>>>>> 
>>>>> Not sure it would meet your requirements, but in the 1.10.x, we added
>>>>> service dependency interceptors. Interceptors are external entities
>>>>> involved in the service resolution. We have 3 types on interceptors:
>>>>> 
>>>>> - tracking interceptors allow hiding services, or selecting the set of
>>>>> services seen by the service dependency (the LDAP filter is a tracking
>>>>> interceptor)
>>>>> - ranking interceptors can change the order of the services (the
>>>>> comparator is a ranking interceptor)
>>>>> - binding interceptors can change the injected service objects (to be
>>> used
>>>>> with caution ;-))
>>>>> 
>>>>> You can, without too much effort, write an interceptor that will shape
>>> the
>>>>> processor list as you want.
>>>>> 
>>>>> As said above, interceptors are external entities. Actually, they are
>>>>> services with a special 'target' property indicating in which
>>> dependencies
>>>>> they want to be involved. So, an interceptor can select one very
>>> specific
>>>>> dependency, all dependencies of an instance, all dependencies
>>> targeting a
>>>>> specific interface…
>>>>> 
>>>>> Unfortunately, there is a long overdue issue about interceptors:
>>>>> FELIX-4136 Document service dependency interceptors.
>>>>> 
>>>>> Best regards,
>>>>> 
>>>>> Clement
>>>>> 
>>>>> 
>>>>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>>>>>> 
>>>>>> Thanks for your reply Richard.
>>>>>> 
>>>>>> I am using a lifecycle controller already to make it possible to
>>>>>> enable/disable my services via a GUI. I'll see if I can use it for
>>> this
>>>>>> purpose.
>>>>>> 
>>>>>> I've also tried the following approach: Keep track of all possible
>>>>> services
>>>>>> that expose the interface I'm intererested in as follows:
>>>>>> 
>>>>>> @Requires(optional = true)
>>>>>> private IOrchestrationProcessor[] mProcessors;
>>>>>> 
>>>>>> In runtime, when my service is being activated (prior to creating the
>>>>> camel
>>>>>> route) I check to see if all required processors exist, if not I
>>> throw an
>>>>>> exception. Unfortunately I have no control of in what order the
>>> services
>>>>>> will be activated so its hard to ever get the camel route created this
>>>>> way.
>>>>>> A lot of the time a "required" services is activated a bit later.
>>>>>> 
>>>>>> /Bengt
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>>>>>> 
>>>>>>> 
>>>>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>>>>>>>> 
>>>>>>>> I'm creating a dynamic processing component using iPOJO and Camel.
>>> The
>>>>>>>> idea
>>>>>>>> is to dynamically specify (via config admin) a number of processor
>>>>> id's.
>>>>>>>> In
>>>>>>>> runtime I want to find the matching processors (the processors are
>>>>> Camel
>>>>>>>> processors published as OSGi services) with the correct id.
>>>>>>>> 
>>>>>>>> E g if I specify a list of services to {A,B} (FileInstall recognizes
>>>>> this
>>>>>>>> as a list). I want to require those services in order for my iPojo
>>>>>>>> instance
>>>>>>>> to become valid. It was much harder than I thought.
>>>>>>>> 
>>>>>>>> I've tried something like:
>>>>>>>> 
>>>>>>>> @Property(name = "processors", mandatory = false, value = "")
>>>>>>>> public void setProcessors(String[] theProcessorIds) {
>>>>>>>>   mProcessorIds = theProcessorIds;
>>>>>>>>   updateProcessorFilter();
>>>>>>>> }
>>>>>>>> 
>>>>>>>> @Requires
>>>>>>>> private Processor[] mProcessors;
>>>>>>>> 
>>>>>>>> The idea is that whenever the configuration property "processors" is
>>>>>>>> updated, I dynamically update the ldap filter on the dependency
>>>>>>>> mProcessors. I've used this approach before and it has worked when
>>>>> using a
>>>>>>>> single dependency (not an array).
>>>>>>>> 
>>>>>>>> The problem is that I want to specifically require each specified
>>>>>>>> processor. In the example above, I require one processor with id=A
>>> AND
>>>>> one
>>>>>>>> processor with id=B. It's not enough with anyone of them since I
>>> want
>>>>> to
>>>>>>>> invoke them one after another.
>>>>>>>> 
>>>>>>>> Can I use a filter for this? I've been thinking of something like
>>> this:
>>>>>>>> 
>>>>>>>> (|(processorId=A)(processorId=**B))
>>>>>>>> 
>>>>>>>> This would match both my processors but if one of them were missing
>>> my
>>>>>>>> instance would still become valid which I don't want.
>>>>>>> 
>>>>>>> I don't think there is anyway to do what you want. This is
>>> essentially
>>>>> an
>>>>>>> "N cardinality" requirement, where you want to say that you require
>>>>>>> specifically N of something. Such requirements had been discussed
>>> over
>>>>> the
>>>>>>> years for Service Binder, Declarative Services, etc., but we could
>>> never
>>>>>>> agree on their usefulness or how to do them, so we just left it as
>>> it is
>>>>>>> now (i.e., optional, at least one...).
>>>>>>> 
>>>>>>> Other than adding some sort of threshold to service dependencies, I
>>>>> don't
>>>>>>> see this happening. You could potentially create an iPOJO lifecycle
>>>>>>> controller that would keep your component invalid until it matched
>>> the
>>>>>>> required number of services (if you can get this information in the
>>>>>>> handler)...or perhaps write/extend the service dependency handler.
>>>>>>> 
>>>>>>> -> richard
>>>>>>> 
>>>>>>> 
>>>>>>>> /Bengt
>>>>> 
>>> ------------------------------**------------------------------**---------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>>>>> users-unsubscribe@felix.apache.org>
>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>> 
>>>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>> 
>>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
A question related to my workaround Clement.

To make sure that my lifecycle controller's value is up to date I need to
recalculate it every time the array of required services change. My code
for this looks as follows:

  @Requires(optional = true, id = "processors")
  private IOrchestrationProcessor[] mProcessors;

  @Bind(id = "processors")
  public void bindProcessors() {
    updateAggregateValid();
  }

  @Unbind(id = "processors")
  public void unbindProcessors() {
    updateAggregateValid();
  }

  @Modified(id = "processors")
  public void modifiedProcessors() {
    updateAggregateValid();
  }

The function updateAggregateValid() checks if all my configurable
requirements are met and then sets the controller value to true, otherwise
to false. I'm not sure when the @Modified method is called. At first it
seemed like @Modified would be the only callback I needed but it does not
seem to be called on "unbind". Now I suspect that it is enough with @Bind
and @Unbind - @Modified seems unnecessary.

What callbacks do I need to handle in order to react on all changes to the
list of required services?

/Bengt




2013/10/2 Bengt Rodehav <be...@rodehav.com>

> Thanks for your detailed response Clement!
>
> Sounds very interesting indeed although the fact that I can't change the
> optionality sounds like a show stopper to me. In my case the list of
> services to require can be >= 0. If, using config admin, I specify an empty
> list then the service dependency must be optional. If the list is non-empty
> then it must not be optional. I can't see how I can solve this using the
> interceptors (although I haven't read the documentation yet :-)).
>
> /Bengt
>
>
> 2013/10/2 clement escoffier <cl...@gmail.com>
>
>> Sent from my iPhone
>>
>> > On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
>> >
>> > Interesting. Do you think it would also be possible to do an
>> all-or-nothing
>> > approach? E g if I want to require A and B, I could check if both A and
>> B
>> > are available. If not, I would make the list empty thus making my
>> instance
>> > invalid? Or can I just say that the dependency is unresolved without
>> having
>> > to change the list?
>>
>> Yes you can to that. I would say that the easiest way is to implement
>> a ranking interceptor that returns an empty array until both services
>> are there. When both are there, it returns both.
>>
>> Notice that returning an empty array invalidates the dependency. For
>> the instance it would just means : no services.
>>
>> >
>> > BTW I did experiment a little with dynamically changing the "optionable"
>> > property of the requires dependency using the dependency manager. I
>> never
>> > did get that to work. It always stayed at the same value it got through
>> the
>> > Requires annotation. Is that as designed or a bug?
>> >
>>
>> Optionality cannot be changed, however the filter can. I can't
>> remember the exact reason for that.
>>
>> > I currently did a workaround using the life cycle controller as adviced
>> by
>> > Richard. Whenever anything changes that could affect the validity of the
>> > instance I recalculate the life cycle controller value to reflect that.
>> For
>> > instance if the list of dependencies change I recalculate and check if
>> all
>> > my required services are in the list. If not I set the controller value
>> to
>> > false.
>> > It works but the code is not very nice and easy to understand. It'll
>> have
>> > to do for now.
>> >
>>
>> I did like this several times and was never happy of the result,
>> especially it may mix, in your component code, business logic with
>> higher-level rules and data. Very hard to maintain on the long term,
>> unclear ad likely spaghetti-like. That's one of the reason we came up
>> with the interceptors.
>>
>>
>> > Clement, is the 1.10.x version released? I'm on a pretty old version and
>> > should probably upgrade. Also, is there any documentation regarding the
>> > interceptors you mentioned?
>>
>> The 1.10.1 was released in june. A 1.11 is under preparation (feature
>> complete, bug-fix complete, lacks some tests and documentation). We
>> plan to release it next week.
>>
>> The good news is that it includes the interceptor documentation.
>>
>> Clement
>>
>>
>> > /Bengt
>> >
>> >
>> > 2013/10/2 Clement Escoffier <cl...@gmail.com>
>> >
>> >> Hi,
>> >>
>> >> Not sure it would meet your requirements, but in the 1.10.x, we added
>> >> service dependency interceptors. Interceptors are external entities
>> >> involved in the service resolution. We have 3 types on interceptors:
>> >>
>> >> - tracking interceptors allow hiding services, or selecting the set of
>> >> services seen by the service dependency (the LDAP filter is a tracking
>> >> interceptor)
>> >> - ranking interceptors can change the order of the services (the
>> >> comparator is a ranking interceptor)
>> >> - binding interceptors can change the injected service objects (to be
>> used
>> >> with caution ;-))
>> >>
>> >> You can, without too much effort, write an interceptor that will shape
>> the
>> >> processor list as you want.
>> >>
>> >> As said above, interceptors are external entities. Actually, they are
>> >> services with a special 'target' property indicating in which
>> dependencies
>> >> they want to be involved. So, an interceptor can select one very
>> specific
>> >> dependency, all dependencies of an instance, all dependencies
>> targeting a
>> >> specific interface…
>> >>
>> >> Unfortunately, there is a long overdue issue about interceptors:
>> >> FELIX-4136 Document service dependency interceptors.
>> >>
>> >> Best regards,
>> >>
>> >> Clement
>> >>
>> >>
>> >>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>> >>>
>> >>> Thanks for your reply Richard.
>> >>>
>> >>> I am using a lifecycle controller already to make it possible to
>> >>> enable/disable my services via a GUI. I'll see if I can use it for
>> this
>> >>> purpose.
>> >>>
>> >>> I've also tried the following approach: Keep track of all possible
>> >> services
>> >>> that expose the interface I'm intererested in as follows:
>> >>>
>> >>> @Requires(optional = true)
>> >>> private IOrchestrationProcessor[] mProcessors;
>> >>>
>> >>> In runtime, when my service is being activated (prior to creating the
>> >> camel
>> >>> route) I check to see if all required processors exist, if not I
>> throw an
>> >>> exception. Unfortunately I have no control of in what order the
>> services
>> >>> will be activated so its hard to ever get the camel route created this
>> >> way.
>> >>> A lot of the time a "required" services is activated a bit later.
>> >>>
>> >>> /Bengt
>> >>>
>> >>>
>> >>>
>> >>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>> >>>
>> >>>>
>> >>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>> >>>>>
>> >>>>> I'm creating a dynamic processing component using iPOJO and Camel.
>> The
>> >>>>> idea
>> >>>>> is to dynamically specify (via config admin) a number of processor
>> >> id's.
>> >>>>> In
>> >>>>> runtime I want to find the matching processors (the processors are
>> >> Camel
>> >>>>> processors published as OSGi services) with the correct id.
>> >>>>>
>> >>>>> E g if I specify a list of services to {A,B} (FileInstall recognizes
>> >> this
>> >>>>> as a list). I want to require those services in order for my iPojo
>> >>>>> instance
>> >>>>> to become valid. It was much harder than I thought.
>> >>>>>
>> >>>>> I've tried something like:
>> >>>>>
>> >>>>>  @Property(name = "processors", mandatory = false, value = "")
>> >>>>>  public void setProcessors(String[] theProcessorIds) {
>> >>>>>    mProcessorIds = theProcessorIds;
>> >>>>>    updateProcessorFilter();
>> >>>>>  }
>> >>>>>
>> >>>>>  @Requires
>> >>>>>  private Processor[] mProcessors;
>> >>>>>
>> >>>>> The idea is that whenever the configuration property "processors" is
>> >>>>> updated, I dynamically update the ldap filter on the dependency
>> >>>>> mProcessors. I've used this approach before and it has worked when
>> >> using a
>> >>>>> single dependency (not an array).
>> >>>>>
>> >>>>> The problem is that I want to specifically require each specified
>> >>>>> processor. In the example above, I require one processor with id=A
>> AND
>> >> one
>> >>>>> processor with id=B. It's not enough with anyone of them since I
>> want
>> >> to
>> >>>>> invoke them one after another.
>> >>>>>
>> >>>>> Can I use a filter for this? I've been thinking of something like
>> this:
>> >>>>>
>> >>>>> (|(processorId=A)(processorId=**B))
>> >>>>>
>> >>>>> This would match both my processors but if one of them were missing
>> my
>> >>>>> instance would still become valid which I don't want.
>> >>>>
>> >>>> I don't think there is anyway to do what you want. This is
>> essentially
>> >> an
>> >>>> "N cardinality" requirement, where you want to say that you require
>> >>>> specifically N of something. Such requirements had been discussed
>> over
>> >> the
>> >>>> years for Service Binder, Declarative Services, etc., but we could
>> never
>> >>>> agree on their usefulness or how to do them, so we just left it as
>> it is
>> >>>> now (i.e., optional, at least one...).
>> >>>>
>> >>>> Other than adding some sort of threshold to service dependencies, I
>> >> don't
>> >>>> see this happening. You could potentially create an iPOJO lifecycle
>> >>>> controller that would keep your component invalid until it matched
>> the
>> >>>> required number of services (if you can get this information in the
>> >>>> handler)...or perhaps write/extend the service dependency handler.
>> >>>>
>> >>>> -> richard
>> >>>>
>> >>>>
>> >>>>> /Bengt
>> >>
>> ------------------------------**------------------------------**---------
>> >>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>> >> users-unsubscribe@felix.apache.org>
>> >>>> For additional commands, e-mail: users-help@felix.apache.org
>> >>
>> >>
>> >> ---------------------------------------------------------------------
>> >> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> >> For additional commands, e-mail: users-help@felix.apache.org
>> >>
>> >>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>

Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
Thanks for your detailed response Clement!

Sounds very interesting indeed although the fact that I can't change the
optionality sounds like a show stopper to me. In my case the list of
services to require can be >= 0. If, using config admin, I specify an empty
list then the service dependency must be optional. If the list is non-empty
then it must not be optional. I can't see how I can solve this using the
interceptors (although I haven't read the documentation yet :-)).

/Bengt


2013/10/2 clement escoffier <cl...@gmail.com>

> Sent from my iPhone
>
> > On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
> >
> > Interesting. Do you think it would also be possible to do an
> all-or-nothing
> > approach? E g if I want to require A and B, I could check if both A and B
> > are available. If not, I would make the list empty thus making my
> instance
> > invalid? Or can I just say that the dependency is unresolved without
> having
> > to change the list?
>
> Yes you can to that. I would say that the easiest way is to implement
> a ranking interceptor that returns an empty array until both services
> are there. When both are there, it returns both.
>
> Notice that returning an empty array invalidates the dependency. For
> the instance it would just means : no services.
>
> >
> > BTW I did experiment a little with dynamically changing the "optionable"
> > property of the requires dependency using the dependency manager. I never
> > did get that to work. It always stayed at the same value it got through
> the
> > Requires annotation. Is that as designed or a bug?
> >
>
> Optionality cannot be changed, however the filter can. I can't
> remember the exact reason for that.
>
> > I currently did a workaround using the life cycle controller as adviced
> by
> > Richard. Whenever anything changes that could affect the validity of the
> > instance I recalculate the life cycle controller value to reflect that.
> For
> > instance if the list of dependencies change I recalculate and check if
> all
> > my required services are in the list. If not I set the controller value
> to
> > false.
> > It works but the code is not very nice and easy to understand. It'll have
> > to do for now.
> >
>
> I did like this several times and was never happy of the result,
> especially it may mix, in your component code, business logic with
> higher-level rules and data. Very hard to maintain on the long term,
> unclear ad likely spaghetti-like. That's one of the reason we came up
> with the interceptors.
>
>
> > Clement, is the 1.10.x version released? I'm on a pretty old version and
> > should probably upgrade. Also, is there any documentation regarding the
> > interceptors you mentioned?
>
> The 1.10.1 was released in june. A 1.11 is under preparation (feature
> complete, bug-fix complete, lacks some tests and documentation). We
> plan to release it next week.
>
> The good news is that it includes the interceptor documentation.
>
> Clement
>
>
> > /Bengt
> >
> >
> > 2013/10/2 Clement Escoffier <cl...@gmail.com>
> >
> >> Hi,
> >>
> >> Not sure it would meet your requirements, but in the 1.10.x, we added
> >> service dependency interceptors. Interceptors are external entities
> >> involved in the service resolution. We have 3 types on interceptors:
> >>
> >> - tracking interceptors allow hiding services, or selecting the set of
> >> services seen by the service dependency (the LDAP filter is a tracking
> >> interceptor)
> >> - ranking interceptors can change the order of the services (the
> >> comparator is a ranking interceptor)
> >> - binding interceptors can change the injected service objects (to be
> used
> >> with caution ;-))
> >>
> >> You can, without too much effort, write an interceptor that will shape
> the
> >> processor list as you want.
> >>
> >> As said above, interceptors are external entities. Actually, they are
> >> services with a special 'target' property indicating in which
> dependencies
> >> they want to be involved. So, an interceptor can select one very
> specific
> >> dependency, all dependencies of an instance, all dependencies targeting
> a
> >> specific interface…
> >>
> >> Unfortunately, there is a long overdue issue about interceptors:
> >> FELIX-4136 Document service dependency interceptors.
> >>
> >> Best regards,
> >>
> >> Clement
> >>
> >>
> >>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
> >>>
> >>> Thanks for your reply Richard.
> >>>
> >>> I am using a lifecycle controller already to make it possible to
> >>> enable/disable my services via a GUI. I'll see if I can use it for this
> >>> purpose.
> >>>
> >>> I've also tried the following approach: Keep track of all possible
> >> services
> >>> that expose the interface I'm intererested in as follows:
> >>>
> >>> @Requires(optional = true)
> >>> private IOrchestrationProcessor[] mProcessors;
> >>>
> >>> In runtime, when my service is being activated (prior to creating the
> >> camel
> >>> route) I check to see if all required processors exist, if not I throw
> an
> >>> exception. Unfortunately I have no control of in what order the
> services
> >>> will be activated so its hard to ever get the camel route created this
> >> way.
> >>> A lot of the time a "required" services is activated a bit later.
> >>>
> >>> /Bengt
> >>>
> >>>
> >>>
> >>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
> >>>
> >>>>
> >>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
> >>>>>
> >>>>> I'm creating a dynamic processing component using iPOJO and Camel.
> The
> >>>>> idea
> >>>>> is to dynamically specify (via config admin) a number of processor
> >> id's.
> >>>>> In
> >>>>> runtime I want to find the matching processors (the processors are
> >> Camel
> >>>>> processors published as OSGi services) with the correct id.
> >>>>>
> >>>>> E g if I specify a list of services to {A,B} (FileInstall recognizes
> >> this
> >>>>> as a list). I want to require those services in order for my iPojo
> >>>>> instance
> >>>>> to become valid. It was much harder than I thought.
> >>>>>
> >>>>> I've tried something like:
> >>>>>
> >>>>>  @Property(name = "processors", mandatory = false, value = "")
> >>>>>  public void setProcessors(String[] theProcessorIds) {
> >>>>>    mProcessorIds = theProcessorIds;
> >>>>>    updateProcessorFilter();
> >>>>>  }
> >>>>>
> >>>>>  @Requires
> >>>>>  private Processor[] mProcessors;
> >>>>>
> >>>>> The idea is that whenever the configuration property "processors" is
> >>>>> updated, I dynamically update the ldap filter on the dependency
> >>>>> mProcessors. I've used this approach before and it has worked when
> >> using a
> >>>>> single dependency (not an array).
> >>>>>
> >>>>> The problem is that I want to specifically require each specified
> >>>>> processor. In the example above, I require one processor with id=A
> AND
> >> one
> >>>>> processor with id=B. It's not enough with anyone of them since I want
> >> to
> >>>>> invoke them one after another.
> >>>>>
> >>>>> Can I use a filter for this? I've been thinking of something like
> this:
> >>>>>
> >>>>> (|(processorId=A)(processorId=**B))
> >>>>>
> >>>>> This would match both my processors but if one of them were missing
> my
> >>>>> instance would still become valid which I don't want.
> >>>>
> >>>> I don't think there is anyway to do what you want. This is essentially
> >> an
> >>>> "N cardinality" requirement, where you want to say that you require
> >>>> specifically N of something. Such requirements had been discussed over
> >> the
> >>>> years for Service Binder, Declarative Services, etc., but we could
> never
> >>>> agree on their usefulness or how to do them, so we just left it as it
> is
> >>>> now (i.e., optional, at least one...).
> >>>>
> >>>> Other than adding some sort of threshold to service dependencies, I
> >> don't
> >>>> see this happening. You could potentially create an iPOJO lifecycle
> >>>> controller that would keep your component invalid until it matched the
> >>>> required number of services (if you can get this information in the
> >>>> handler)...or perhaps write/extend the service dependency handler.
> >>>>
> >>>> -> richard
> >>>>
> >>>>
> >>>>> /Bengt
> >>
> ------------------------------**------------------------------**---------
> >>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
> >> users-unsubscribe@felix.apache.org>
> >>>> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: iPOJO and dynamic requires

Posted by clement escoffier <cl...@gmail.com>.
Sent from my iPhone

> On 2 oct. 2013, at 20:32, Bengt Rodehav <be...@rodehav.com> wrote:
>
> Interesting. Do you think it would also be possible to do an all-or-nothing
> approach? E g if I want to require A and B, I could check if both A and B
> are available. If not, I would make the list empty thus making my instance
> invalid? Or can I just say that the dependency is unresolved without having
> to change the list?

Yes you can to that. I would say that the easiest way is to implement
a ranking interceptor that returns an empty array until both services
are there. When both are there, it returns both.

Notice that returning an empty array invalidates the dependency. For
the instance it would just means : no services.

>
> BTW I did experiment a little with dynamically changing the "optionable"
> property of the requires dependency using the dependency manager. I never
> did get that to work. It always stayed at the same value it got through the
> Requires annotation. Is that as designed or a bug?
>

Optionality cannot be changed, however the filter can. I can't
remember the exact reason for that.

> I currently did a workaround using the life cycle controller as adviced by
> Richard. Whenever anything changes that could affect the validity of the
> instance I recalculate the life cycle controller value to reflect that. For
> instance if the list of dependencies change I recalculate and check if all
> my required services are in the list. If not I set the controller value to
> false.
> It works but the code is not very nice and easy to understand. It'll have
> to do for now.
>

I did like this several times and was never happy of the result,
especially it may mix, in your component code, business logic with
higher-level rules and data. Very hard to maintain on the long term,
unclear ad likely spaghetti-like. That's one of the reason we came up
with the interceptors.


> Clement, is the 1.10.x version released? I'm on a pretty old version and
> should probably upgrade. Also, is there any documentation regarding the
> interceptors you mentioned?

The 1.10.1 was released in june. A 1.11 is under preparation (feature
complete, bug-fix complete, lacks some tests and documentation). We
plan to release it next week.

The good news is that it includes the interceptor documentation.

Clement


> /Bengt
>
>
> 2013/10/2 Clement Escoffier <cl...@gmail.com>
>
>> Hi,
>>
>> Not sure it would meet your requirements, but in the 1.10.x, we added
>> service dependency interceptors. Interceptors are external entities
>> involved in the service resolution. We have 3 types on interceptors:
>>
>> - tracking interceptors allow hiding services, or selecting the set of
>> services seen by the service dependency (the LDAP filter is a tracking
>> interceptor)
>> - ranking interceptors can change the order of the services (the
>> comparator is a ranking interceptor)
>> - binding interceptors can change the injected service objects (to be used
>> with caution ;-))
>>
>> You can, without too much effort, write an interceptor that will shape the
>> processor list as you want.
>>
>> As said above, interceptors are external entities. Actually, they are
>> services with a special 'target' property indicating in which dependencies
>> they want to be involved. So, an interceptor can select one very specific
>> dependency, all dependencies of an instance, all dependencies targeting a
>> specific interface…
>>
>> Unfortunately, there is a long overdue issue about interceptors:
>> FELIX-4136 Document service dependency interceptors.
>>
>> Best regards,
>>
>> Clement
>>
>>
>>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>>>
>>> Thanks for your reply Richard.
>>>
>>> I am using a lifecycle controller already to make it possible to
>>> enable/disable my services via a GUI. I'll see if I can use it for this
>>> purpose.
>>>
>>> I've also tried the following approach: Keep track of all possible
>> services
>>> that expose the interface I'm intererested in as follows:
>>>
>>> @Requires(optional = true)
>>> private IOrchestrationProcessor[] mProcessors;
>>>
>>> In runtime, when my service is being activated (prior to creating the
>> camel
>>> route) I check to see if all required processors exist, if not I throw an
>>> exception. Unfortunately I have no control of in what order the services
>>> will be activated so its hard to ever get the camel route created this
>> way.
>>> A lot of the time a "required" services is activated a bit later.
>>>
>>> /Bengt
>>>
>>>
>>>
>>> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>>>
>>>>
>>>>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>>>>>
>>>>> I'm creating a dynamic processing component using iPOJO and Camel. The
>>>>> idea
>>>>> is to dynamically specify (via config admin) a number of processor
>> id's.
>>>>> In
>>>>> runtime I want to find the matching processors (the processors are
>> Camel
>>>>> processors published as OSGi services) with the correct id.
>>>>>
>>>>> E g if I specify a list of services to {A,B} (FileInstall recognizes
>> this
>>>>> as a list). I want to require those services in order for my iPojo
>>>>> instance
>>>>> to become valid. It was much harder than I thought.
>>>>>
>>>>> I've tried something like:
>>>>>
>>>>>  @Property(name = "processors", mandatory = false, value = "")
>>>>>  public void setProcessors(String[] theProcessorIds) {
>>>>>    mProcessorIds = theProcessorIds;
>>>>>    updateProcessorFilter();
>>>>>  }
>>>>>
>>>>>  @Requires
>>>>>  private Processor[] mProcessors;
>>>>>
>>>>> The idea is that whenever the configuration property "processors" is
>>>>> updated, I dynamically update the ldap filter on the dependency
>>>>> mProcessors. I've used this approach before and it has worked when
>> using a
>>>>> single dependency (not an array).
>>>>>
>>>>> The problem is that I want to specifically require each specified
>>>>> processor. In the example above, I require one processor with id=A AND
>> one
>>>>> processor with id=B. It's not enough with anyone of them since I want
>> to
>>>>> invoke them one after another.
>>>>>
>>>>> Can I use a filter for this? I've been thinking of something like this:
>>>>>
>>>>> (|(processorId=A)(processorId=**B))
>>>>>
>>>>> This would match both my processors but if one of them were missing my
>>>>> instance would still become valid which I don't want.
>>>>
>>>> I don't think there is anyway to do what you want. This is essentially
>> an
>>>> "N cardinality" requirement, where you want to say that you require
>>>> specifically N of something. Such requirements had been discussed over
>> the
>>>> years for Service Binder, Declarative Services, etc., but we could never
>>>> agree on their usefulness or how to do them, so we just left it as it is
>>>> now (i.e., optional, at least one...).
>>>>
>>>> Other than adding some sort of threshold to service dependencies, I
>> don't
>>>> see this happening. You could potentially create an iPOJO lifecycle
>>>> controller that would keep your component invalid until it matched the
>>>> required number of services (if you can get this information in the
>>>> handler)...or perhaps write/extend the service dependency handler.
>>>>
>>>> -> richard
>>>>
>>>>
>>>>> /Bengt
>> ------------------------------**------------------------------**---------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>> users-unsubscribe@felix.apache.org>
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
Aha, I just saw what FELIX-4136 is all about...

/Bengt


2013/10/2 Bengt Rodehav <be...@rodehav.com>

> Interesting. Do you think it would also be possible to do an
> all-or-nothing approach? E g if I want to require A and B, I could check if
> both A and B are available. If not, I would make the list empty thus making
> my instance invalid? Or can I just say that the dependency is unresolved
> without having to change the list?
>
> BTW I did experiment a little with dynamically changing the "optionable"
> property of the requires dependency using the dependency manager. I never
> did get that to work. It always stayed at the same value it got through the
> Requires annotation. Is that as designed or a bug?
>
> I currently did a workaround using the life cycle controller as adviced by
> Richard. Whenever anything changes that could affect the validity of the
> instance I recalculate the life cycle controller value to reflect that. For
> instance if the list of dependencies change I recalculate and check if all
> my required services are in the list. If not I set the controller value to
> false.
>
> It works but the code is not very nice and easy to understand. It'll have
> to do for now.
>
> Clement, is the 1.10.x version released? I'm on a pretty old version and
> should probably upgrade. Also, is there any documentation regarding the
> interceptors you mentioned?
>
> /Bengt
>
>
> 2013/10/2 Clement Escoffier <cl...@gmail.com>
>
>> Hi,
>>
>> Not sure it would meet your requirements, but in the 1.10.x, we added
>> service dependency interceptors. Interceptors are external entities
>> involved in the service resolution. We have 3 types on interceptors:
>>
>> - tracking interceptors allow hiding services, or selecting the set of
>> services seen by the service dependency (the LDAP filter is a tracking
>> interceptor)
>> - ranking interceptors can change the order of the services (the
>> comparator is a ranking interceptor)
>> - binding interceptors can change the injected service objects (to be
>> used with caution ;-))
>>
>> You can, without too much effort, write an interceptor that will shape
>> the processor list as you want.
>>
>> As said above, interceptors are external entities. Actually, they are
>> services with a special 'target' property indicating in which dependencies
>> they want to be involved. So, an interceptor can select one very specific
>> dependency, all dependencies of an instance, all dependencies targeting a
>> specific interface…
>>
>> Unfortunately, there is a long overdue issue about interceptors:
>> FELIX-4136 Document service dependency interceptors.
>>
>> Best regards,
>>
>> Clement
>>
>>
>> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>>
>> > Thanks for your reply Richard.
>> >
>> > I am using a lifecycle controller already to make it possible to
>> > enable/disable my services via a GUI. I'll see if I can use it for this
>> > purpose.
>> >
>> > I've also tried the following approach: Keep track of all possible
>> services
>> > that expose the interface I'm intererested in as follows:
>> >
>> >  @Requires(optional = true)
>> >  private IOrchestrationProcessor[] mProcessors;
>> >
>> > In runtime, when my service is being activated (prior to creating the
>> camel
>> > route) I check to see if all required processors exist, if not I throw
>> an
>> > exception. Unfortunately I have no control of in what order the services
>> > will be activated so its hard to ever get the camel route created this
>> way.
>> > A lot of the time a "required" services is activated a bit later.
>> >
>> > /Bengt
>> >
>> >
>> >
>> > 2013/10/2 Richard S. Hall <he...@ungoverned.org>
>> >
>> >>
>> >> On 10/2/13 08:42 , Bengt Rodehav wrote:
>> >>
>> >>> I'm creating a dynamic processing component using iPOJO and Camel. The
>> >>> idea
>> >>> is to dynamically specify (via config admin) a number of processor
>> id's.
>> >>> In
>> >>> runtime I want to find the matching processors (the processors are
>> Camel
>> >>> processors published as OSGi services) with the correct id.
>> >>>
>> >>> E g if I specify a list of services to {A,B} (FileInstall recognizes
>> this
>> >>> as a list). I want to require those services in order for my iPojo
>> >>> instance
>> >>> to become valid. It was much harder than I thought.
>> >>>
>> >>> I've tried something like:
>> >>>
>> >>>   @Property(name = "processors", mandatory = false, value = "")
>> >>>   public void setProcessors(String[] theProcessorIds) {
>> >>>     mProcessorIds = theProcessorIds;
>> >>>     updateProcessorFilter();
>> >>>   }
>> >>>
>> >>>   @Requires
>> >>>   private Processor[] mProcessors;
>> >>>
>> >>> The idea is that whenever the configuration property "processors" is
>> >>> updated, I dynamically update the ldap filter on the dependency
>> >>> mProcessors. I've used this approach before and it has worked when
>> using a
>> >>> single dependency (not an array).
>> >>>
>> >>> The problem is that I want to specifically require each specified
>> >>> processor. In the example above, I require one processor with id=A
>> AND one
>> >>> processor with id=B. It's not enough with anyone of them since I want
>> to
>> >>> invoke them one after another.
>> >>>
>> >>> Can I use a filter for this? I've been thinking of something like
>> this:
>> >>>
>> >>> (|(processorId=A)(processorId=**B))
>> >>>
>> >>> This would match both my processors but if one of them were missing my
>> >>> instance would still become valid which I don't want.
>> >>>
>> >>
>> >> I don't think there is anyway to do what you want. This is essentially
>> an
>> >> "N cardinality" requirement, where you want to say that you require
>> >> specifically N of something. Such requirements had been discussed over
>> the
>> >> years for Service Binder, Declarative Services, etc., but we could
>> never
>> >> agree on their usefulness or how to do them, so we just left it as it
>> is
>> >> now (i.e., optional, at least one...).
>> >>
>> >> Other than adding some sort of threshold to service dependencies, I
>> don't
>> >> see this happening. You could potentially create an iPOJO lifecycle
>> >> controller that would keep your component invalid until it matched the
>> >> required number of services (if you can get this information in the
>> >> handler)...or perhaps write/extend the service dependency handler.
>> >>
>> >> -> richard
>> >>
>> >>
>> >>> /Bengt
>> >>>
>> >>>
>> >>
>> >>
>> ------------------------------**------------------------------**---------
>> >> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
>> users-unsubscribe@felix.apache.org>
>> >> For additional commands, e-mail: users-help@felix.apache.org
>> >>
>> >>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>

Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
Interesting. Do you think it would also be possible to do an all-or-nothing
approach? E g if I want to require A and B, I could check if both A and B
are available. If not, I would make the list empty thus making my instance
invalid? Or can I just say that the dependency is unresolved without having
to change the list?

BTW I did experiment a little with dynamically changing the "optionable"
property of the requires dependency using the dependency manager. I never
did get that to work. It always stayed at the same value it got through the
Requires annotation. Is that as designed or a bug?

I currently did a workaround using the life cycle controller as adviced by
Richard. Whenever anything changes that could affect the validity of the
instance I recalculate the life cycle controller value to reflect that. For
instance if the list of dependencies change I recalculate and check if all
my required services are in the list. If not I set the controller value to
false.

It works but the code is not very nice and easy to understand. It'll have
to do for now.

Clement, is the 1.10.x version released? I'm on a pretty old version and
should probably upgrade. Also, is there any documentation regarding the
interceptors you mentioned?

/Bengt


2013/10/2 Clement Escoffier <cl...@gmail.com>

> Hi,
>
> Not sure it would meet your requirements, but in the 1.10.x, we added
> service dependency interceptors. Interceptors are external entities
> involved in the service resolution. We have 3 types on interceptors:
>
> - tracking interceptors allow hiding services, or selecting the set of
> services seen by the service dependency (the LDAP filter is a tracking
> interceptor)
> - ranking interceptors can change the order of the services (the
> comparator is a ranking interceptor)
> - binding interceptors can change the injected service objects (to be used
> with caution ;-))
>
> You can, without too much effort, write an interceptor that will shape the
> processor list as you want.
>
> As said above, interceptors are external entities. Actually, they are
> services with a special 'target' property indicating in which dependencies
> they want to be involved. So, an interceptor can select one very specific
> dependency, all dependencies of an instance, all dependencies targeting a
> specific interface…
>
> Unfortunately, there is a long overdue issue about interceptors:
> FELIX-4136 Document service dependency interceptors.
>
> Best regards,
>
> Clement
>
>
> On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:
>
> > Thanks for your reply Richard.
> >
> > I am using a lifecycle controller already to make it possible to
> > enable/disable my services via a GUI. I'll see if I can use it for this
> > purpose.
> >
> > I've also tried the following approach: Keep track of all possible
> services
> > that expose the interface I'm intererested in as follows:
> >
> >  @Requires(optional = true)
> >  private IOrchestrationProcessor[] mProcessors;
> >
> > In runtime, when my service is being activated (prior to creating the
> camel
> > route) I check to see if all required processors exist, if not I throw an
> > exception. Unfortunately I have no control of in what order the services
> > will be activated so its hard to ever get the camel route created this
> way.
> > A lot of the time a "required" services is activated a bit later.
> >
> > /Bengt
> >
> >
> >
> > 2013/10/2 Richard S. Hall <he...@ungoverned.org>
> >
> >>
> >> On 10/2/13 08:42 , Bengt Rodehav wrote:
> >>
> >>> I'm creating a dynamic processing component using iPOJO and Camel. The
> >>> idea
> >>> is to dynamically specify (via config admin) a number of processor
> id's.
> >>> In
> >>> runtime I want to find the matching processors (the processors are
> Camel
> >>> processors published as OSGi services) with the correct id.
> >>>
> >>> E g if I specify a list of services to {A,B} (FileInstall recognizes
> this
> >>> as a list). I want to require those services in order for my iPojo
> >>> instance
> >>> to become valid. It was much harder than I thought.
> >>>
> >>> I've tried something like:
> >>>
> >>>   @Property(name = "processors", mandatory = false, value = "")
> >>>   public void setProcessors(String[] theProcessorIds) {
> >>>     mProcessorIds = theProcessorIds;
> >>>     updateProcessorFilter();
> >>>   }
> >>>
> >>>   @Requires
> >>>   private Processor[] mProcessors;
> >>>
> >>> The idea is that whenever the configuration property "processors" is
> >>> updated, I dynamically update the ldap filter on the dependency
> >>> mProcessors. I've used this approach before and it has worked when
> using a
> >>> single dependency (not an array).
> >>>
> >>> The problem is that I want to specifically require each specified
> >>> processor. In the example above, I require one processor with id=A AND
> one
> >>> processor with id=B. It's not enough with anyone of them since I want
> to
> >>> invoke them one after another.
> >>>
> >>> Can I use a filter for this? I've been thinking of something like this:
> >>>
> >>> (|(processorId=A)(processorId=**B))
> >>>
> >>> This would match both my processors but if one of them were missing my
> >>> instance would still become valid which I don't want.
> >>>
> >>
> >> I don't think there is anyway to do what you want. This is essentially
> an
> >> "N cardinality" requirement, where you want to say that you require
> >> specifically N of something. Such requirements had been discussed over
> the
> >> years for Service Binder, Declarative Services, etc., but we could never
> >> agree on their usefulness or how to do them, so we just left it as it is
> >> now (i.e., optional, at least one...).
> >>
> >> Other than adding some sort of threshold to service dependencies, I
> don't
> >> see this happening. You could potentially create an iPOJO lifecycle
> >> controller that would keep your component invalid until it matched the
> >> required number of services (if you can get this information in the
> >> handler)...or perhaps write/extend the service dependency handler.
> >>
> >> -> richard
> >>
> >>
> >>> /Bengt
> >>>
> >>>
> >>
> >>
> ------------------------------**------------------------------**---------
> >> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<
> users-unsubscribe@felix.apache.org>
> >> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: iPOJO and dynamic requires

Posted by Clement Escoffier <cl...@gmail.com>.
Hi,

Not sure it would meet your requirements, but in the 1.10.x, we added service dependency interceptors. Interceptors are external entities involved in the service resolution. We have 3 types on interceptors:

- tracking interceptors allow hiding services, or selecting the set of services seen by the service dependency (the LDAP filter is a tracking interceptor)
- ranking interceptors can change the order of the services (the comparator is a ranking interceptor)
- binding interceptors can change the injected service objects (to be used with caution ;-))

You can, without too much effort, write an interceptor that will shape the processor list as you want.

As said above, interceptors are external entities. Actually, they are services with a special 'target' property indicating in which dependencies they want to be involved. So, an interceptor can select one very specific dependency, all dependencies of an instance, all dependencies targeting a specific interface…

Unfortunately, there is a long overdue issue about interceptors: FELIX-4136 Document service dependency interceptors.

Best regards,

Clement


On 2 oct. 2013, at 15:57, Bengt Rodehav <be...@rodehav.com> wrote:

> Thanks for your reply Richard.
> 
> I am using a lifecycle controller already to make it possible to
> enable/disable my services via a GUI. I'll see if I can use it for this
> purpose.
> 
> I've also tried the following approach: Keep track of all possible services
> that expose the interface I'm intererested in as follows:
> 
>  @Requires(optional = true)
>  private IOrchestrationProcessor[] mProcessors;
> 
> In runtime, when my service is being activated (prior to creating the camel
> route) I check to see if all required processors exist, if not I throw an
> exception. Unfortunately I have no control of in what order the services
> will be activated so its hard to ever get the camel route created this way.
> A lot of the time a "required" services is activated a bit later.
> 
> /Bengt
> 
> 
> 
> 2013/10/2 Richard S. Hall <he...@ungoverned.org>
> 
>> 
>> On 10/2/13 08:42 , Bengt Rodehav wrote:
>> 
>>> I'm creating a dynamic processing component using iPOJO and Camel. The
>>> idea
>>> is to dynamically specify (via config admin) a number of processor id's.
>>> In
>>> runtime I want to find the matching processors (the processors are Camel
>>> processors published as OSGi services) with the correct id.
>>> 
>>> E g if I specify a list of services to {A,B} (FileInstall recognizes this
>>> as a list). I want to require those services in order for my iPojo
>>> instance
>>> to become valid. It was much harder than I thought.
>>> 
>>> I've tried something like:
>>> 
>>>   @Property(name = "processors", mandatory = false, value = "")
>>>   public void setProcessors(String[] theProcessorIds) {
>>>     mProcessorIds = theProcessorIds;
>>>     updateProcessorFilter();
>>>   }
>>> 
>>>   @Requires
>>>   private Processor[] mProcessors;
>>> 
>>> The idea is that whenever the configuration property "processors" is
>>> updated, I dynamically update the ldap filter on the dependency
>>> mProcessors. I've used this approach before and it has worked when using a
>>> single dependency (not an array).
>>> 
>>> The problem is that I want to specifically require each specified
>>> processor. In the example above, I require one processor with id=A AND one
>>> processor with id=B. It's not enough with anyone of them since I want to
>>> invoke them one after another.
>>> 
>>> Can I use a filter for this? I've been thinking of something like this:
>>> 
>>> (|(processorId=A)(processorId=**B))
>>> 
>>> This would match both my processors but if one of them were missing my
>>> instance would still become valid which I don't want.
>>> 
>> 
>> I don't think there is anyway to do what you want. This is essentially an
>> "N cardinality" requirement, where you want to say that you require
>> specifically N of something. Such requirements had been discussed over the
>> years for Service Binder, Declarative Services, etc., but we could never
>> agree on their usefulness or how to do them, so we just left it as it is
>> now (i.e., optional, at least one...).
>> 
>> Other than adding some sort of threshold to service dependencies, I don't
>> see this happening. You could potentially create an iPOJO lifecycle
>> controller that would keep your component invalid until it matched the
>> required number of services (if you can get this information in the
>> handler)...or perhaps write/extend the service dependency handler.
>> 
>> -> richard
>> 
>> 
>>> /Bengt
>>> 
>>> 
>> 
>> ------------------------------**------------------------------**---------
>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: iPOJO and dynamic requires

Posted by Bengt Rodehav <be...@rodehav.com>.
Thanks for your reply Richard.

I am using a lifecycle controller already to make it possible to
enable/disable my services via a GUI. I'll see if I can use it for this
purpose.

I've also tried the following approach: Keep track of all possible services
that expose the interface I'm intererested in as follows:

  @Requires(optional = true)
  private IOrchestrationProcessor[] mProcessors;

In runtime, when my service is being activated (prior to creating the camel
route) I check to see if all required processors exist, if not I throw an
exception. Unfortunately I have no control of in what order the services
will be activated so its hard to ever get the camel route created this way.
A lot of the time a "required" services is activated a bit later.

/Bengt



2013/10/2 Richard S. Hall <he...@ungoverned.org>

>
> On 10/2/13 08:42 , Bengt Rodehav wrote:
>
>> I'm creating a dynamic processing component using iPOJO and Camel. The
>> idea
>> is to dynamically specify (via config admin) a number of processor id's.
>> In
>> runtime I want to find the matching processors (the processors are Camel
>> processors published as OSGi services) with the correct id.
>>
>> E g if I specify a list of services to {A,B} (FileInstall recognizes this
>> as a list). I want to require those services in order for my iPojo
>> instance
>> to become valid. It was much harder than I thought.
>>
>> I've tried something like:
>>
>>    @Property(name = "processors", mandatory = false, value = "")
>>    public void setProcessors(String[] theProcessorIds) {
>>      mProcessorIds = theProcessorIds;
>>      updateProcessorFilter();
>>    }
>>
>>    @Requires
>>    private Processor[] mProcessors;
>>
>> The idea is that whenever the configuration property "processors" is
>> updated, I dynamically update the ldap filter on the dependency
>> mProcessors. I've used this approach before and it has worked when using a
>> single dependency (not an array).
>>
>> The problem is that I want to specifically require each specified
>> processor. In the example above, I require one processor with id=A AND one
>> processor with id=B. It's not enough with anyone of them since I want to
>> invoke them one after another.
>>
>> Can I use a filter for this? I've been thinking of something like this:
>>
>> (|(processorId=A)(processorId=**B))
>>
>> This would match both my processors but if one of them were missing my
>> instance would still become valid which I don't want.
>>
>
> I don't think there is anyway to do what you want. This is essentially an
> "N cardinality" requirement, where you want to say that you require
> specifically N of something. Such requirements had been discussed over the
> years for Service Binder, Declarative Services, etc., but we could never
> agree on their usefulness or how to do them, so we just left it as it is
> now (i.e., optional, at least one...).
>
> Other than adding some sort of threshold to service dependencies, I don't
> see this happening. You could potentially create an iPOJO lifecycle
> controller that would keep your component invalid until it matched the
> required number of services (if you can get this information in the
> handler)...or perhaps write/extend the service dependency handler.
>
> -> richard
>
>
>> /Bengt
>>
>>
>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: iPOJO and dynamic requires

Posted by "Richard S. Hall" <he...@ungoverned.org>.
On 10/2/13 08:42 , Bengt Rodehav wrote:
> I'm creating a dynamic processing component using iPOJO and Camel. The idea
> is to dynamically specify (via config admin) a number of processor id's. In
> runtime I want to find the matching processors (the processors are Camel
> processors published as OSGi services) with the correct id.
>
> E g if I specify a list of services to {A,B} (FileInstall recognizes this
> as a list). I want to require those services in order for my iPojo instance
> to become valid. It was much harder than I thought.
>
> I've tried something like:
>
>    @Property(name = "processors", mandatory = false, value = "")
>    public void setProcessors(String[] theProcessorIds) {
>      mProcessorIds = theProcessorIds;
>      updateProcessorFilter();
>    }
>
>    @Requires
>    private Processor[] mProcessors;
>
> The idea is that whenever the configuration property "processors" is
> updated, I dynamically update the ldap filter on the dependency
> mProcessors. I've used this approach before and it has worked when using a
> single dependency (not an array).
>
> The problem is that I want to specifically require each specified
> processor. In the example above, I require one processor with id=A AND one
> processor with id=B. It's not enough with anyone of them since I want to
> invoke them one after another.
>
> Can I use a filter for this? I've been thinking of something like this:
>
> (|(processorId=A)(processorId=B))
>
> This would match both my processors but if one of them were missing my
> instance would still become valid which I don't want.

I don't think there is anyway to do what you want. This is essentially 
an "N cardinality" requirement, where you want to say that you require 
specifically N of something. Such requirements had been discussed over 
the years for Service Binder, Declarative Services, etc., but we could 
never agree on their usefulness or how to do them, so we just left it as 
it is now (i.e., optional, at least one...).

Other than adding some sort of threshold to service dependencies, I 
don't see this happening. You could potentially create an iPOJO 
lifecycle controller that would keep your component invalid until it 
matched the required number of services (if you can get this information 
in the handler)...or perhaps write/extend the service dependency handler.

-> richard

>
> /Bengt
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org