On Fri, Aug 5, 2011 at 7:48 AM, Anuj Bhatia <[email protected]> wrote:
> Hello,
>
> I'm a Tuscany SCA newbie and am looking to solve an integration problem
> using SCA. I have a Java SCA component that needs to route a message to one
> of many external (non-SCA) web service end points. Each web service end
> point exposes an identical interface, only the URL to which it is deployed
> is different. As an example consider a CMS system that has multiple
> 'instances' one each for Authoring, Publishing, Staging, Production etc.
>
> The number of these external end points needs to be configurable and
> decoupled from the message router, so the message router can not simply have
> a fixed number of SCA references with each pointing to one of the end
> points. I'm not sure what's the best way to wire up the application using
> SCA, some options could be:
>
> 1. Define a separate SCA component for each of the services. Each of these
> SCA components provides a service with the same interface as the external
> web service and has a reference to the external URL. These components will
> just delegate all requests to the external web service. The message routing
> SCA component can dynamically look up the component that corresponds to the
> target end point from the injected ComponentContext.
>
> 2. Define a single reference on the message routing component and wire it up
> using a special custom binding. Here the custom binding can be designed to
> wrap a number of different end points with the actual target for a message
> selected at run time somehow.
>
> 3.  Define a single reference on the message routing component and add a
> reference policy interceptor. The interceptor can be designed to somehow
> look at the message and override the target end point at run time.
>
> I'm not sure whether 2 and 3 are even feasible. Any thoughts on the proposed
> solutions?
>
> Thanks
> Anuj
>
>
>
>
>

Hi Anuj

While I think all of the options a potentially feasible I'm attracted
most by 1. Tuscany at the moment is a little restricted in it's
ability to handle dynamic updates once  a reference has been used.
This is because the point at which a reference is first used is the
point at which the reference is resolved against the registry to find
matching endpoints. There is some code that repeats the process if the
infrastructure detects that endpoints have changed but I don't think
it currently detects the case that new services are added that match a
reference with multiplicity > 1

So two approaches that come immediately to mind depending on whether
or not you know all of the external services at the point at which the
composite is started.

1) If you know all the external service when you start the composite
you'll have a composite something like...

Composite1
   RouterComponent
   ComponentProxyToExternalService1
   ComponentProxyToExternalService2
   ComponentProxyToExternalService3

If you wire a reference (with multiplicity > 1) in RouterComponent to
the three services then you get a collection of references injected
into the component and you can make your selected based on the routing
algorithm. A downside of this is that, as the referenced services all
implement the same interface, it is difficult to distinguish one from
another. You would likely have to implement some interface on the
ComponentProxyToExternalService services in order to be able to
retrieve some meta-data in order to distinguish between them for
routing purposes.

2)  If you don't know all the external service when you start the
composite you'll have a composite that starts out something like...

Composite1
   RouterComponent
   ComponentProxyToExternalService1
   ComponentProxyToExternalService2

and at some point in the future while the system is running you add
the following composite to the domain

Composite2
   ComponentProxyToExternalService3

As I say we should be able to cope with this but I can't guarantee
that we do so an alternative approach is to wire each
ComponentProxyToExternalService to the router component and have them
call a service operation on the router component passing in self
reference (which can be retrieved from the component context).   This
also gives you the opportunity to pass in any meta-data that the
RouterCompoent requires to be able to select between the
ComponentProxyToExternalServices. RouterComponent component then
caches the service reference provided, along with any meta-data, and
uses this to call the services in the future.

On older versions of Tuscany I have seem others implement the routing
pattern using the getService() client api to retrieve a named service
from the domain based on a routing algorithm that is able to determine
a service name. I've not seem anyone trying to use the OASIS client
SPI from within a component implementation to retrieve a named
component service from the domain but in theory it's possible so that
could be another approach.

Hope that helps

Simon

-- 
Apache Tuscany committer: tuscany.apache.org
Co-author of a book about Tuscany and SCA: tuscanyinaction.com

Reply via email to