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]
>
>

Reply via email to