felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bengt Rodehav <be...@rodehav.com>
Subject Re: Using iPojo interceptors
Date Thu, 28 Nov 2013 11:17:52 GMT
Hello again Clement!

I was away on business yesterday which is why I'm late replying.

I've come a bit further now but still have problems accessing my
component's "extenders" property. Here is what my code looks like now:

*  public List<ServiceReference> getServiceReferences(DependencyModel
theDependencyModel,*
*      List<ServiceReference> theMatching) {*

*    ComponentInstance instance =
theDependencyModel.getComponentInstance();*
*    InstanceDescription instanceDescription =
instance.getInstanceDescription();*
*    ComponentTypeDescription componentTypeDescription =
instanceDescription.getComponentDescription();*
*    String factoryName =
componentTypeDescription.getFactory().getFactoryName();*

*    if (FACTORY_NAME.equals(factoryName)) {*
*      System.out.println("Found a GenericService2");*
*      ConfigurationHandlerDescription configHandlerDescription =
(ConfigurationHandlerDescription) instanceDescription*
*          .getHandlerDescription("org.apache.felix.ipojo.properties");*
*      int state = instanceDescription.getState();*
*      System.out.println("State: " + state);*
*      if(ComponentInstance.VALID == instanceDescription.getState()) {*
*        PropertyDescription propDesc =
configHandlerDescription.getPropertyByName("extenders"); // NPE*
*        if(propDesc != null) {*
*          String extenders = propDesc.getValue();*
*          System.out.println("Extenders: " + extenders);*
*        }*
*        else {*
*          System.out.println("Extenders is null");*
*        }*
*      }*
*    }*

I check the factory name to determine if this is a component that I should
intercept. Presently I wait until the component is valid but I'm not sure
if I can wait since my interceptor has to kick in before that. Presently I
 get a null pointer exception when I try to retrieve my property. Do you
have any idea why? It doesn't seem possible to retrieve properties at this
pont.

I also noticed that the method PropertyDescription.getValue() always
returns a String. In my case the underlying object is an array of String
(String[]). Is it possible to get the value in the correct type?

/Bengt

























2013/11/27 Clement Escoffier <clement.escoffier@gmail.com>

> Hi,
>
> On 26 nov. 2013, at 16:00, Bengt Rodehav <bengt@rodehav.com> wrote:
>
> > I'm getting a bit closer regarding the interceptors. Still two problems
> for
> > me:
> >
> > a) I still don't understand how to get hold of my intercepted instance
> from
> > within my interceptor. I get a reference to a DependencyModel from which
> I
> > can get a ComponentInstance. But how do I go from there to my ComponentA
> > class. I need to access the property "extenders" in order for my
> > interceptor to do its job.
> >
>
> It depends how how is managed the extender property, let’s imagine it’s a
> @Property. In this case, from the Dependency Model, you can retrieve the
> component instance. From the instance, you have access to the introspection
> layer (getInstanceDescription()), which let you analyze the iPOJO container.
>
> To be a bit more clear, let’s see some code:
>
> //First retrieve the configuration handler description from the instance
> container:
> ConfigurationHandlerDescription description =
> (ConfigurationHandlerDescription)
> model.getComponentInstance().getInstanceDescription().getHandlerDescription("org.apache.felix.ipojo.properties”);
> // Find the extenders property
> String extenders = description.getPropertyByName("extenders").getValue();
> // You have your value !
>
> > b) Also, when the property "extenders" is changed, I need to force the
> > interceptor to recalculate the dependencies. How can I accomplish that?
>
> It also depends on how this reconfiguration happen. Let’s say that the
> instance is reconfigured from the configuration admin or iPOJO
> reconfiguration abilities. In these case being notified is quite simple, as
> you can register a ConfigurationListener on the
> ConfigurationHandlerDescription object:
>
> description.addListener(new ConfigurationListener() {
>             public void configurationChanged(ComponentInstance instance,
> Map<String, Object> configuration) {
>                 // The extender property may have been modified
>             }
>         });
>
> Don’t forget to unregister the listener when the interceptor is unplugged
> from the instance.
>
> >
> > Getting deeper into iPojo than I've been before…
>
> It’s just the beginning…. (contributions are welcome if you see some
> dark(er) area)
>
> >
> > /Bengt
> >
> >
> > 2013/11/26 Bengt Rodehav <bengt@rodehav.com>
> >
> >> Thanks Clement!
> >>
> >>
> >> 2013/11/26 Clement Escoffier <clement.escoffier@gmail.com>
> >>
> >>> Hi,
> >>>
> >>> On 25 nov. 2013, at 20:19, Bengt Rodehav <bengt@rodehav.com> wrote:
> >>>
> >>>> Hello Clement and as always thanks for your detailed answer!
> >>>>
> >>>
> >>> You’re welcome.
> >>>
> >>>> It does seem a bit complicated to "require" an interceptor. Perhaps
an
> >>>> easier way of doing this might be possible in the future.
> >>>
> >>> I think it would be a good addition. Thinking about it.
> >>>
> >>>> Anyway, I'm not
> >>>> exactly sure that I understood what you meant. Just to clarify:
> >>>>
> >>>> My Component A (the component to be intercepted) has the following
> code:
> >>>>
> >>>> @Property(name = "extenders", mandatory = false)
> >>>> private String[] mExtenderIds;
> >>>>
> >>>> @Requires(optional = true, id = "extenders")
> >>>> private IExtender[] mExtenders;
> >>>>
> >>>> Do you mean that I should put a filter on the @Requires with
> >>> id="extenders"
> >>>> (the intercepted = true) so that it can only be satisfied if my
> >>> interceptor
> >>>> has added that property?
> >>>
> >>> Exactly.
> >>>
> >>>>
> >>>> But how do I then handle the situation where my Component A does not
> >>>> require any extenders? In that case I was planning on setting the
> >>>> dependency to optional to make my instance valid without any
> extenders.
> >>>>
> >>>> Or, perhaps I could first set the @Requires to mandatory (with the
> >>> filter):
> >>>>
> >>>> @Requires(optional = false, id = "extenders",
> >>> filter="(intercepted=true)")
> >>>> private IExtender[] mExtenders;
> >>>>
> >>>> Then, if my interceptor sees that the instance does not require any
> >>>> extenders it can set the dependency to become optional. This way I
> both
> >>>> require the interceptor (via the filter) and I ensure that the only
> way
> >>> to
> >>>> allow the instance to be valid without the dependency is if the
> >>> interceptor
> >>>> has explicitly set the dependency to optional.
> >>>
> >>> That would work. You can change the optionality status of the
> dependency
> >>> from the dependency model you get in the interceptor.
> >>>
> >>> Regards,
> >>>
> >>> Clement
> >>>
> >>>>
> >>>> /Bengt
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> 2013/11/25 Clement Escoffier <clement.escoffier@gmail.com>
> >>>>
> >>>>> Hi,
> >>>>>
> >>>>>
> >>>>> On 25 nov. 2013, at 11:04, Bengt Rodehav <bengt@rodehav.com>
wrote:
> >>>>>
> >>>>>> I've started to investigate using iPojo interceptors. I'm using
> iPojo
> >>>>>> version 1.11.0. I want to accomplish the following:
> >>>>>>
> >>>>>> Component A can be "extended" by specifying a list of (required)
> >>>>>> "extenders" (actually their id's), like this:
> >>>>>>
> >>>>>> @Property(name = "extenders", mandatory = false)
> >>>>>> private String[] mExtenderIds;
> >>>>>>
> >>>>>> @Requires(optional = true, id = "extenders")
> >>>>>> private IExtender[] mExtenders;
> >>>>>>
> >>>>>>
> >>>>>> The property is optional but if any extenderId's are listed
then the
> >>>>>> @Requires should require that IExtender's with the corresponding
> >>>>> extenderId
> >>>>>> is started.
> >>>>>>
> >>>>>> The IExtender interface contains the following method:
> >>>>>>
> >>>>>> public String getExtenderId();
> >>>>>>
> >>>>>> Thus, every extender has an extenderId and if that id is listed
in a
> >>>>>> components "extender" property then the corresponding service
should
> >>> be
> >>>>>> required, otherwise not.
> >>>>>>
> >>>>>> My idea (actually Clement's idea from a previous conversation
on
> this
> >>>>>> list). is to use a RankingInterceptor that returns an empty
array
> >>> until
> >>>>> all
> >>>>>> required services are present.
> >>>>>>
> >>>>>> I think this is doable but in order for my RankingInterceptor
to
> >>> work, it
> >>>>>> must have access to the component's "extenders" property. It
would
> >>> then
> >>>>> go
> >>>>>> through all the services implementing the IExtender interface
and if
> >>>>> there
> >>>>>> are extenders corresponding to the required extenderId's it
would
> >>> return
> >>>>>> all of those, otherwise it would return an empty list. Also,
if a
> >>> list of
> >>>>>> extenderId's was specified, then the service dependency is set
to
> >>>>>> mandatory, otherwise to optional.
> >>>>>>
> >>>>>> My problem is how to gain access to the configuration property
(the
> >>>>>> "extenders" property) of my component from the interceptor.
How can
> I
> >>> do
> >>>>>> this?
> >>>>>
> >>>>> When the interceptor is hooked to a dependency, it receives the
> >>> dependency
> >>>>> model object. From this object you can retrieve the component
> instance
> >>> and
> >>>>> get the introspection metadata.
> >>>>>
> >>>>>>
> >>>>>> Another question I have is how to make sure that the interceptor
is
> >>>>> active.
> >>>>>> If the interceptor is not active then my component could become
> >>>>> erroneously
> >>>>>> valid. Would it be feasible to have a mandatory dependency on
the
> >>>>>> interceptor?
> >>>>>
> >>>>> Unfortunately not, at least not easily. What you can do is a
> >>> combination
> >>>>> between a filter and two interceptors: the ranking interceptors
as
> you
> >>> did,
> >>>>> and a tracking interceptor. Let me explain:
> >>>>>
> >>>>> Let’s imagine your consumer with your service dependency. Add
a
> filter
> >>>>> that will be resolved only if your interceptor is there, something
> >>> like:
> >>>>> (intercepted=true).
> >>>>> Your interceptor implement both tracking and ranking interceptors.
> When
> >>>>> the accept method is called on your interceptor, it  can ‘transform’
> >>> the
> >>>>> original service reference to add the ‘intercepted’ property
> >>>>> (ref.addProperty(“intercepted”, true);) This modified service
> reference
> >>>>> matches your filter. Then, do your ranking policy are we discussed.
> >>>>>
> >>>>> This solution ensure that your dependency can only be resolved if
> your
> >>>>> interceptor is there. Indeed without the interceptor, the filter
does
> >>> not
> >>>>> match.
> >>>>>
> >>>>> Regards,
> >>>>>
> >>>>> Clement
> >>>>>
> >>>>>>
> >>>>>> /Bengt
> >>>>>
> >>>>>
> >>>>> ---------------------------------------------------------------------
> >>>>> 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