I think you have a problem because the URI is wrong. I don't think you can
create a URI without URLEncoding the URI. Furthermore, I have never been a
fan of embedding SQL in the URI which is why I prefer the SQL component
over the JDBC one. What I would try is something like:

.setHeader(SqlConstants.SQL_QUERY, constant(createMyQuery())) // create
your query in a method
.setHeader("destination", new Expression() {
  @Override
  public <T> T evaluate(final Exchange exchange, final Class<T> type) {
    // code to pick correct data source as a string ... note datasource
must be registered in the registry so this code
    // might have to do that as well if it is new.
    return "sql" + calculatedDataSource;
  }
}
.recipientList(header("destination");

In this manner the code is cleaner. If the sql needs to be dynamic as well
create an expression to set it instead of using constant(). Furthermore, if
you create the expressions as named classes it will be more testable.

*Robert Simmons Jr. MSc. - Lead Java Architect @ EA*
*Author of: Hardcore Java (2003) and Maintainable Java (2012)*
*LinkedIn: **http://www.linkedin.com/pub/robert-simmons/40/852/a39
<http://www.linkedin.com/pub/robert-simmons/40/852/a39>*


On Mon, Jun 9, 2014 at 12:34 PM, Matt Raible <m...@raibledesigns.com> wrote:

> Thanks for the advice. I've tried to implement this. Here's what my code
> looks like:
>
> from("direct:lookup")
>     .process(new Processor() {
>         public void process(Exchange exchange) throws Exception {
>                 MemberRequest request =
> exchange.getIn().getBody(MemberRequest.class);
>                 String client = request.getClient();
>                 String memberId = request.getMemberId();
>                 String dataSourceName = "";
>                 switch (client) {
>                         case "client1":
>                                 dataSourceName = "dsforclient1";
>                                 break;
>                         case "client2":
>                                 dataSourceName = "dsforclient2";
>                                 break;
>                         default:
>                                 // todo: propagate to error
>                 }
>                 exchange.getOut().setHeader("dataSource", dataSourceName);
>                 exchange.getOut().setHeader("memberId", memberId);
>         }
>     })
> .recipientList(simple("sql:SELECT MEMBER_ID, ADDRESS1, ADDRESS2, ADDRESS3,
> " +
>         "COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5, COLUMN6, COLUMN7,
> COLUMN8, COLUMN9, COLUMN10, " +
>         "COLUMN11, COLUMN12, COLUMN13, COLUMN14, COLUMN15, COLUMN16,
> COLUMN17, COLUMN18, COLUMN19, COLUMN20 " +
>         "FROM MEMBER " +
>         "WHERE PATIENT.MEMBER_ID = :#memberId?dataSource=:#dataSource"))
> .process(new Processor() {
>         public void process(Exchange exchange) throws Exception {
>                 List<HashMap> data = (ArrayList<HashMap>)
> exchange.getIn().getBody();
>                 List<Member> members = new ArrayList<>();
>                 for (HashMap<String, String> map : data) {
>                         Member member = new Member();
>                         member.setMemberId(map.get("MEMBER_ID"));
>                         member.setFirstName(map.get("FIRST_NAME"));
>                         members.add(member);
>                 }
>                 exchange.getOut().setBody(members.get(0));
>         }
> });
>
> Unfortunately, this results in the following error:
>
> org.apache.camel.NoSuchEndpointException: No endpoint could be found for:
> ADDRESS1, please check your classpath contains the needed Camel component
> jar.
>
> I tried switching it to Antoine's recommendation, but it results in the
> same error.
>
>     .setHeader("target", simple("sql:SELECT MEMBER_ID, ADDRESS1, ADDRESS2,
> ADDRESS3, " +
>             "COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5, COLUMN6,
> COLUMN7, COLUMN8, COLUMN9, COLUMN10, " +
>             "COLUMN11, COLUMN12, COLUMN13, COLUMN14, COLUMN15, COLUMN16,
> COLUMN17, COLUMN18, COLUMN19, COLUMN20 " +
>             "FROM MEMBER " +
>             "WHERE PATIENT.MEMBER_ID =
> :#memberId?dataSource=:#dataSource"))
>     .recipientList(header("target"))
>
>
> On Jun 8, 2014, at 1:07 AM, Claus Ibsen <claus.ib...@gmail.com> wrote:
>
> > Hi
> >
> >
> > If you se <to> then the uri is computed statically, eg once when the
> > route is initialized.
> >
> > So the "dynamic to" is a good practice for dynamic uris
> > http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
> >
> > As you can the pass in the dataSource parameter dynamically. As well
> > construct the SQL dynamic too.
> >
> > And if you want this CASE SELECT construct in the routes as well, then
> > you can use the content based router. But having that logic in a java
> > class is maybe better.
> >
> >
> >
> > On Sat, Jun 7, 2014 at 5:31 PM, Antoine DESSAIGNE
> > <antoine.dessai...@gmail.com> wrote:
> >> Hello Matt,
> >>
> >> You'll have to use the recipient list [1] pattern:
> >>
> >> from("direct:projects")
> >>   .setProperty("ds", /* logic to convert client param to datasource name
> >> */)
> >>   .setHeader("target", simple("sql:select * from projects order by
> >> id?dataSource=${property.ds}")
> >>   .recipientList(header("target"))
> >>   .to(/* what you would do next after the SQL request */)
> >>
> >> Antoine.
> >>
> >> [1] http://camel.apache.org/recipient-list.html
> >>
> >>
> >> 2014-06-07 0:08 GMT+02:00 Matt Raible <m...@raibledesigns.com>:
> >>
> >>> Hello,
> >>>
> >>> I'm converting services written with IBM Message Broker 6.1 to Apache
> >>> Camel. Here's some of the logic I'm trying to convert:
> >>>
> >>> SET Environment.Variables.dataSource = '';
> >>> CASE
> UPPER(InputRoot.XMLNSC.ns:memberLookupRequest.ns:args0.ax21:Client)
> >>>        WHEN 'client1'  THEN SET Environment.Variables.dataSource =
> 'foo';
> >>>        WHEN 'client2'  THEN SET Environment.Variables.dataSource =
> 'bar';
> >>>        WHEN 'client3'          THEN SET
> Environment.Variables.dataSource
> >>> = 'baz';
> >>> END CASE;
> >>>
> >>> Basically, a parameter comes in and the dataSource is dynamically
> >>> configured based on it. What's the best way to do this with Apache
> Camel?
> >>> I'm guessing something like this might work (adopted from
> >>> http://camel.apache.org/sql-component.html):
> >>>
> >>> from("direct:projects")
> >>>  .setProperty("ds", /* logic to convert client param to datasource name
> >>> */)
> >>>  .to("sql:select * from projects order by
> id?dataSource=#${property.ds}")
> >>>
> >>> Is this the best way to configure dynamic datasources? For each
> >>> datasource, I realize I'll have to configure it as a @Bean with
> Spring's
> >>> JavaConfig.
> >>>
> >>> Thanks,
> >>>
> >>> Matt
> >
> >
> >
> > --
> > Claus Ibsen
> > -----------------
> > Red Hat, Inc.
> > Email: cib...@redhat.com
> > Twitter: davsclaus
> > Blog: http://davsclaus.com
> > Author of Camel in Action: http://www.manning.com/ibsen
> > hawtio: http://hawt.io/
> > fabric8: http://fabric8.io/
>
>

Reply via email to