You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Emmanuel Lécharny <el...@apache.org> on 2011/10/13 13:20:19 UTC

[ADS 2.0] OSGi, interceptors

Hi,

Göktük asked if there is a way to transform Interceptors to be bundles 
instead of being statically loaded in core.

I tried to play around the idea yesterday in the train, and I faced some 
interesting challenges.

o First, many interecptors are doing calls to the chain again, but with 
a restricted set of interceptors. For instance, in the 
SchemaInterceptor, we go through the chain again when modifying the 
schema itself. In order to speedup the operation, we declare a BYPASS 
sets of interceptors (I'm not sure it's a good idea, but right now, this 
is how we proceed). At the end, this BYPASS set is declared this way :

     private static final Collection<String> BYPASS;

     static
     {
         Set<String> c = new HashSet<String>();
         c.add( AuthenticationInterceptor.class.getName() );
         c.add( AciAuthorizationInterceptor.class.getName() );
         c.add( DefaultAuthorizationInterceptor.class.getName() );
         c.add( ExceptionInterceptor.class.getName() );
         c.add( SchemaInterceptor.class.getName() );
         BYPASS = Collections.unmodifiableCollection( c );
     }

As we can see, it creates a static dependency on interceptors. It might 
be a better idea to use logical names instead of class names, and let 
the OSGi container retrieve the classes itself.

o Second, we have places in core were we call the interceptors, like in 
DefaultDirectoryService :

     public boolean isPwdPolicyEnabled()
     {
         AuthenticationInterceptor authenticationInterceptor = 
(AuthenticationInterceptor)getInterceptor( 
AuthenticationInterceptor.class.getName() );
         if ( authenticationInterceptor == null )
         {
             return false;
         }

         PpolicyConfigContainer pwdPolicyContainer = 
authenticationInterceptor.getPwdPolicyContainer();

         return ( ( pwdPolicyContainer != null )
&& ( ( pwdPolicyContainer.getDefaultPolicy() != null )
                 || ( pwdPolicyContainer.hasCustomConfigs() ) ) );
     }

I'm quite sure we should do that in anothr way...



Right, now, I'm experimenting, moving each interceptors into a dedicated 
project (under apacheds/interceptors/authn, ...) to see what are the 
impacts. I'll come back with some more informations when I'll have a 
clear vision about the impacts.

Tahnks !

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: [ADS 2.0] OSGi, interceptors : status

Posted by Göktürk Gezer <go...@gmail.com>.
Hi Emmanuel,

On Fri, Oct 14, 2011 at 7:36 PM, Emmanuel Lécharny <el...@apache.org>wrote:

> Ok, as of today, I have a working trunk (all tests passing).
>
> The main modifications are :
> - we have one sub-project under apacheds, 'interceptors', which is the root
> for all the interceptors. It's a pom
> - each interceptor is under this sub-project, and currently produce a jar
> - I had to create a core-shared project in order to avoid cyclic
> dependencies between interceptors and core. Currently, interceptors depend
> on core-shared, and core depends on all the interceptors plus core-shared.
>
We're going to change that behavior so that core will not be dependent on
any interceptor as class reference.

> - I had to replace the XXX.class.getName() (where XXX is an interceptor
> name) by the direct interceptor name in the ByPass collections. This has a
> direct impact : we now name interceptors using their simple name (ie,
> without the package). This is not good, but this is just temporary
>
Yes, maybe i must implement some helper for you to get class reference of
intended interceptor using its name.

> - I also had to register the SimpleName for interceptors all over the code
> (not that many refs, though)
>
> The things we should do :
> - we still have interceptors depending on other interceptors. This is not
> good, and I will try to get rid of those dependencies
> - we must find a way to manage the chain by using an abstract name, not the
> Interceptor class name. Same for byPasses.
>
I'm on it. Basically we can handle this by using filtering while getting
interceptor references through OSGI. And this basic thing will help us to
get rid of all inter and intra interceptor dependencies.

>
> The worst part of the work was surprisingly not the decoupling, but the
> pom.xml modifications...
>
> I will commit my current changes, be ready for many modifications.
>

So we must provide custom OSGI build of ApacheDS as first step ASAP. That
will help us identifying problems of bundleizing current code. I'm on it
primarily.

>

Thanks !


>
>
> --
> Regards,
> Cordialement,
> Emmanuel Lécharny
> www.iktek.com
>
>
Regards,
Gokturk

Re: [ADS 2.0] OSGi, interceptors : status

Posted by Alex Karasulu <ak...@apache.org>.
First off a great effort ... thanks Emmanuel.  More inline ...

On Fri, Oct 14, 2011 at 7:36 PM, Emmanuel Lécharny <el...@apache.org>wrote:

> Ok, as of today, I have a working trunk (all tests passing).
>
> The main modifications are :
> - I had to create a core-shared project in order to avoid cyclic
> dependencies between interceptors and core. Currently, interceptors depend
> on core-shared, and core depends on all the interceptors plus core-shared.
>

This might eventually go away with further refactoring which removes
interceptor coupling.


> The things we should do :
> - we still have interceptors depending on other interceptors. This is not
> good, and I will try to get rid of those dependencies
>

There are some cases where we have data structures that are members of
Interceptors where they should really be first class data structures that
are members of the DirectoryService. For example in the SubentryInterceptor
there are data structures that should be part of the directory service but
are embedded inside the interceptor making other interceptors have to depend
on the SubentryInterceptor.

To fix these kinds of problems a new first class service (i.e.
SubtreeService) can be introduced under the DirectoryService which also
happens to have a SubentryInterceptor that acts as an interception helper.
However other Interceptors ask this service for information to perform their
tasks instead of having a direct handle on the SubentryInterceptor itself.

-- 
Best Regards,
-- Alex

Re: [ADS 2.0] OSGi, interceptors : status

Posted by Emmanuel Lécharny <el...@apache.org>.
Ok, as of today, I have a working trunk (all tests passing).

The main modifications are :
- we have one sub-project under apacheds, 'interceptors', which is the 
root for all the interceptors. It's a pom
- each interceptor is under this sub-project, and currently produce a jar
- I had to create a core-shared project in order to avoid cyclic 
dependencies between interceptors and core. Currently, interceptors 
depend on core-shared, and core depends on all the interceptors plus 
core-shared.
- I had to replace the XXX.class.getName() (where XXX is an interceptor 
name) by the direct interceptor name in the ByPass collections. This has 
a direct impact : we now name interceptors using their simple name (ie, 
without the package). This is not good, but this is just temporary
- I also had to register the SimpleName for interceptors all over the 
code (not that many refs, though)

The things we should do :
- we still have interceptors depending on other interceptors. This is 
not good, and I will try to get rid of those dependencies
- we must find a way to manage the chain by using an abstract name, not 
the Interceptor class name. Same for byPasses.

The worst part of the work was surprisingly not the decoupling, but the 
pom.xml modifications...

I will commit my current changes, be ready for many modifications.

Thanks !


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: [ADS 2.0] OSGi, interceptors : status

Posted by Alex Karasulu <ak...@apache.org>.
Nicely done and not an easy feat.

Thanks,
Alex

On Fri, Oct 14, 2011 at 1:46 AM, Emmanuel Lecharny <el...@gmail.com>wrote:

> Hi,
>
> as of tonite, I have almost all the interceptors correctly decoupled. I
> have created another extra project, core-shared, containing the elements
> used by the various interceptors. Now, the core project can reference the
> interceptors and core-shared.
>
> I still have to cleanup the poms, but I'm a bit tired to do it tonite (it's
> 1 am), I'll do t tomorrow.
>
> --
> Regards,
> Cordialement,
> Emmanuel Lécharny
> www.iktek.com
>
>


-- 
Best Regards,
-- Alex

Re: [ADS 2.0] OSGi, interceptors : status

Posted by Emmanuel Lecharny <el...@gmail.com>.
Hi,

as of tonite, I have almost all the interceptors correctly decoupled. I 
have created another extra project, core-shared, containing the elements 
used by the various interceptors. Now, the core project can reference 
the interceptors and core-shared.

I still have to cleanup the poms, but I'm a bit tired to do it tonite 
(it's 1 am), I'll do t tomorrow.

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: [ADS 2.0] OSGi, interceptors

Posted by Emmanuel Lécharny <el...@apache.org>.
On 10/13/11 4:30 PM, Alex Karasulu wrote:
>
>>
>>>   I tried to play around the idea yesterday in the train, and I faced some
>>>>>>> interesting challenges.
>>>>>>>
>>>>>>> o First, many interecptors are doing calls to the chain again, but
>>>>>>> with
>>>>>>> a
>>>>>>> restricted set of interceptors. For instance, in the
>>>>>>> SchemaInterceptor,
>>>>>>> we
>>>>>>> go through the chain again when modifying the schema itself. In order
>>>>>>> to
>>>>>>> speedup the operation, we declare a BYPASS sets of interceptors (I'm
>>>>>>> not
>>>>>>> sure it's a good idea, but right now, this is how we proceed). At the
>>>>>>> end,
>>>>>>> this BYPASS set is declared this way :
>>>>>>>
>>>>>>>     private static final Collection<String>    BYPASS;
>>>>>>>
>>>>>>>     static
>>>>>>>     {
>>>>>>>         Set<String>    c = new HashSet<String>();
>>>>>>>         c.add( AuthenticationInterceptor.******class.getName() );
>>>>>>>         c.add( AciAuthorizationInterceptor.******class.getName() );
>>>>>>>         c.add( DefaultAuthorizationIntercepto******r.class.getName()
>>>>>>> );
>>>>>>>         c.add( ExceptionInterceptor.class.******getName() );
>>>>>>>         c.add( SchemaInterceptor.class.******getName() );
>>>>>>>         BYPASS = Collections.******unmodifiableCollection( c );
>>>>>>>
>>>>>>>
>>>>>>>     }
>>>>>>>
>>>>>>> As we can see, it creates a static dependency on interceptors. It
>>>>>>> might
>>>>>>> be
>>>>>>> a better idea to use logical names instead of class names, and let the
>>>>>>> OSGi
>>>>>>> container retrieve the classes itself.
>>>>>>>
>>>>>>>
>>>>>>>   This is a good idea. How about going a little further and having a
>>>>>>> set
>>>>>>>
>>>>>> of
>>>>>> interceptor chain re-entry constants or set of enum values like:
>>>>>>
>>>>>> ReEntry.NO_AUTHENTICATION
>>>>>> ReEntry.NO_AUTHORIZATION
>>>>>> ReEntry.NO_ERROR_CHECKING
>>>>>> ReEntry.NO_SCHEMA_CHECKING
>>>>>>
>>>>>> etc ...
>>>>>>
>>>>>> This is like saying we do not need authentication, authorization,
>>>>>> additional
>>>>>> exception handling and checks or schema checking on re-entry instead of
>>>>>> having a direct list of interceptors to avoid.
>>>>>>
>>>>>>   That's a good idea.
>>>>> One thing that might be problematic though is that we have no idea which
>>>>> interceptors are going to be present in the chain, so we may be unable
>>>>> to
>>>>> tell the chain not to use the interceptors added on the fly (for
>>>>> instance,
>>>>> the logger interceptor).
>>>>>
>>>>>
>>>>>   Good point. Perhaps this is where we can have some kind of generic
>>>> property
>>>> that states whether or not by default on re-entry the interceptor should
>>>> be
>>>> included or excluded. There's a system default, say exclude by default
>>>> always. Then the interceptor might override this with some class property
>>>> like excludeOnReentry?
>>>>
>>>> This way even though the IC does not know which interceptors are present
>>>> it
>>>> can react accordingly on reentry. So for this logger interceptor example
>>>> it
>>>> might have excludeOnReentry set to false in which case it will always be
>>>> included when present which makes send. We would not add the interceptor
>>>> if
>>>> we did not want to log reentrant invocations.
>>>>
>> IMO, the best would be to declare sets of (I) we should go through, instead
>> of sets of (I) we should bypass. This way, we will be able to know what is
>> being executed, and we won't provide a way for users to pollute the internal
>> executions of operations (keep in mind that those internal operation are
>> themselves called by other operations).
>>
>> We can also declare those sets in the configuration, for each operation, so
>> if we want to allow someone to modify the execution order, it's still
>> possible to do so. (it can be done later though).
>>
> Perhaps we should break this out and discuss this in a separate thread. The
> reason historically for listing what you should not execute was a poor
> attempt to decouple and well you just don't know what extra interceptors you
> have.
>
> I have some ideas here that I also want to think through as well then post.

Sure, create another thread.



-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: [ADS 2.0] OSGi, interceptors

Posted by Alex Karasulu <ak...@apache.org>.
On Thu, Oct 13, 2011 at 5:01 PM, Emmanuel Lecharny <el...@gmail.com>wrote:

> On 10/13/11 3:16 PM, Göktürk Gezer wrote:
>
>> Hi Emmanuel,Alex
>>
>> I would like to add something to discussion.
>> More inline...
>>
>> On Thu, Oct 13, 2011 at 3:23 PM, Alex Karasulu<ak...@apache.org>
>>  wrote:
>>
>>
>>> On Thu, Oct 13, 2011 at 3:05 PM, Emmanuel Lécharny<el...@apache.org>
>>> **wrote:
>>>
>>>  On 10/13/11 1:44 PM, Alex Karasulu wrote:
>>>>
>>>>  On Thu, Oct 13, 2011 at 2:20 PM, Emmanuel Lécharny<
>>>>> elecharny@apache.org>
>>>>> **wrote:
>>>>>
>>>>>
>>>>>  Hi,
>>>>>
>>>>>> Göktük asked if there is a way to transform Interceptors to be bundles
>>>>>> instead of being statically loaded in core.
>>>>>>
>>>>>>  This can be case yes, but i actually wanted them for further
>>>>>
>>>> interceptors. We can keep core interceptors in place. Don't need to
>> separate
>> them all. Lets keep core interceptors in apacheds-core, and protocol
>> specific interceptors in their protocol implementation. And then any other
>> interceptor that comes and registers itself through OSGI can be attached
>> to
>> DirectoryService's interceptor list.
>>
>
> I'd rather decouple the whole thing. There is no reason for core to depend
> on Interceptors.
>

I'm in agreement here as well. Even if this is done as an exercise it will
clean up a lot of ugly coupling crust resident in the code. It's a bit
extreme but it has value and maybe will allow replacement of core
functionality easily down the line. It gives us more options in the end.


>
>
>>  I tried to play around the idea yesterday in the train, and I faced some
>>>>>> interesting challenges.
>>>>>>
>>>>>> o First, many interecptors are doing calls to the chain again, but
>>>>>> with
>>>>>> a
>>>>>> restricted set of interceptors. For instance, in the
>>>>>> SchemaInterceptor,
>>>>>> we
>>>>>> go through the chain again when modifying the schema itself. In order
>>>>>> to
>>>>>> speedup the operation, we declare a BYPASS sets of interceptors (I'm
>>>>>> not
>>>>>> sure it's a good idea, but right now, this is how we proceed). At the
>>>>>> end,
>>>>>> this BYPASS set is declared this way :
>>>>>>
>>>>>>    private static final Collection<String>   BYPASS;
>>>>>>
>>>>>>    static
>>>>>>    {
>>>>>>        Set<String>   c = new HashSet<String>();
>>>>>>        c.add( AuthenticationInterceptor.******class.getName() );
>>>>>>        c.add( AciAuthorizationInterceptor.******class.getName() );
>>>>>>        c.add( DefaultAuthorizationIntercepto******r.class.getName()
>>>>>> );
>>>>>>        c.add( ExceptionInterceptor.class.******getName() );
>>>>>>        c.add( SchemaInterceptor.class.******getName() );
>>>>>>        BYPASS = Collections.******unmodifiableCollection( c );
>>>>>>
>>>>>>
>>>>>>    }
>>>>>>
>>>>>> As we can see, it creates a static dependency on interceptors. It
>>>>>> might
>>>>>> be
>>>>>> a better idea to use logical names instead of class names, and let the
>>>>>> OSGi
>>>>>> container retrieve the classes itself.
>>>>>>
>>>>>>
>>>>>>  This is a good idea. How about going a little further and having a
>>>>>> set
>>>>>>
>>>>> of
>>>>> interceptor chain re-entry constants or set of enum values like:
>>>>>
>>>>> ReEntry.NO_AUTHENTICATION
>>>>> ReEntry.NO_AUTHORIZATION
>>>>> ReEntry.NO_ERROR_CHECKING
>>>>> ReEntry.NO_SCHEMA_CHECKING
>>>>>
>>>>> etc ...
>>>>>
>>>>> This is like saying we do not need authentication, authorization,
>>>>> additional
>>>>> exception handling and checks or schema checking on re-entry instead of
>>>>> having a direct list of interceptors to avoid.
>>>>>
>>>>>  That's a good idea.
>>>>
>>>> One thing that might be problematic though is that we have no idea which
>>>> interceptors are going to be present in the chain, so we may be unable
>>>> to
>>>> tell the chain not to use the interceptors added on the fly (for
>>>> instance,
>>>> the logger interceptor).
>>>>
>>>>
>>>>  Good point. Perhaps this is where we can have some kind of generic
>>> property
>>> that states whether or not by default on re-entry the interceptor should
>>> be
>>> included or excluded. There's a system default, say exclude by default
>>> always. Then the interceptor might override this with some class property
>>> like excludeOnReentry?
>>>
>>> This way even though the IC does not know which interceptors are present
>>> it
>>> can react accordingly on reentry. So for this logger interceptor example
>>> it
>>> might have excludeOnReentry set to false in which case it will always be
>>> included when present which makes send. We would not add the interceptor
>>> if
>>> we did not want to log reentrant invocations.
>>>
>>
> IMO, the best would be to declare sets of (I) we should go through, instead
> of sets of (I) we should bypass. This way, we will be able to know what is
> being executed, and we won't provide a way for users to pollute the internal
> executions of operations (keep in mind that those internal operation are
> themselves called by other operations).
>
> We can also declare those sets in the configuration, for each operation, so
> if we want to allow someone to modify the execution order, it's still
> possible to do so. (it can be done later though).
>

Perhaps we should break this out and discuss this in a separate thread. The
reason historically for listing what you should not execute was a poor
attempt to decouple and well you just don't know what extra interceptors you
have.

I have some ideas here that I also want to think through as well then post.


>  <snip/>
>>>
>>> The Interceptors themselves each have a configuration. In this
>>> configuration the Interceptor should expose what aspects it participates
>>> in.
>>> For example FooInterceptor might expose that it participates in the
>>> authentication aspect. This way the IC knows for example in a schema
>>> modification operation that causes re-entry to occur, this aspect is
>>> excluded say during a modify operation since the session is already
>>> authenticated (no need to perform this twice or on each re-entry into the
>>> IC). The FooInterceptor will be bypassed in this case.
>>>
>>>  For all the discussions above i may suggest using OSGI service
>> properties.
>> So we don't statically reference the specific interceptor class, we just
>> get
>> them using OSGI with some filter like
>> (interceptor.type="**AuthenticationInterceptor"). By this way we don't
>> change
>> a code much but we handle the decoupling.
>>
>
> I like that.
>
>
+1


>
>
>>
>>>
>>>  There can also be other hint mechanisms given to the interceptor chain
>>>>> so
>>>>> it
>>>>> can correctly asses which interceptors to include or exclude on
>>>>> re-entry.
>>>>> For example there could be properties exposed for defaults on the
>>>>> interceptor telling the chain always exclude on re-entry etc. There
>>>>> should
>>>>> be some more thought put on this but the present situation as you state
>>>>> sucks where OSGi and pluggability is concerned.
>>>>>
>>>>>  Right. We will try to get OSGi implemented anyway, and once it's done,
>>>> we
>>>> can start thinking about a better mechanism.
>>>>
>>> FYI, i just implemented dynamic Interceptor loading using IPojo. Its a
>>>
>> starter implementation. We can  improve it using the ideas those come out
>> from that mail. But you must now handling interceptor dynamism does not
>> solved the problems. Now i've to solve problems about concurrency.
>> java.util.concurrent classses are acting weird under OSGI.
>>
>
> Let's think about it when we are done with the decoupling. We first have to
> clean up the place before starting building up something new, otherwise we
> might build some castle on sand...
>

Sounds good.

-- 
Best Regards,
-- Alex

Re: [ADS 2.0] OSGi, interceptors

Posted by Emmanuel Lecharny <el...@gmail.com>.
On 10/13/11 3:16 PM, Göktürk Gezer wrote:
> Hi Emmanuel,Alex
>
> I would like to add something to discussion.
> More inline...
>
> On Thu, Oct 13, 2011 at 3:23 PM, Alex Karasulu<ak...@apache.org>  wrote:
>
>>
>> On Thu, Oct 13, 2011 at 3:05 PM, Emmanuel Lécharny<el...@apache.org>wrote:
>>
>>> On 10/13/11 1:44 PM, Alex Karasulu wrote:
>>>
>>>> On Thu, Oct 13, 2011 at 2:20 PM, Emmanuel Lécharny<el...@apache.org>
>>>> **wrote:
>>>>
>>>>   Hi,
>>>>> Göktük asked if there is a way to transform Interceptors to be bundles
>>>>> instead of being statically loaded in core.
>>>>>
>>>> This can be case yes, but i actually wanted them for further
> interceptors. We can keep core interceptors in place. Don't need to separate
> them all. Lets keep core interceptors in apacheds-core, and protocol
> specific interceptors in their protocol implementation. And then any other
> interceptor that comes and registers itself through OSGI can be attached to
> DirectoryService's interceptor list.

I'd rather decouple the whole thing. There is no reason for core to 
depend on Interceptors.

>
>>>>> I tried to play around the idea yesterday in the train, and I faced some
>>>>> interesting challenges.
>>>>>
>>>>> o First, many interecptors are doing calls to the chain again, but with
>>>>> a
>>>>> restricted set of interceptors. For instance, in the SchemaInterceptor,
>>>>> we
>>>>> go through the chain again when modifying the schema itself. In order to
>>>>> speedup the operation, we declare a BYPASS sets of interceptors (I'm not
>>>>> sure it's a good idea, but right now, this is how we proceed). At the
>>>>> end,
>>>>> this BYPASS set is declared this way :
>>>>>
>>>>>     private static final Collection<String>   BYPASS;
>>>>>
>>>>>     static
>>>>>     {
>>>>>         Set<String>   c = new HashSet<String>();
>>>>>         c.add( AuthenticationInterceptor.****class.getName() );
>>>>>         c.add( AciAuthorizationInterceptor.****class.getName() );
>>>>>         c.add( DefaultAuthorizationIntercepto****r.class.getName() );
>>>>>         c.add( ExceptionInterceptor.class.****getName() );
>>>>>         c.add( SchemaInterceptor.class.****getName() );
>>>>>         BYPASS = Collections.****unmodifiableCollection( c );
>>>>>
>>>>>     }
>>>>>
>>>>> As we can see, it creates a static dependency on interceptors. It might
>>>>> be
>>>>> a better idea to use logical names instead of class names, and let the
>>>>> OSGi
>>>>> container retrieve the classes itself.
>>>>>
>>>>>
>>>>>   This is a good idea. How about going a little further and having a set
>>>> of
>>>> interceptor chain re-entry constants or set of enum values like:
>>>>
>>>> ReEntry.NO_AUTHENTICATION
>>>> ReEntry.NO_AUTHORIZATION
>>>> ReEntry.NO_ERROR_CHECKING
>>>> ReEntry.NO_SCHEMA_CHECKING
>>>>
>>>> etc ...
>>>>
>>>> This is like saying we do not need authentication, authorization,
>>>> additional
>>>> exception handling and checks or schema checking on re-entry instead of
>>>> having a direct list of interceptors to avoid.
>>>>
>>> That's a good idea.
>>>
>>> One thing that might be problematic though is that we have no idea which
>>> interceptors are going to be present in the chain, so we may be unable to
>>> tell the chain not to use the interceptors added on the fly (for instance,
>>> the logger interceptor).
>>>
>>>
>> Good point. Perhaps this is where we can have some kind of generic property
>> that states whether or not by default on re-entry the interceptor should be
>> included or excluded. There's a system default, say exclude by default
>> always. Then the interceptor might override this with some class property
>> like excludeOnReentry?
>>
>> This way even though the IC does not know which interceptors are present it
>> can react accordingly on reentry. So for this logger interceptor example it
>> might have excludeOnReentry set to false in which case it will always be
>> included when present which makes send. We would not add the interceptor if
>> we did not want to log reentrant invocations.

IMO, the best would be to declare sets of (I) we should go through, 
instead of sets of (I) we should bypass. This way, we will be able to 
know what is being executed, and we won't provide a way for users to 
pollute the internal executions of operations (keep in mind that those 
internal operation are themselves called by other operations).

We can also declare those sets in the configuration, for each operation, 
so if we want to allow someone to modify the execution order, it's still 
possible to do so. (it can be done later though).
>> <snip/>
>> The Interceptors themselves each have a configuration. In this
>> configuration the Interceptor should expose what aspects it participates in.
>> For example FooInterceptor might expose that it participates in the
>> authentication aspect. This way the IC knows for example in a schema
>> modification operation that causes re-entry to occur, this aspect is
>> excluded say during a modify operation since the session is already
>> authenticated (no need to perform this twice or on each re-entry into the
>> IC). The FooInterceptor will be bypassed in this case.
>>
> For all the discussions above i may suggest using OSGI service properties.
> So we don't statically reference the specific interceptor class, we just get
> them using OSGI with some filter like
> (interceptor.type="AuthenticationInterceptor"). By this way we don't change
> a code much but we handle the decoupling.

I like that.

>
>>
>>
>>>> There can also be other hint mechanisms given to the interceptor chain so
>>>> it
>>>> can correctly asses which interceptors to include or exclude on re-entry.
>>>> For example there could be properties exposed for defaults on the
>>>> interceptor telling the chain always exclude on re-entry etc. There
>>>> should
>>>> be some more thought put on this but the present situation as you state
>>>> sucks where OSGi and pluggability is concerned.
>>>>
>>> Right. We will try to get OSGi implemented anyway, and once it's done, we
>>> can start thinking about a better mechanism.
>> FYI, i just implemented dynamic Interceptor loading using IPojo. Its a
> starter implementation. We can  improve it using the ideas those come out
> from that mail. But you must now handling interceptor dynamism does not
> solved the problems. Now i've to solve problems about concurrency.
> java.util.concurrent classses are acting weird under OSGI.

Let's think about it when we are done with the decoupling. We first have 
to clean up the place before starting building up something new, 
otherwise we might build some castle on sand...

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: [ADS 2.0] OSGi, interceptors

Posted by Göktürk Gezer <go...@gmail.com>.
Hi Emmanuel,Alex

I would like to add something to discussion.
More inline...

On Thu, Oct 13, 2011 at 3:23 PM, Alex Karasulu <ak...@apache.org> wrote:

>
>
> On Thu, Oct 13, 2011 at 3:05 PM, Emmanuel Lécharny <el...@apache.org>wrote:
>
>> On 10/13/11 1:44 PM, Alex Karasulu wrote:
>>
>>> On Thu, Oct 13, 2011 at 2:20 PM, Emmanuel Lécharny<el...@apache.org>
>>> **wrote:
>>>
>>>  Hi,
>>>>
>>>> Göktük asked if there is a way to transform Interceptors to be bundles
>>>> instead of being statically loaded in core.
>>>>
>>> This can be case yes, but i actually wanted them for further
interceptors. We can keep core interceptors in place. Don't need to separate
them all. Lets keep core interceptors in apacheds-core, and protocol
specific interceptors in their protocol implementation. And then any other
interceptor that comes and registers itself through OSGI can be attached to
DirectoryService's interceptor list.

>
>>>>
>>>
>>>> I tried to play around the idea yesterday in the train, and I faced some
>>>> interesting challenges.
>>>>
>>>> o First, many interecptors are doing calls to the chain again, but with
>>>> a
>>>> restricted set of interceptors. For instance, in the SchemaInterceptor,
>>>> we
>>>> go through the chain again when modifying the schema itself. In order to
>>>> speedup the operation, we declare a BYPASS sets of interceptors (I'm not
>>>> sure it's a good idea, but right now, this is how we proceed). At the
>>>> end,
>>>> this BYPASS set is declared this way :
>>>>
>>>>    private static final Collection<String>  BYPASS;
>>>>
>>>>    static
>>>>    {
>>>>        Set<String>  c = new HashSet<String>();
>>>>        c.add( AuthenticationInterceptor.****class.getName() );
>>>>        c.add( AciAuthorizationInterceptor.****class.getName() );
>>>>        c.add( DefaultAuthorizationIntercepto****r.class.getName() );
>>>>        c.add( ExceptionInterceptor.class.****getName() );
>>>>        c.add( SchemaInterceptor.class.****getName() );
>>>>        BYPASS = Collections.****unmodifiableCollection( c );
>>>>
>>>>    }
>>>>
>>>> As we can see, it creates a static dependency on interceptors. It might
>>>> be
>>>> a better idea to use logical names instead of class names, and let the
>>>> OSGi
>>>> container retrieve the classes itself.
>>>>
>>>>
>>>>  This is a good idea. How about going a little further and having a set
>>> of
>>> interceptor chain re-entry constants or set of enum values like:
>>>
>>> ReEntry.NO_AUTHENTICATION
>>> ReEntry.NO_AUTHORIZATION
>>> ReEntry.NO_ERROR_CHECKING
>>> ReEntry.NO_SCHEMA_CHECKING
>>>
>>> etc ...
>>>
>>> This is like saying we do not need authentication, authorization,
>>> additional
>>> exception handling and checks or schema checking on re-entry instead of
>>> having a direct list of interceptors to avoid.
>>>
>>
>> That's a good idea.
>>
>> One thing that might be problematic though is that we have no idea which
>> interceptors are going to be present in the chain, so we may be unable to
>> tell the chain not to use the interceptors added on the fly (for instance,
>> the logger interceptor).
>>
>>
> Good point. Perhaps this is where we can have some kind of generic property
> that states whether or not by default on re-entry the interceptor should be
> included or excluded. There's a system default, say exclude by default
> always. Then the interceptor might override this with some class property
> like excludeOnReentry?
>
> This way even though the IC does not know which interceptors are present it
> can react accordingly on reentry. So for this logger interceptor example it
> might have excludeOnReentry set to false in which case it will always be
> included when present which makes send. We would not add the interceptor if
> we did not want to log reentrant invocations.
>
>
>> I'd rather create a set of interceptors we want to go through, as we know
>> which one we will use in those internal cases.
>>
>> In any case, using constants instead of class name is the way to go.
>>
>>
> Yes this is definitely the first step, perhaps the final step but perhaps
> you might want to entertain the idea of evaluating inclusion or exclusion
> based on properties. This makes debugging a tiny bit more complicated but it
> gives us a more pluggable way to manage the IC.
>
>
>>
>>> Then Interceptors when they register themselves can announce what
>>> standard
>>> functions they perform according to this set. Some may not announce at
>>> all
>>> if they perform none of these functions. This way the chain determines
>>> what
>>> to include and what to exclude based on these properties. There's no
>>> direct
>>> link with the interceptor itself and any implementation can be swapped in
>>> and out.
>>>
>>> This way we are letting the interceptor chain devise the proper chain of
>>> interceptors based on these properties instead of using more explicit
>>> names
>>> or direct references to the interceptor classes.
>>>
>>
>> Ultimately, for each operation (add, delete, lookup, etc), we should be
>> able to define the set of interceptors we are going through.
>
>
> My thinking is to not define things in terms of interceptors to go through
> or not go through for each operation but rather we should define the aspects
> to include or exclude on re-entry into the IC for each operation. Keeping it
> generic this way, and having the Interceptor tell the IC which aspects it
> participates in allows the IC to include or exclude on re-entry.
>
>
>> This should be defined somewhere in the code, not in each interceptors. It
>> may even be some configurable information...
>>
>>
> I see two points of configuration.
>
> One configuration is the IC configuration it self which includes the
> aspects to include or exclude on re-entry for each of the add, delete,
> lookup etc operations. The IC itself is a component with this perspective.
>
> The Interceptors themselves each have a configuration. In this
> configuration the Interceptor should expose what aspects it participates in.
> For example FooInterceptor might expose that it participates in the
> authentication aspect. This way the IC knows for example in a schema
> modification operation that causes re-entry to occur, this aspect is
> excluded say during a modify operation since the session is already
> authenticated (no need to perform this twice or on each re-entry into the
> IC). The FooInterceptor will be bypassed in this case.
>
For all the discussions above i may suggest using OSGI service properties.
So we don't statically reference the specific interceptor class, we just get
them using OSGI with some filter like
(interceptor.type="AuthenticationInterceptor"). By this way we don't change
a code much but we handle the decoupling.

>
>
>
>>
>>> There can also be other hint mechanisms given to the interceptor chain so
>>> it
>>> can correctly asses which interceptors to include or exclude on re-entry.
>>> For example there could be properties exposed for defaults on the
>>> interceptor telling the chain always exclude on re-entry etc. There
>>> should
>>> be some more thought put on this but the present situation as you state
>>> sucks where OSGi and pluggability is concerned.
>>>
>> Right. We will try to get OSGi implemented anyway, and once it's done, we
>> can start thinking about a better mechanism.
>
> FYI, i just implemented dynamic Interceptor loading using IPojo. Its a
starter implementation. We can  improve it using the ideas those come out
from that mail. But you must now handling interceptor dynamism does not
solved the problems. Now i've to solve problems about concurrency.
java.util.concurrent classses are acting weird under OSGI.

>
>>
>>
>> --
>> Regards,
>> Cordialement,
>> Emmanuel Lécharny
>> www.iktek.com
>>
>>
>
>
> --
> Best Regards,
> -- Alex
>
>

Re: [ADS 2.0] OSGi, interceptors

Posted by Alex Karasulu <ak...@apache.org>.
On Thu, Oct 13, 2011 at 3:05 PM, Emmanuel Lécharny <el...@apache.org>wrote:

> On 10/13/11 1:44 PM, Alex Karasulu wrote:
>
>> On Thu, Oct 13, 2011 at 2:20 PM, Emmanuel Lécharny<el...@apache.org>*
>> *wrote:
>>
>>  Hi,
>>>
>>> Göktük asked if there is a way to transform Interceptors to be bundles
>>> instead of being statically loaded in core.
>>>
>>> I tried to play around the idea yesterday in the train, and I faced some
>>> interesting challenges.
>>>
>>> o First, many interecptors are doing calls to the chain again, but with a
>>> restricted set of interceptors. For instance, in the SchemaInterceptor,
>>> we
>>> go through the chain again when modifying the schema itself. In order to
>>> speedup the operation, we declare a BYPASS sets of interceptors (I'm not
>>> sure it's a good idea, but right now, this is how we proceed). At the
>>> end,
>>> this BYPASS set is declared this way :
>>>
>>>    private static final Collection<String>  BYPASS;
>>>
>>>    static
>>>    {
>>>        Set<String>  c = new HashSet<String>();
>>>        c.add( AuthenticationInterceptor.****class.getName() );
>>>        c.add( AciAuthorizationInterceptor.****class.getName() );
>>>        c.add( DefaultAuthorizationIntercepto****r.class.getName() );
>>>        c.add( ExceptionInterceptor.class.****getName() );
>>>        c.add( SchemaInterceptor.class.****getName() );
>>>        BYPASS = Collections.****unmodifiableCollection( c );
>>>
>>>    }
>>>
>>> As we can see, it creates a static dependency on interceptors. It might
>>> be
>>> a better idea to use logical names instead of class names, and let the
>>> OSGi
>>> container retrieve the classes itself.
>>>
>>>
>>>  This is a good idea. How about going a little further and having a set
>> of
>> interceptor chain re-entry constants or set of enum values like:
>>
>> ReEntry.NO_AUTHENTICATION
>> ReEntry.NO_AUTHORIZATION
>> ReEntry.NO_ERROR_CHECKING
>> ReEntry.NO_SCHEMA_CHECKING
>>
>> etc ...
>>
>> This is like saying we do not need authentication, authorization,
>> additional
>> exception handling and checks or schema checking on re-entry instead of
>> having a direct list of interceptors to avoid.
>>
>
> That's a good idea.
>
> One thing that might be problematic though is that we have no idea which
> interceptors are going to be present in the chain, so we may be unable to
> tell the chain not to use the interceptors added on the fly (for instance,
> the logger interceptor).
>
>
Good point. Perhaps this is where we can have some kind of generic property
that states whether or not by default on re-entry the interceptor should be
included or excluded. There's a system default, say exclude by default
always. Then the interceptor might override this with some class property
like excludeOnReentry?

This way even though the IC does not know which interceptors are present it
can react accordingly on reentry. So for this logger interceptor example it
might have excludeOnReentry set to false in which case it will always be
included when present which makes send. We would not add the interceptor if
we did not want to log reentrant invocations.


> I'd rather create a set of interceptors we want to go through, as we know
> which one we will use in those internal cases.
>
> In any case, using constants instead of class name is the way to go.
>
>
Yes this is definitely the first step, perhaps the final step but perhaps
you might want to entertain the idea of evaluating inclusion or exclusion
based on properties. This makes debugging a tiny bit more complicated but it
gives us a more pluggable way to manage the IC.


>
>> Then Interceptors when they register themselves can announce what standard
>> functions they perform according to this set. Some may not announce at all
>> if they perform none of these functions. This way the chain determines
>> what
>> to include and what to exclude based on these properties. There's no
>> direct
>> link with the interceptor itself and any implementation can be swapped in
>> and out.
>>
>> This way we are letting the interceptor chain devise the proper chain of
>> interceptors based on these properties instead of using more explicit
>> names
>> or direct references to the interceptor classes.
>>
>
> Ultimately, for each operation (add, delete, lookup, etc), we should be
> able to define the set of interceptors we are going through.


My thinking is to not define things in terms of interceptors to go through
or not go through for each operation but rather we should define the aspects
to include or exclude on re-entry into the IC for each operation. Keeping it
generic this way, and having the Interceptor tell the IC which aspects it
participates in allows the IC to include or exclude on re-entry.


> This should be defined somewhere in the code, not in each interceptors. It
> may even be some configurable information...
>
>
I see two points of configuration.

One configuration is the IC configuration it self which includes the aspects
to include or exclude on re-entry for each of the add, delete, lookup etc
operations. The IC itself is a component with this perspective.

The Interceptors themselves each have a configuration. In this configuration
the Interceptor should expose what aspects it participates in. For example
FooInterceptor might expose that it participates in the authentication
aspect. This way the IC knows for example in a schema modification operation
that causes re-entry to occur, this aspect is excluded say during a modify
operation since the session is already authenticated (no need to perform
this twice or on each re-entry into the IC). The FooInterceptor will be
bypassed in this case.



>
>> There can also be other hint mechanisms given to the interceptor chain so
>> it
>> can correctly asses which interceptors to include or exclude on re-entry.
>> For example there could be properties exposed for defaults on the
>> interceptor telling the chain always exclude on re-entry etc. There should
>> be some more thought put on this but the present situation as you state
>> sucks where OSGi and pluggability is concerned.
>>
> Right. We will try to get OSGi implemented anyway, and once it's done, we
> can start thinking about a better mechanism.
>
>
>
> --
> Regards,
> Cordialement,
> Emmanuel Lécharny
> www.iktek.com
>
>


-- 
Best Regards,
-- Alex

Re: [ADS 2.0] OSGi, interceptors

Posted by Emmanuel Lécharny <el...@apache.org>.
On 10/13/11 1:44 PM, Alex Karasulu wrote:
> On Thu, Oct 13, 2011 at 2:20 PM, Emmanuel Lécharny<el...@apache.org>wrote:
>
>> Hi,
>>
>> Göktük asked if there is a way to transform Interceptors to be bundles
>> instead of being statically loaded in core.
>>
>> I tried to play around the idea yesterday in the train, and I faced some
>> interesting challenges.
>>
>> o First, many interecptors are doing calls to the chain again, but with a
>> restricted set of interceptors. For instance, in the SchemaInterceptor, we
>> go through the chain again when modifying the schema itself. In order to
>> speedup the operation, we declare a BYPASS sets of interceptors (I'm not
>> sure it's a good idea, but right now, this is how we proceed). At the end,
>> this BYPASS set is declared this way :
>>
>>     private static final Collection<String>  BYPASS;
>>
>>     static
>>     {
>>         Set<String>  c = new HashSet<String>();
>>         c.add( AuthenticationInterceptor.**class.getName() );
>>         c.add( AciAuthorizationInterceptor.**class.getName() );
>>         c.add( DefaultAuthorizationIntercepto**r.class.getName() );
>>         c.add( ExceptionInterceptor.class.**getName() );
>>         c.add( SchemaInterceptor.class.**getName() );
>>         BYPASS = Collections.**unmodifiableCollection( c );
>>     }
>>
>> As we can see, it creates a static dependency on interceptors. It might be
>> a better idea to use logical names instead of class names, and let the OSGi
>> container retrieve the classes itself.
>>
>>
> This is a good idea. How about going a little further and having a set of
> interceptor chain re-entry constants or set of enum values like:
>
> ReEntry.NO_AUTHENTICATION
> ReEntry.NO_AUTHORIZATION
> ReEntry.NO_ERROR_CHECKING
> ReEntry.NO_SCHEMA_CHECKING
>
> etc ...
>
> This is like saying we do not need authentication, authorization, additional
> exception handling and checks or schema checking on re-entry instead of
> having a direct list of interceptors to avoid.

That's a good idea.

One thing that might be problematic though is that we have no idea which 
interceptors are going to be present in the chain, so we may be unable 
to tell the chain not to use the interceptors added on the fly (for 
instance, the logger interceptor).

I'd rather create a set of interceptors we want to go through, as we 
know which one we will use in those internal cases.

In any case, using constants instead of class name is the way to go.
>
> Then Interceptors when they register themselves can announce what standard
> functions they perform according to this set. Some may not announce at all
> if they perform none of these functions. This way the chain determines what
> to include and what to exclude based on these properties. There's no direct
> link with the interceptor itself and any implementation can be swapped in
> and out.
>
> This way we are letting the interceptor chain devise the proper chain of
> interceptors based on these properties instead of using more explicit names
> or direct references to the interceptor classes.

Ultimately, for each operation (add, delete, lookup, etc), we should be 
able to define the set of interceptors we are going through. This should 
be defined somewhere in the code, not in each interceptors. It may even 
be some configurable information...
>
> There can also be other hint mechanisms given to the interceptor chain so it
> can correctly asses which interceptors to include or exclude on re-entry.
> For example there could be properties exposed for defaults on the
> interceptor telling the chain always exclude on re-entry etc. There should
> be some more thought put on this but the present situation as you state
> sucks where OSGi and pluggability is concerned.
Right. We will try to get OSGi implemented anyway, and once it's done, 
we can start thinking about a better mechanism.


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: [ADS 2.0] OSGi, interceptors

Posted by Alex Karasulu <ak...@apache.org>.
On Thu, Oct 13, 2011 at 2:20 PM, Emmanuel Lécharny <el...@apache.org>wrote:

> Hi,
>
> Göktük asked if there is a way to transform Interceptors to be bundles
> instead of being statically loaded in core.
>
> I tried to play around the idea yesterday in the train, and I faced some
> interesting challenges.
>
> o First, many interecptors are doing calls to the chain again, but with a
> restricted set of interceptors. For instance, in the SchemaInterceptor, we
> go through the chain again when modifying the schema itself. In order to
> speedup the operation, we declare a BYPASS sets of interceptors (I'm not
> sure it's a good idea, but right now, this is how we proceed). At the end,
> this BYPASS set is declared this way :
>
>    private static final Collection<String> BYPASS;
>
>    static
>    {
>        Set<String> c = new HashSet<String>();
>        c.add( AuthenticationInterceptor.**class.getName() );
>        c.add( AciAuthorizationInterceptor.**class.getName() );
>        c.add( DefaultAuthorizationIntercepto**r.class.getName() );
>        c.add( ExceptionInterceptor.class.**getName() );
>        c.add( SchemaInterceptor.class.**getName() );
>        BYPASS = Collections.**unmodifiableCollection( c );
>    }
>
> As we can see, it creates a static dependency on interceptors. It might be
> a better idea to use logical names instead of class names, and let the OSGi
> container retrieve the classes itself.
>
>
This is a good idea. How about going a little further and having a set of
interceptor chain re-entry constants or set of enum values like:

ReEntry.NO_AUTHENTICATION
ReEntry.NO_AUTHORIZATION
ReEntry.NO_ERROR_CHECKING
ReEntry.NO_SCHEMA_CHECKING

etc ...

This is like saying we do not need authentication, authorization, additional
exception handling and checks or schema checking on re-entry instead of
having a direct list of interceptors to avoid.

Then Interceptors when they register themselves can announce what standard
functions they perform according to this set. Some may not announce at all
if they perform none of these functions. This way the chain determines what
to include and what to exclude based on these properties. There's no direct
link with the interceptor itself and any implementation can be swapped in
and out.

This way we are letting the interceptor chain devise the proper chain of
interceptors based on these properties instead of using more explicit names
or direct references to the interceptor classes.

There can also be other hint mechanisms given to the interceptor chain so it
can correctly asses which interceptors to include or exclude on re-entry.
For example there could be properties exposed for defaults on the
interceptor telling the chain always exclude on re-entry etc. There should
be some more thought put on this but the present situation as you state
sucks where OSGi and pluggability is concerned.


> o Second, we have places in core were we call the interceptors, like in
> DefaultDirectoryService :
>
>    public boolean isPwdPolicyEnabled()
>    {
>        AuthenticationInterceptor authenticationInterceptor =
> (AuthenticationInterceptor)**getInterceptor( AuthenticationInterceptor.**class.getName()
> );
>        if ( authenticationInterceptor == null )
>        {
>            return false;
>        }
>
>        PpolicyConfigContainer pwdPolicyContainer =
> authenticationInterceptor.**getPwdPolicyContainer();
>
>        return ( ( pwdPolicyContainer != null )
> && ( ( pwdPolicyContainer.**getDefaultPolicy() != null )
>                || ( pwdPolicyContainer.**hasCustomConfigs() ) ) );
>    }
>
> I'm quite sure we should do that in anothr way...
>
>
>
Yes this is causing unnecessary coupling between interceptors.


>
> Right, now, I'm experimenting, moving each interceptors into a dedicated
> project (under apacheds/interceptors/authn, ...) to see what are the
> impacts.


Good idea this should clean things up and show us clearly what the cross
interceptor dependencies are.


> I'll come back with some more informations when I'll have a clear vision
> about the impacts.
>
>
Thank you,
Alex