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 <[email protected]>

> Hi,
>
> On 3 oct. 2013, at 08:33, Bengt Rodehav <[email protected]> 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 <[email protected]>
> >
> >> 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 <[email protected]>
> >>
> >>> Sent from my iPhone
> >>>
> >>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <[email protected]> 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 <[email protected]>
> >>>>
> >>>>> 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 <[email protected]> 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 <[email protected]>
> >>>>>>
> >>>>>>>
> >>>>>>>> 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<
> >>>>> [email protected]>
> >>>>>>> For additional commands, e-mail: [email protected]
> >>>>>
> >>>>>
> >>>>> ---------------------------------------------------------------------
> >>>>> To unsubscribe, e-mail: [email protected]
> >>>>> For additional commands, e-mail: [email protected]
> >>>>>
> >>>>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: [email protected]
> >>> For additional commands, e-mail: [email protected]
> >>>
> >>>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>

Reply via email to