felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Clement Escoffier <clement.escoff...@gmail.com>
Subject Re: Using iPojo interceptors
Date Thu, 28 Nov 2013 14:04:10 GMT

On 28 nov. 2013, at 14:36, Bengt Rodehav <bengt@rodehav.com> wrote:

> Hello Clement,
> 
> I changed to the following line:
> 
>        PropertyDescription[] propDescs =
> configHandlerDescription.getProperties();
> 
> But I still get an NPE. Have you tried to call these methods from within an
> interceptor?

Not this method, but I did something pretty similar. Will investigate to see why you get an
NPE. 

Clement

> 
> /Bengt
> 
> 
> 2013/11/28 Clement Escoffier <clement.escoffier@gmail.com>
> 
>> 
>> On 28 nov. 2013, at 12:17, Bengt Rodehav <bengt@rodehav.com> wrote:
>> 
>>> 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.
>> 
>> Did you try to inter ate over the set of properties and see what are they ?
>> 
>>> 
>>> 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?
>> 
>> Yes, there is a getObjectValue(BundleContext context) method, but you need
>> to give a bundle context object used if it needs to load classes.
>> 
>> Clement
>> 
>>> 
>>> /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
>>>> 
>>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> 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
View raw message