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

> Hi,
>
> On 3 oct. 2013, at 12:09, Bengt Rodehav <[email protected]> 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 <[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]
>
>

Reply via email to