Looking forward to it! /Bengt
2013/10/3 Clement Escoffier <[email protected]> > > On 3 oct. 2013, at 20:08, Bengt Rodehav <[email protected]> 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 <[email protected]> > > > >> 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] > >>> > >>> > >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >

