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

