You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Jim Marino <jm...@myromatours.com> on 2006/04/26 09:28:30 UTC

extension apis

I've added the extension APIs to core for the following:

- Bindings (entry points/external services)
- Component types (atomic/composite)
- Policy

There are two basic levels, "simple" and "advanced". The simple  
approach, which is designed for the "80%" case, involves extending  
one of four support classes in core/extension. This approach hides as  
much of the infrastructure as possible. I would like to iterate over  
the API design since I am sure it will need to be changed as we  
encounter different use cases. I would also like to eventually  
automate creation of extension points further by creating IDE  
templates which produce many of the extension classes, since quite a  
few are wrote. The more advanced, or low-level, API can be released  
later as we gain confidence in the design since it exposes more  
capabilities.

For example, with the simple approach, one needs to do the following  
to implement a component type (the most complex scenario). The  
description is also probably more complex than the code:

1. Write the assembly artifacts and loader as described on the wiki

2. Extend ContextFactoryBuilderSupport, overriding the  
createContextFactory method, which passes back the ContextFactory for  
the component type. JavaContextFactoryBuilder is an example, which is  
a little more complex than it needs to be due to processing of  
annotations for things like init and destroy, which I intend to  
remove in refactorings today.

3. Write a Context and ContextFactory implementation. The  
ContextFactory implementation is used by the runtime to create  
configured Contexts, which manage component implementation instances.

The ContextFactory will be passed properties (name, object value) and  
wire factories. Wire factories are either of type SourceWireFactory  
or TargetWireFactory, corresponding to outgoing wires for a reference  
and incoming wires for a service respectively. Source and target  
invocation chains (per operation) are connected by the runtime to  
form a wire between two of the following: entry point, external  
service, or component. If a non-component client calls locateService,  
they will be returned a proxy fronting just the TargetWireFactory  
invocation chains. The ContextFactory must take those factories and  
pass them to a Context which "connects" them to the component  
implementation instance. For example, the Java support wraps source  
wire factories in an ObjectFactory which is used by an Injector to  
create a proxy that is injected into a method or field on the  
component implementation class. The proxy creation method is located  
on WireFactory, the base class for SourceWireFactory and  
TargetWireFactory.

3. Write a TargetInvoker implementation and extend  
WireBuilderSupport, overriding createInvoker. The latter creates the  
TargetInvoker, which is responsible for dispatching to an instance of  
the component type. This class also contains another method,  
handlesTargetType, which signals to the runtime which component  
implementation type the wire builder creates target invokers for. I  
intend to eliminate this as it may be reflected through generics. The  
TargetInvoker interface is pretty simple, one has to implement  
invokeTarget and clone.

For component implementation types, a target invoker will generally  
take the scope context the component is associated with and resolve  
the component instance against it when it receives an invocation. The  
TargetInvoker may cache the resolved result if the source is of a  
lesser scope than the target (this information is passed into the  
WireBuilder). Don't cache resolves when going from a greater to  
lesser scope since that will result in "crossed" contexts. Clone is  
necessary since TargetInvokers are cached on the source side of a  
wire per operation and passed through both
source and target invokcation chains, where it is "invoked" by the  
last interceptor in the target chain. TargetInvoker.clone() is called  
by the proxy invocation handler (e.g. JDKInvocationHandler) if the  
target invoker caches invocations on the first invoke of the  
operation and held there. Otherwise it uses a "stateless invoker".  
This allows us to optimize resolves away for sources of a lesser  
scope.  All of this is probably more detail than a component  
implementor will need to be aware of since the extension classes  
abstract this away.

4. Contribute the loader, ContextFactory, and WireBuilder  
implementations as a system module (along with the TargetInvoker  
class). They will automagically be registered in the runtime and  
everything should just work.

Please take a look and provide feedback.

Jim

Re: extension apis

Posted by James F Marino <ji...@gmail.com>.
On 4/26/06, ant elder <an...@gmail.com> wrote:
> Great stuff, this makes things much simpler. I've moved the JSON-RPC binding
> over to this API now which is fairly trivial but FWIW here are a few
> comments:
>
> 1) Is there anyway to avoid requiring the @Scope("MODULE") annotation on the
> EntryPointBuilderSupport subclass? Its easy to forget and not obvious whats
> wrong when you do.
>
Yea I'm going to fix this with the annotation processing work I'm doing now.

> 2) Wouldn't it be simpler if handlesBindingType returned the binding class
> instead of a boolean so all the logic could be in EntryPointBuilderSupport?
>
Yes. Actually, I'm going to get rid of this method altogether and just
reflect generics.  I already did the for the
ContextFactoryBuilderSupport, so someone subclasses it and uses
generics to describe the impl type it handles as in
JavaContextFactoryBuilder extends
ContextFactoryBuilderSupport<JavaImplementation>

> 3) Could there be a default implementation of
> EntryPointBuilderSupport.createEntryPointContextFactory which returns the
> EntryPointContextFactory impl in the core? Neither the Axis2 or JSONRPC
> bindings add any function to that.
>
The only problem with that is I we need those subclasses because that
is what the wire builder uses to determine if it can set a target
invoker during wiring.  Let me take a look and see if I can do
something with generics or some other mechanism.

> 4) Instead of being protected should the fields builderRegistry, wireService
> and messageFactory in EntryPointBuilderSupport be private and have getter
> methods?  This class is becoming like an SPI so getters would give a bit
> more flexibility if something needs to be changed later.
>
I don't have any strong opinion on this. I generally like to have the
ability to reset things in the parent so that would mean getters and
setters. I just collapsed it down to protected but I guess getters and
setters allow addition of extra behavior.  I'll change that as well.

Thanks for the feedback and let me know how this works out.
>    ...ant
>
>
> On 4/26/06, Jim Marino <jm...@myromatours.com> wrote:
> >
> > I've added the extension APIs to core for the following:
> >
> > - Bindings (entry points/external services)
> > - Component types (atomic/composite)
> > - Policy
> >
> > There are two basic levels, "simple" and "advanced". The simple
> > approach, which is designed for the "80%" case, involves extending
> > one of four support classes in core/extension. This approach hides as
> > much of the infrastructure as possible. I would like to iterate over
> > the API design since I am sure it will need to be changed as we
> > encounter different use cases. I would also like to eventually
> > automate creation of extension points further by creating IDE
> > templates which produce many of the extension classes, since quite a
> > few are wrote. The more advanced, or low-level, API can be released
> > later as we gain confidence in the design since it exposes more
> > capabilities.
> >
> > For example, with the simple approach, one needs to do the following
> > to implement a component type (the most complex scenario). The
> > description is also probably more complex than the code:
> >
> > 1. Write the assembly artifacts and loader as described on the wiki
> >
> > 2. Extend ContextFactoryBuilderSupport, overriding the
> > createContextFactory method, which passes back the ContextFactory for
> > the component type. JavaContextFactoryBuilder is an example, which is
> > a little more complex than it needs to be due to processing of
> > annotations for things like init and destroy, which I intend to
> > remove in refactorings today.
> >
> > 3. Write a Context and ContextFactory implementation. The
> > ContextFactory implementation is used by the runtime to create
> > configured Contexts, which manage component implementation instances.
> >
> > The ContextFactory will be passed properties (name, object value) and
> > wire factories. Wire factories are either of type SourceWireFactory
> > or TargetWireFactory, corresponding to outgoing wires for a reference
> > and incoming wires for a service respectively. Source and target
> > invocation chains (per operation) are connected by the runtime to
> > form a wire between two of the following: entry point, external
> > service, or component. If a non-component client calls locateService,
> > they will be returned a proxy fronting just the TargetWireFactory
> > invocation chains. The ContextFactory must take those factories and
> > pass them to a Context which "connects" them to the component
> > implementation instance. For example, the Java support wraps source
> > wire factories in an ObjectFactory which is used by an Injector to
> > create a proxy that is injected into a method or field on the
> > component implementation class. The proxy creation method is located
> > on WireFactory, the base class for SourceWireFactory and
> > TargetWireFactory.
> >
> > 3. Write a TargetInvoker implementation and extend
> > WireBuilderSupport, overriding createInvoker. The latter creates the
> > TargetInvoker, which is responsible for dispatching to an instance of
> > the component type. This class also contains another method,
> > handlesTargetType, which signals to the runtime which component
> > implementation type the wire builder creates target invokers for. I
> > intend to eliminate this as it may be reflected through generics. The
> > TargetInvoker interface is pretty simple, one has to implement
> > invokeTarget and clone.
> >
> > For component implementation types, a target invoker will generally
> > take the scope context the component is associated with and resolve
> > the component instance against it when it receives an invocation. The
> > TargetInvoker may cache the resolved result if the source is of a
> > lesser scope than the target (this information is passed into the
> > WireBuilder). Don't cache resolves when going from a greater to
> > lesser scope since that will result in "crossed" contexts. Clone is
> > necessary since TargetInvokers are cached on the source side of a
> > wire per operation and passed through both
> > source and target invokcation chains, where it is "invoked" by the
> > last interceptor in the target chain. TargetInvoker.clone() is called
> > by the proxy invocation handler (e.g. JDKInvocationHandler) if the
> > target invoker caches invocations on the first invoke of the
> > operation and held there. Otherwise it uses a "stateless invoker".
> > This allows us to optimize resolves away for sources of a lesser
> > scope.  All of this is probably more detail than a component
> > implementor will need to be aware of since the extension classes
> > abstract this away.
> >
> > 4. Contribute the loader, ContextFactory, and WireBuilder
> > implementations as a system module (along with the TargetInvoker
> > class). They will automagically be registered in the runtime and
> > everything should just work.
> >
> > Please take a look and provide feedback.
> >
> > Jim
> >
>
>

Re: extension apis

Posted by ant elder <an...@gmail.com>.
Great stuff, this makes things much simpler. I've moved the JSON-RPC binding
over to this API now which is fairly trivial but FWIW here are a few
comments:

1) Is there anyway to avoid requiring the @Scope("MODULE") annotation on the
EntryPointBuilderSupport subclass? Its easy to forget and not obvious whats
wrong when you do.

2) Wouldn't it be simpler if handlesBindingType returned the binding class
instead of a boolean so all the logic could be in EntryPointBuilderSupport?

3) Could there be a default implementation of
EntryPointBuilderSupport.createEntryPointContextFactory which returns the
EntryPointContextFactory impl in the core? Neither the Axis2 or JSONRPC
bindings add any function to that.

4) Instead of being protected should the fields builderRegistry, wireService
and messageFactory in EntryPointBuilderSupport be private and have getter
methods?  This class is becoming like an SPI so getters would give a bit
more flexibility if something needs to be changed later.

   ...ant


On 4/26/06, Jim Marino <jm...@myromatours.com> wrote:
>
> I've added the extension APIs to core for the following:
>
> - Bindings (entry points/external services)
> - Component types (atomic/composite)
> - Policy
>
> There are two basic levels, "simple" and "advanced". The simple
> approach, which is designed for the "80%" case, involves extending
> one of four support classes in core/extension. This approach hides as
> much of the infrastructure as possible. I would like to iterate over
> the API design since I am sure it will need to be changed as we
> encounter different use cases. I would also like to eventually
> automate creation of extension points further by creating IDE
> templates which produce many of the extension classes, since quite a
> few are wrote. The more advanced, or low-level, API can be released
> later as we gain confidence in the design since it exposes more
> capabilities.
>
> For example, with the simple approach, one needs to do the following
> to implement a component type (the most complex scenario). The
> description is also probably more complex than the code:
>
> 1. Write the assembly artifacts and loader as described on the wiki
>
> 2. Extend ContextFactoryBuilderSupport, overriding the
> createContextFactory method, which passes back the ContextFactory for
> the component type. JavaContextFactoryBuilder is an example, which is
> a little more complex than it needs to be due to processing of
> annotations for things like init and destroy, which I intend to
> remove in refactorings today.
>
> 3. Write a Context and ContextFactory implementation. The
> ContextFactory implementation is used by the runtime to create
> configured Contexts, which manage component implementation instances.
>
> The ContextFactory will be passed properties (name, object value) and
> wire factories. Wire factories are either of type SourceWireFactory
> or TargetWireFactory, corresponding to outgoing wires for a reference
> and incoming wires for a service respectively. Source and target
> invocation chains (per operation) are connected by the runtime to
> form a wire between two of the following: entry point, external
> service, or component. If a non-component client calls locateService,
> they will be returned a proxy fronting just the TargetWireFactory
> invocation chains. The ContextFactory must take those factories and
> pass them to a Context which "connects" them to the component
> implementation instance. For example, the Java support wraps source
> wire factories in an ObjectFactory which is used by an Injector to
> create a proxy that is injected into a method or field on the
> component implementation class. The proxy creation method is located
> on WireFactory, the base class for SourceWireFactory and
> TargetWireFactory.
>
> 3. Write a TargetInvoker implementation and extend
> WireBuilderSupport, overriding createInvoker. The latter creates the
> TargetInvoker, which is responsible for dispatching to an instance of
> the component type. This class also contains another method,
> handlesTargetType, which signals to the runtime which component
> implementation type the wire builder creates target invokers for. I
> intend to eliminate this as it may be reflected through generics. The
> TargetInvoker interface is pretty simple, one has to implement
> invokeTarget and clone.
>
> For component implementation types, a target invoker will generally
> take the scope context the component is associated with and resolve
> the component instance against it when it receives an invocation. The
> TargetInvoker may cache the resolved result if the source is of a
> lesser scope than the target (this information is passed into the
> WireBuilder). Don't cache resolves when going from a greater to
> lesser scope since that will result in "crossed" contexts. Clone is
> necessary since TargetInvokers are cached on the source side of a
> wire per operation and passed through both
> source and target invokcation chains, where it is "invoked" by the
> last interceptor in the target chain. TargetInvoker.clone() is called
> by the proxy invocation handler (e.g. JDKInvocationHandler) if the
> target invoker caches invocations on the first invoke of the
> operation and held there. Otherwise it uses a "stateless invoker".
> This allows us to optimize resolves away for sources of a lesser
> scope.  All of this is probably more detail than a component
> implementor will need to be aware of since the extension classes
> abstract this away.
>
> 4. Contribute the loader, ContextFactory, and WireBuilder
> implementations as a system module (along with the TargetInvoker
> class). They will automagically be registered in the runtime and
> everything should just work.
>
> Please take a look and provide feedback.
>
> Jim
>

Re: extension apis

Posted by Jim Marino <jm...@myromatours.com>.
Nice job on the web services extensions...I noticed you kind of got  
stuck with some nasty integration issues and had the brunt of dealing  
with them.


Yea I'd go ahead and move them up. FYI, we're working on some more  
things which may introduce changes but we'll make the appropriate  
refactors if needed.

Jim


On May 3, 2006, at 11:57 AM, ant elder wrote:

> Anyone had a chance to look at this, could i move
> ExternalServiceTargetInvoker and ExternalServiceInvoker to  
> extensions in the
> core project?
>
>   ...ant
>
> On 4/30/06, ant elder <an...@gmail.com> wrote:
>
>>
>> I've just committed the first cut at moving all the Axis2 binding  
>> over to
>> this. I wasn't completely sure how the externalService part was  
>> supposed to
>> work, maybe you could have a look at what I've done and comment.
>>
>> The main relevant classes are ExternalWebServiceBuilder,
>> ExternalServiceTargetInvoker, ExternalServiceInvoker, and
>> Axis2ServiceInvoker.
>>
>>
>> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/ 
>> bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/ 
>> axis2/builder/ExternalWebServiceBuilder.java
>>
>> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/ 
>> bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/ 
>> axis2/handler/ExternalServiceTargetInvoker.java
>>
>> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/ 
>> bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/ 
>> axis2/handler/ExternalServiceInvoker.java
>>
>> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/ 
>> bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/ 
>> axis2/handler/Axis2ServiceInvoker.java
>>
>> ExternalServiceTargetInvoker and ExternalServiceInvoker have nothing
>> specific to the binding so I wondered if something like them  
>> should be
>> provided in the o.a.t.core.extension package.
>>
>> If the code is mostly ok as it is now then the main remaining work  
>> is to
>> change the WS entryPoint to use the TomcatHost mechanism to  
>> register the
>> servlet, and to move all the configuring of each entryPoint out  
>> the servlet
>> init.  Jeremy, I've not yet been able to get either of these to  
>> work yet so
>> if you're about and have time to chat about this on IRC let me know.
>>
>>    ...ant
>>
>> On 4/26/06, Jim Marino <jm...@myromatours.com> wrote:
>>
>> > I've added the extension APIs to core for the following:
>> >
>> > - Bindings (entry points/external services)
>> > - Component types (atomic/composite)
>> > - Policy
>> >
>> > There are two basic levels, "simple" and "advanced". The simple
>> > approach, which is designed for the "80%" case, involves extending
>> > one of four support classes in core/extension. This approach  
>> hides as
>> > much of the infrastructure as possible. I would like to iterate  
>> over
>> > the API design since I am sure it will need to be changed as we
>> > encounter different use cases. I would also like to eventually
>> > automate creation of extension points further by creating IDE
>> > templates which produce many of the extension classes, since  
>> quite a
>> > few are wrote. The more advanced, or low-level, API can be released
>> > later as we gain confidence in the design since it exposes more
>> > capabilities.
>> >
>> > For example, with the simple approach, one needs to do the  
>> following
>> > to implement a component type (the most complex scenario). The
>> > description is also probably more complex than the code:
>> >
>> > 1. Write the assembly artifacts and loader as described on the wiki
>> >
>> > 2. Extend ContextFactoryBuilderSupport, overriding the
>> > createContextFactory method, which passes back the  
>> ContextFactory for
>> > the component type. JavaContextFactoryBuilder is an example,  
>> which is
>> > a little more complex than it needs to be due to processing of
>> > annotations for things like init and destroy, which I intend to
>> > remove in refactorings today.
>> >
>> > 3. Write a Context and ContextFactory implementation. The
>> > ContextFactory implementation is used by the runtime to create
>> > configured Contexts, which manage component implementation  
>> instances.
>> >
>> > The ContextFactory will be passed properties (name, object  
>> value) and
>> > wire factories. Wire factories are either of type SourceWireFactory
>> > or TargetWireFactory, corresponding to outgoing wires for a  
>> reference
>> > and incoming wires for a service respectively. Source and target
>> > invocation chains (per operation) are connected by the runtime to
>> > form a wire between two of the following: entry point, external
>> > service, or component. If a non-component client calls  
>> locateService,
>> > they will be returned a proxy fronting just the TargetWireFactory
>> > invocation chains. The ContextFactory must take those factories and
>> > pass them to a Context which "connects" them to the component
>> > implementation instance. For example, the Java support wraps source
>> > wire factories in an ObjectFactory which is used by an Injector to
>> > create a proxy that is injected into a method or field on the
>> > component implementation class. The proxy creation method is  
>> located
>> > on WireFactory, the base class for SourceWireFactory and
>> > TargetWireFactory.
>> >
>> > 3. Write a TargetInvoker implementation and extend
>> > WireBuilderSupport, overriding createInvoker. The latter creates  
>> the
>> > TargetInvoker, which is responsible for dispatching to an  
>> instance of
>> > the component type. This class also contains another method,
>> > handlesTargetType, which signals to the runtime which component
>> > implementation type the wire builder creates target invokers for. I
>> > intend to eliminate this as it may be reflected through  
>> generics. The
>> > TargetInvoker interface is pretty simple, one has to implement
>> > invokeTarget and clone.
>> >
>> > For component implementation types, a target invoker will generally
>> > take the scope context the component is associated with and resolve
>> > the component instance against it when it receives an  
>> invocation. The
>> > TargetInvoker may cache the resolved result if the source is of a
>> > lesser scope than the target (this information is passed into the
>> > WireBuilder). Don't cache resolves when going from a greater to
>> > lesser scope since that will result in "crossed" contexts. Clone is
>> > necessary since TargetInvokers are cached on the source side of a
>> > wire per operation and passed through both
>> > source and target invokcation chains, where it is "invoked" by the
>> > last interceptor in the target chain. TargetInvoker.clone() is  
>> called
>> > by the proxy invocation handler (e.g. JDKInvocationHandler) if the
>> > target invoker caches invocations on the first invoke of the
>> > operation and held there. Otherwise it uses a "stateless invoker".
>> > This allows us to optimize resolves away for sources of a lesser
>> > scope.  All of this is probably more detail than a component
>> > implementor will need to be aware of since the extension classes
>> > abstract this away.
>> >
>> > 4. Contribute the loader, ContextFactory, and WireBuilder
>> > implementations as a system module (along with the TargetInvoker
>> > class). They will automagically be registered in the runtime and
>> > everything should just work.
>> >
>> > Please take a look and provide feedback.
>> >
>> > Jim
>> >
>>
>>
>


Re: extension apis

Posted by ant elder <an...@gmail.com>.
Anyone had a chance to look at this, could i move
ExternalServiceTargetInvoker and ExternalServiceInvoker to extensions in the
core project?

   ...ant

On 4/30/06, ant elder <an...@gmail.com> wrote:
>
> I've just committed the first cut at moving all the Axis2 binding over to
> this. I wasn't completely sure how the externalService part was supposed to
> work, maybe you could have a look at what I've done and comment.
>
> The main relevant classes are ExternalWebServiceBuilder,
> ExternalServiceTargetInvoker, ExternalServiceInvoker, and
> Axis2ServiceInvoker.
>
>
> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceBuilder.java
>
> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/handler/ExternalServiceTargetInvoker.java
>
> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/handler/ExternalServiceInvoker.java
>
> http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/handler/Axis2ServiceInvoker.java
>
> ExternalServiceTargetInvoker and ExternalServiceInvoker have nothing
> specific to the binding so I wondered if something like them should be
> provided in the o.a.t.core.extension package.
>
> If the code is mostly ok as it is now then the main remaining work is to
> change the WS entryPoint to use the TomcatHost mechanism to register the
> servlet, and to move all the configuring of each entryPoint out the servlet
> init.  Jeremy, I've not yet been able to get either of these to work yet so
> if you're about and have time to chat about this on IRC let me know.
>
>    ...ant
>
> On 4/26/06, Jim Marino <jm...@myromatours.com> wrote:
>
> > I've added the extension APIs to core for the following:
> >
> > - Bindings (entry points/external services)
> > - Component types (atomic/composite)
> > - Policy
> >
> > There are two basic levels, "simple" and "advanced". The simple
> > approach, which is designed for the "80%" case, involves extending
> > one of four support classes in core/extension. This approach hides as
> > much of the infrastructure as possible. I would like to iterate over
> > the API design since I am sure it will need to be changed as we
> > encounter different use cases. I would also like to eventually
> > automate creation of extension points further by creating IDE
> > templates which produce many of the extension classes, since quite a
> > few are wrote. The more advanced, or low-level, API can be released
> > later as we gain confidence in the design since it exposes more
> > capabilities.
> >
> > For example, with the simple approach, one needs to do the following
> > to implement a component type (the most complex scenario). The
> > description is also probably more complex than the code:
> >
> > 1. Write the assembly artifacts and loader as described on the wiki
> >
> > 2. Extend ContextFactoryBuilderSupport, overriding the
> > createContextFactory method, which passes back the ContextFactory for
> > the component type. JavaContextFactoryBuilder is an example, which is
> > a little more complex than it needs to be due to processing of
> > annotations for things like init and destroy, which I intend to
> > remove in refactorings today.
> >
> > 3. Write a Context and ContextFactory implementation. The
> > ContextFactory implementation is used by the runtime to create
> > configured Contexts, which manage component implementation instances.
> >
> > The ContextFactory will be passed properties (name, object value) and
> > wire factories. Wire factories are either of type SourceWireFactory
> > or TargetWireFactory, corresponding to outgoing wires for a reference
> > and incoming wires for a service respectively. Source and target
> > invocation chains (per operation) are connected by the runtime to
> > form a wire between two of the following: entry point, external
> > service, or component. If a non-component client calls locateService,
> > they will be returned a proxy fronting just the TargetWireFactory
> > invocation chains. The ContextFactory must take those factories and
> > pass them to a Context which "connects" them to the component
> > implementation instance. For example, the Java support wraps source
> > wire factories in an ObjectFactory which is used by an Injector to
> > create a proxy that is injected into a method or field on the
> > component implementation class. The proxy creation method is located
> > on WireFactory, the base class for SourceWireFactory and
> > TargetWireFactory.
> >
> > 3. Write a TargetInvoker implementation and extend
> > WireBuilderSupport, overriding createInvoker. The latter creates the
> > TargetInvoker, which is responsible for dispatching to an instance of
> > the component type. This class also contains another method,
> > handlesTargetType, which signals to the runtime which component
> > implementation type the wire builder creates target invokers for. I
> > intend to eliminate this as it may be reflected through generics. The
> > TargetInvoker interface is pretty simple, one has to implement
> > invokeTarget and clone.
> >
> > For component implementation types, a target invoker will generally
> > take the scope context the component is associated with and resolve
> > the component instance against it when it receives an invocation. The
> > TargetInvoker may cache the resolved result if the source is of a
> > lesser scope than the target (this information is passed into the
> > WireBuilder). Don't cache resolves when going from a greater to
> > lesser scope since that will result in "crossed" contexts. Clone is
> > necessary since TargetInvokers are cached on the source side of a
> > wire per operation and passed through both
> > source and target invokcation chains, where it is "invoked" by the
> > last interceptor in the target chain. TargetInvoker.clone() is called
> > by the proxy invocation handler (e.g. JDKInvocationHandler) if the
> > target invoker caches invocations on the first invoke of the
> > operation and held there. Otherwise it uses a "stateless invoker".
> > This allows us to optimize resolves away for sources of a lesser
> > scope.  All of this is probably more detail than a component
> > implementor will need to be aware of since the extension classes
> > abstract this away.
> >
> > 4. Contribute the loader, ContextFactory, and WireBuilder
> > implementations as a system module (along with the TargetInvoker
> > class). They will automagically be registered in the runtime and
> > everything should just work.
> >
> > Please take a look and provide feedback.
> >
> > Jim
> >
>
>

Re: extension apis

Posted by ant elder <an...@gmail.com>.
I've just committed the first cut at moving all the Axis2 binding over to
this. I wasn't completely sure how the externalService part was supposed to
work, maybe you could have a look at what I've done and comment.

The main relevant classes are ExternalWebServiceBuilder,
ExternalServiceTargetInvoker, ExternalServiceInvoker, and
Axis2ServiceInvoker.

http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceBuilder.java
http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/handler/ExternalServiceTargetInvoker.java
http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/handler/ExternalServiceInvoker.java
http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/handler/Axis2ServiceInvoker.java

ExternalServiceTargetInvoker and ExternalServiceInvoker have nothing
specific to the binding so I wondered if something like them should be
provided in the o.a.t.core.extension package.

If the code is mostly ok as it is now then the main remaining work is to
change the WS entryPoint to use the TomcatHost mechanism to register the
servlet, and to move all the configuring of each entryPoint out the servlet
init.  Jeremy, I've not yet been able to get either of these to work yet so
if you're about and have time to chat about this on IRC let me know.

   ...ant

On 4/26/06, Jim Marino <jm...@myromatours.com> wrote:
>
> I've added the extension APIs to core for the following:
>
> - Bindings (entry points/external services)
> - Component types (atomic/composite)
> - Policy
>
> There are two basic levels, "simple" and "advanced". The simple
> approach, which is designed for the "80%" case, involves extending
> one of four support classes in core/extension. This approach hides as
> much of the infrastructure as possible. I would like to iterate over
> the API design since I am sure it will need to be changed as we
> encounter different use cases. I would also like to eventually
> automate creation of extension points further by creating IDE
> templates which produce many of the extension classes, since quite a
> few are wrote. The more advanced, or low-level, API can be released
> later as we gain confidence in the design since it exposes more
> capabilities.
>
> For example, with the simple approach, one needs to do the following
> to implement a component type (the most complex scenario). The
> description is also probably more complex than the code:
>
> 1. Write the assembly artifacts and loader as described on the wiki
>
> 2. Extend ContextFactoryBuilderSupport, overriding the
> createContextFactory method, which passes back the ContextFactory for
> the component type. JavaContextFactoryBuilder is an example, which is
> a little more complex than it needs to be due to processing of
> annotations for things like init and destroy, which I intend to
> remove in refactorings today.
>
> 3. Write a Context and ContextFactory implementation. The
> ContextFactory implementation is used by the runtime to create
> configured Contexts, which manage component implementation instances.
>
> The ContextFactory will be passed properties (name, object value) and
> wire factories. Wire factories are either of type SourceWireFactory
> or TargetWireFactory, corresponding to outgoing wires for a reference
> and incoming wires for a service respectively. Source and target
> invocation chains (per operation) are connected by the runtime to
> form a wire between two of the following: entry point, external
> service, or component. If a non-component client calls locateService,
> they will be returned a proxy fronting just the TargetWireFactory
> invocation chains. The ContextFactory must take those factories and
> pass them to a Context which "connects" them to the component
> implementation instance. For example, the Java support wraps source
> wire factories in an ObjectFactory which is used by an Injector to
> create a proxy that is injected into a method or field on the
> component implementation class. The proxy creation method is located
> on WireFactory, the base class for SourceWireFactory and
> TargetWireFactory.
>
> 3. Write a TargetInvoker implementation and extend
> WireBuilderSupport, overriding createInvoker. The latter creates the
> TargetInvoker, which is responsible for dispatching to an instance of
> the component type. This class also contains another method,
> handlesTargetType, which signals to the runtime which component
> implementation type the wire builder creates target invokers for. I
> intend to eliminate this as it may be reflected through generics. The
> TargetInvoker interface is pretty simple, one has to implement
> invokeTarget and clone.
>
> For component implementation types, a target invoker will generally
> take the scope context the component is associated with and resolve
> the component instance against it when it receives an invocation. The
> TargetInvoker may cache the resolved result if the source is of a
> lesser scope than the target (this information is passed into the
> WireBuilder). Don't cache resolves when going from a greater to
> lesser scope since that will result in "crossed" contexts. Clone is
> necessary since TargetInvokers are cached on the source side of a
> wire per operation and passed through both
> source and target invokcation chains, where it is "invoked" by the
> last interceptor in the target chain. TargetInvoker.clone() is called
> by the proxy invocation handler (e.g. JDKInvocationHandler) if the
> target invoker caches invocations on the first invoke of the
> operation and held there. Otherwise it uses a "stateless invoker".
> This allows us to optimize resolves away for sources of a lesser
> scope.  All of this is probably more detail than a component
> implementor will need to be aware of since the extension classes
> abstract this away.
>
> 4. Contribute the loader, ContextFactory, and WireBuilder
> implementations as a system module (along with the TargetInvoker
> class). They will automagically be registered in the runtime and
> everything should just work.
>
> Please take a look and provide feedback.
>
> Jim
>