I'm not sure that's it. It's almost like the SQL Component doesn't like column 
names specified in the SQL. I tried changing it to "SELECT * FROM MEMBER" and 
then hard-coding the dataSource name to match a bean name, and it works. I 
guess I can live with using "select *", but you'd think any valid SQL would 
work.

Now, to set my dataSource dynamically. I have a @Bean configured as follows:

        @Bean(name = "ds.dsforclient1")
        public DataSource upmcDataWarehouse() {
                DriverManagerDataSource dataSource = new 
DriverManagerDataSource();
                // set properties
                return dataSource;
        }

I expect the following logic to set a "dataSource" header to "ds.dsforclient1".

>>                switch (client) {
>>                        case "client1":
>>                                dataSourceName = "dsforclient1";
>>                                break;
>>                        case "client2":
>>                                dataSourceName = "dsforclient2";
>>                                break;
>>                        default:
>>                                // todo: propagate to error
>>                }
>>                exchange.getOut().setHeader("dataSource", "ds." + 
>> dataSourceName);

However, I get the following error:

Failed to resolve endpoint: sql://mycustomsql?dataSource=%23dataSource due to: 
No bean could be found in the registry for: dataSource of type: 
javax.sql.DataSource

If I hard-code "?dataSource=ds.dsforclient1", it works fine. Is there a special 
syntax to tell the SQL component that this is a bean name?

Thanks,

Matt

On Jun 9, 2014, at 12:24 PM, Claus Ibsen <claus.ib...@gmail.com> wrote:

> Hi
> 
> Ah dataSource=:#dataSource should just be #dataSource, eg as its a
> regular lookup in the registry. See more at
> http://camel.apache.org/how-do-i-configure-endpoints.html
> 
> Its only the SQL component that has that special :#key for the SQL
> placeholders (eg with a colon).
> 
> 
> On Mon, Jun 9, 2014 at 7: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/
>> 
> 
> 
> 
> -- 
> 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