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
