felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bengt Rodehav <be...@rodehav.com>
Subject Re: iPOJO and dynamic requires
Date Fri, 04 Oct 2013 06:22:27 GMT
Looking forward to it!

/Bengt


2013/10/3 Clement Escoffier <clement.escoffier@gmail.com>

>
> On 3 oct. 2013, at 20:08, Bengt Rodehav <bengt@rodehav.com> 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 <bengt@rodehav.com>
> >
> >> 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 <clement.escoffier@gmail.com>
> >>
> >>> Hi,
> >>>
> >>> On 3 oct. 2013, at 08:33, Bengt Rodehav <bengt@rodehav.com> 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 <bengt@rodehav.com>
> >>>>
> >>>>> 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 <clement.escoffier@gmail.com>
> >>>>>
> >>>>>> Sent from my iPhone
> >>>>>>
> >>>>>>> On 2 oct. 2013, at 20:32, Bengt Rodehav <bengt@rodehav.com>
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 <clement.escoffier@gmail.com>
> >>>>>>>
> >>>>>>>> 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 <bengt@rodehav.com>
> 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 <heavy@ungoverned.org>
> >>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>> 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<
> >>>>>>>> users-unsubscribe@felix.apache.org>
> >>>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>> ---------------------------------------------------------------------
> >>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>>>
> >>>>>>>>
> >>>>>>
> >>>>>>
> ---------------------------------------------------------------------
> >>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>>>
> >>>>>>
> >>>>>
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>> For additional commands, e-mail: users-help@felix.apache.org
> >>>
> >>>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message