camel-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Strachan <james.strac...@gmail.com>
Subject Re: Data-driven routing
Date Fri, 27 Feb 2009 10:16:23 GMT
2009/2/26 jbower1950 <jim.bower@gmail.com>:
>
> I have tried that approach. It was pretty intuitive and made sense. The
> problem came when I had two routes from the same source (e.g., a log), one
> portion of which I wanted to route to one topic, the other part going to
> another topic. It appeared that, using the DSL with two routes, one message
> would go to one route (and get resolved properly), then the next would go to
> the next route (and not get resolved properly).
>
> So, graphically:
>
> Source 1 --> Xpath 1 --> Process A --> Sink 1
> Source 1 --> Xpath 2 --> Process A --> Sink 2
>
> It seemed that message 1 hit the first route and ended up in the right
> place. Message 2, which should have been resolved by the first route, went
> to the second route and did not proceed (no match on the xpath filter).

It depends a little on what the load balancing mechanism used inside
the endpoint.

For example if Source 1 was a JMS topic the above would work perfectly.

However the general case is going to be you want multiple filters to
be part of the same route.

If so just change your code to reuse the same route for the same
source string. e.g.


    for (Foo foo : foos) {
       String u = foo.getFromEndpointUri();
       String xp = foo.getXPath();
       Class type = foo.getBeanType(); // or processor type

       getFromFor(u).
         filter().xpath(xp).bean(type).
         end();  // this is important to close the filter block!
    }

...

 /** returns the route for the given endpoint */
RouteType getFromFor(String endpoint) {
  RouteType answer = routesMap.get(endpoint);
  if (answer == null) {
    answer = from(endpoint);
    routesMap.put(endpoint, answer);
  }
 return answer;
 }

basically you'd then the concatenating the routes together so all
filters on a single endpoint are part of the same route. So you'd be
doing in pseudo code...

from(source1).
  filter().xpath(xpath1).bean(bean1).end().
  filter().xpath(xpath2).bean(bean2).end().

etc

Another approach which is similar - but avoids issues if folks forget
the 'end()' and so is a little bit more rugged - is to treat each of
those routes as independent routes with their own URIs - then
separately chain them together in a separate route on the real
endpoint.

e.g.

 public void configure() {
      Multimap<String,String> uriMap = ...;


    List<Foo> foos = ... // some query
    for (Foo foo : foos) {
       String realUri = foo.getFromEndpointUri();
       String xp = foo.getXPath();
       Class type = foo.getBeanType(); // or processor type

       // lets add a route from the uri and filter to the given
processor

       String newUri = createNewUri(); // returns say direct:1234
       from(newUri).filter().xpath(xp).bean(type);

       // lets map the newUri to the real uri 'realUri'
      multimap.put(realUri, newUri);
    }

   // now lets bind these routes to the real URIs...
  for (Entry<String,List<String> entry : multimap.entries()) {
     String realUri = entry.getKey();
     List<String> indiviualUris = entry.getValue();
     from(realUri).to(indvidualUris);
  }
 }



-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Mime
View raw message