You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Albert Kwong <ma...@yahoo.com> on 2004/04/19 12:49:27 UTC

Container supported interceptable service

Avalon is so great!  It makes almost everything
pluggable.  Besides pluggable, I find it also useful
to make component operations interceptable, so that
external logic can be inserted before and after
operations.  It would be even better if the container
can support it and make all components easily
interceptable.

I have drafted some ideas here.  What do you think?

Albert Kwong (Mandr)

=========
Objective
=========
Allow components (interceptors) to intercept the
operations of another component using a Chain of
Responsibility pattern.  Better support for SOC.


Component
=========

/**
 *@avalon.interceptor type='AbcServiceInterceptor'
 */
public interface AbcService
{
    String doAbc (String param);

    /** @avalon.interceptor.skip */
    String doDef ();
}

/**
 * Automatically generated from AbcService meta tags.
 */
public interface AbcServiceInterceptor
{
    String doAbc (String param, Iterator chain);
}

/**
 * To be deployed as abcService.
 */
public class AbcServiceImpl implements AbcService
{
    String doAbc (String param) {};
}

/**
 * to be deployed as abcInterceptor
 */
public class AbcServiceInterceptorImpl implements
AbcServiceInterceptor
{
    String doAbc (String param, Iterator chain)
    {
        /* pre processing interception */
        ((AbcServiceInterceptor) chain.next()).doAbc
(param, chain);
        /* post processing interception */
    }
}


Deployment
==========

<!-- Order of interception depends on the order
attribute. -->
<targets>
    <target name='abcInterceptor'>
        <intercept
order='1000'><source>abcService</source></intercept>
    </target>
</targets>


Proxy processing
================
1. Application calls abcService.doAbc (param)
2. Proxy creates the Iterator chain [abcInterceptor,
Proxy(abcService)]     (note: Proxy(abcService)
implements AbcServiceInterceptor)
3. Container calls abcInterceptor.doAbc (param, chain)
4. abcInterceptor pre processing
5. abcInterceptor calls Proxy(abcService).doAbc
(param, chain)
5. Proxy(abcService) calls abcService.doAbc(param)
6. abcService returns
7. Proxy(abcService) returns
8. abcInterceptor post processing
9. abcInterceptor returns
10. ...



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Stephen McConnell <mc...@apache.org>.
Niclas Hedhman wrote:

> On Monday 19 April 2004 18:49, Albert Kwong wrote:
> 
>>I have drafted some ideas here.  What do you think?
> 
> 
> Ok, I have a better picture now, but one assumption still remain;
> 1. The InterceptorOne and InterceptorTwo are handled as components by the 
> container.
> 
> I kind-of like the whole notion, but still wonder if it is generic enough for 
> "most cases". Likewise I wonder if a "more generic" way is an overkill and 
> adds too much complexity.
> 
> Lets take small steps, and start with the simple pieces first. Here are my 
> reflections;
> 
> Your model requires the Service to declare what can be intercepted and the 
> Type of the Interception components.
> IMHO, it is more natural to do the opposite, declaring the Service(s) that the 
> Interceptor works upon.
> 
> public interface AbcService
> {
>     String doAbc ();
> 
>     String doDef ();
> }
> 
> /** @avalon.interceptor  type=AbcService
>  **/
> public interface AbcInterceptor
> {
>     String doAbc ();
> }
> 
> /** @avalon.interceptor  type=AbcService
>  **/
> public interface DefInterceptor
> {
>     String doDef();
> }
> 
> The advantage would be that you can create interception on any existing 
> component/service, without modification. Also, better separation of 
> Interception of different sorts, as many Interceptions can be done on the 
> same Service.
> The disadvantage would be that the Interceptor interface needs to be created 
> maually (IMO, a very small price.).
> 
> 
> If I halt here for a second, and let you and others comment, before moving on 
> to more details...


I'm thinking exactly the same thing.
But I'm still thinking (and its late - dangerous combination).

Steve.


-- 

|------------------------------------------------|
| Magic by Merlin                                |
| Production by Avalon                           |
|                                                |
| http://avalon.apache.org/merlin                |
| http://dpml.net/merlin/distributions/latest    |
|------------------------------------------------|

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Albert Kwong <ma...@yahoo.com>.
 --- Niclas Hedhman <ni...@hedhman.org>
> As I have understood it (it is not my idea), is that
> the Interceptor is an 
> interface and have any number of implementations,
> each configured and brought 
> to life as components in general.
> 
> Albert then suggested a "Order" value for each such
> component to determine 
> which one is first and last in the chain.

Correct.  Note that the end-point of the chain shall
always be the original service, which is not aware of
the chain at all.

I thought about Niclas's suggestion about multiple
interceptor interfaces.  Implementation-wise it seems
to be slower and more complex than the original
proposal.  However, from a design point of view it
seems cleaner, more flexible, and more backward
compatible.

I like Niclas's suggestion.

Albert

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Niclas Hedhman <ni...@hedhman.org>.
On Wednesday 21 April 2004 00:06, Timothy Bennett wrote:

> I really like this idea.  Would there be some notion of chaining
> multiple interceptions acting on a single service together?  Ordering, etc?

As I have understood it (it is not my idea), is that the Interceptor is an 
interface and have any number of implementations, each configured and brought 
to life as components in general.

Albert then suggested a "Order" value for each such component to determine 
which one is first and last in the chain.

Furthermore, one could possibly extend this to the LifeCycle methods as well, 
and do away with the current somewhat awkward lifecycle extension mechanism.

Niclas
-- 
+---------//-------------------+
|   http://www.bali.ac         |
|  http://niclas.hedhman.org   |
+------//----------------------+

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Timothy Bennett <ex...@comcast.net>.
Niclas Hedhman wrote:
> On Monday 19 April 2004 18:49, Albert Kwong wrote:
> 
> public interface AbcService
> {
>     String doAbc ();
> 
>     String doDef ();
> }
> 
> /** @avalon.interceptor  type=AbcService
>  **/
> public interface AbcInterceptor
> {
>     String doAbc ();
> }
> 
> /** @avalon.interceptor  type=AbcService
>  **/
> public interface DefInterceptor
> {
>     String doDef();
> }
> 
> The advantage would be that you can create interception on any existing 
> component/service, without modification. Also, better separation of 
> Interception of different sorts, as many Interceptions can be done on the 
> same Service.
> The disadvantage would be that the Interceptor interface needs to be created 
> maually (IMO, a very small price.).
> 

I really like this idea.  Would there be some notion of chaining 
multiple interceptions acting on a single service together?  Ordering, etc?


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Niclas Hedhman <ni...@hedhman.org>.
On Monday 19 April 2004 18:49, Albert Kwong wrote:
> I have drafted some ideas here.  What do you think?

Ok, I have a better picture now, but one assumption still remain;
1. The InterceptorOne and InterceptorTwo are handled as components by the 
container.

I kind-of like the whole notion, but still wonder if it is generic enough for 
"most cases". Likewise I wonder if a "more generic" way is an overkill and 
adds too much complexity.

Lets take small steps, and start with the simple pieces first. Here are my 
reflections;

Your model requires the Service to declare what can be intercepted and the 
Type of the Interception components.
IMHO, it is more natural to do the opposite, declaring the Service(s) that the 
Interceptor works upon.

public interface AbcService
{
    String doAbc ();

    String doDef ();
}

/** @avalon.interceptor  type=AbcService
 **/
public interface AbcInterceptor
{
    String doAbc ();
}

/** @avalon.interceptor  type=AbcService
 **/
public interface DefInterceptor
{
    String doDef();
}

The advantage would be that you can create interception on any existing 
component/service, without modification. Also, better separation of 
Interception of different sorts, as many Interceptions can be done on the 
same Service.
The disadvantage would be that the Interceptor interface needs to be created 
maually (IMO, a very small price.).


If I halt here for a second, and let you and others comment, before moving on 
to more details...


Cheers
Niclas

-- 
+---------//-------------------+
|   http://www.bali.ac         |
|  http://niclas.hedhman.org   |
+------//----------------------+

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Albert Kwong <ma...@yahoo.com>.
Since I also lost hammett's post, let me reply it
here:

> I used aspects to provide interceptors capabilities.
However this works for
> all components, not for some in particular. What you
are proposing can be
> (or should be) possible using simple extensions.

In my applications, I am using a two component pattern
to provide the interceptor functionality I have
described (without container support).

public interface AbcService
{
    /* adds the interceptor to a list */
    public void register (int order, AbcInterceptor
interceptor);

    /* gets iterator from list and calls the first
plugin */
    public String doAbc (Object p);
}

/* both interceptor and the end point service
implements this interface.  Each implementation will
register itself with the AbcService.register() method.
*/
public interface AbcPlugin
{
    public String doAbc (Object p, Iterator plugins);
}

This pattern served me well.  However, there are some
downsides:

1. I need to create a register component for every
service that I want to be interceptable.
2. The end-point service also receives the interator,
which is a bit ugly :)
3. Interceptors shall not be allowed beyond the
end-point service.  However my current solution do not
prevent that becuase the registry service do not know
which plugin is the end point (unless I hard code it).

That's why I want it to be managed by the container. 
In that case, I can have interceptors whenever I need
it, wherever I want it.

> >
http://marc.theaimsgroup.com/?l=avalon-dev&m=107696768708344&w=2
> >
http://marc.theaimsgroup.com/?t=107678024500003&r=1&w=2
> >
> > Tell us what you think.

I want to comment on the use cases.

The interceptors are like aspects, except that aspects
are write once and apply to many places, while
interceptors are application specific.  I see
interceptors as extentions to components.

For example, I have an account management service
(service A), and I need to initialize some objects for
each account created (service B).

Without the interceptors, I may build a wrapper that
uses service A and B one by one.  The more complicated
the account creation business logic, the more messy
the wrapper, and hence high coupling and low SOC.

With interceptor, for each service that contributes to
the account creation process, an interceptor can be
designed.  Each interceptor need not know the
existence of the other.  Thus low coupling and high
SOC.

There are some other interesting points in the
previous discussions.  For instance the performance
issues with proxy.  I will need to take a closer look
at that.

Albert


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Albert Kwong <ma...@yahoo.com>.
> On Friday 16 April 2004 11:39, Albert Kwong wrote:
> > What do you think?  
> 
> I think you have thrown in some fresh thinking into
the pot :o)
> 
> However, maybe I am a bit tired, or maybe not smart
enough, but I have a bit 
> of problems to realize all the details.
> 
> Could you elaborate with a larger example;
> 
> MyClientImpl  -->  InterceptorOne --> InterceptorTwo
 -->  MyServiceImpl
> 
> 
> The following things is a bit unclear;
> 
> 1. How does InceptorOne and InterceptorTwo,
respectively, declare that they 
> should be 'injected' where they are?
> 

Here's the configuration.  The container shall sort
out the execution order based on the 'order' attribute
of the intercept element.

<targets>
    <target name='MyServiceImpl'>
        <!-- nothing new here -->
    </target>

    <target name='InterceptorOne'>
        <intercept order='1000'>
            <source>MyServiceImpl</source>
        </intercept>
    </target>

    <target name='InterceptorTwo'>
        <intercept order='2000'>
            <source>MyServiceImpl</source>
        </intercept>
    </target>

</targets>

> 2. You mentioned that the Proxy for AbcServiceImpl
is implementing 
> AbcInterceptor (just like InterceptorOne and
InterceptorTwo above, I guess). 
> What if the two interceptors above are removed from
the chain?

During deployment, the container can figure out the
interceptor sequence based on the order attribute. 
The chain-of-responsibility pattern will only apply if
there is at least one interceptor.

Therefore, if the two interceptors are removed, the
MyServiceImpl will be called like normal components.

> 3. Is there something in the name between AbcService
and AbcInceptor?

Having a naming convention between the AbcService and
the AbcInterceptor is nice to have, but not absolutely
necessary.  In the AbcService's meta tag, the
AbcService declares the type of the interceptor (
@avalon.interceptor type='AbcInterceptor' ).  In my
redundant email, I made a little amendment where you
can declare @avalon.interceptor.skin for operations. 
i.e.

/**
 * @avalon.interceptor type='AbcInterceptor'
 */
public interface AbcService
{
    /** this operation can be intercepted */
    public String doAbc ();

    /**
     * This one forbids interception.
     * @avalon.interceptor.skin
     */
    public String doDef ();
}

With this setup, it shall be possible to generate the
AbcInterceptor.java file from the build process and
include it in the api package.

Albert

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Albert Kwong <ma...@yahoo.com>.
Sorry I thought my post was lost.  Let me search for
your reply and get back to you.

Albert

 --- Niclas Hedhman <ni...@hedhman.org> 內容:> > I
have drafted some ideas here.  What do you
> think?
> 
> You posted this on Friday as well, and I had some
> questions, which still 
> remains. Would be great if you could clarify a bit.
> 
> 
> Niclas
> 
>
---------------------------------------------------------------------
> To unsubscribe, e-mail:
> dev-unsubscribe@avalon.apache.org
> For additional commands, e-mail:
> dev-help@avalon.apache.org
>  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Re: Container supported interceptable service

Posted by Niclas Hedhman <ni...@hedhman.org>.
> I have drafted some ideas here.  What do you think?

You posted this on Friday as well, and I had some questions, which still 
remains. Would be great if you could clarify a bit.


Niclas

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org