Having trouble using data from a header in a camel route - spring

In my camel route I am attempting to set a custom header and set the value of that header to data contained in the body. This header is later used in a SQL query, but it is not working correctly. I get an exception and it appears that the SQL query never gets the value of my header. Here is my camel route:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext trace="false" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:soapEndpoint"/>
<log message="${body}"/>
<setHeader headerName="accountNumber">
<simple>${body}</simple>
</setHeader>
<log message="The header value is ${header.accountNumber}" />
<to uri="sql:select account_name from hz_cust_accounts where account_number=:#accountNumber"/>
</route>
</camelContext>
<!-- this is the JDBC data source -->
<bean id="OracleDS" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#myserver:1558:mydb" />
<property name="username" value="someuser" />
<property name="password" value="somepass" />
</bean>
<!-- configure the Camel SQL component to use the JDBC data source -->
<bean id="sql" class="org.apache.camel.component.sql.SqlComponent">
<property name="dataSource" ref="OracleDS" />
</bean>
<cxf:cxfEndpoint id="soapEndpoint" address="http://localhost:10001/erpsoap"
serviceClass="apps.vci.camel.erptest.ERPSoapImpl"
wsdlURL="META-INF/wsdl/GetHzCustDetailsService.wsdl"
endpointName="s:getHzCustDetailsPort"
serviceName="s:getHzCustDetailsService"
xmlns:s="http://apps.vci.camel.erptest" />
</beans>
When the data travels through the route this is the error I get:
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [select account_name from hz_cust_accounts where account_number=?]; SQL state [99999]; error code [17004]; Invalid column type; nested exception is java.sql.SQLException: Invalid column type
It's like the SQL component doesn't get the value that's in the header. I do log the value after I set it and I do see that it's set correctly because I get this back in my log:
[ qtp665755841-45] route1 INFO The header value is 4089699
Anyone have any idea why this might be happening to me?
Thanks

Force the header accountNumber to be an Integer:
<setHeader headerName="accountNumber">
<simple>${bodyAs(Integer)}</simple>
</setHeader>
There are a few types which have a shorthand notation, so we can use String instead of java.lang.String. These are: byte[], String, Integer, Long. All other types must use their FQN name, e.g. org.w3c.dom.Document (Camel documentation).

Related

Spring - Social - Hibernate: Unable to register / login as UserConnection is not mapped

Working on trying to implement Spring Social aspects into a web app and having a few difficulties.
I'm using Postgresql, hibernate flavour of JPA and Spring with XML config. I found a well recommended JAR that meant I could carry on using JPA.
Details are here : https://github.com/michaellavelle/spring-social-hibernate-jpa
Imported using maven, followed instructions and all seemed well. When selecting login with Facebook (I'm not using their sdk) I receive a 500 with the error:
message org.hibernate.hql.internal.ast.QuerySyntaxException: UserConnection is not mapped [select u from UserConnection u where u.primaryKey.providerId = :providerId and u.primaryKey.providerUserId = :providerUserId order by u.rank]
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: UserConnection is not mapped [select u from UserConnection u where u.primaryKey.providerId = :providerId and u.primaryKey.providerUserId = :providerUserId order by u.rank]
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:350)
The error itself seems fairly self explanatory, there is no UserConnection table in the DB which leads me to think I've configured something incorrectly as this is the responsibility of the library.
Or am I completely mistaken? Any help is very much appreciated, would love to get this working.
EDIT:
Social.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:facebook="http://www.springframework.org/schema/social/facebook"
xmlns:twitter="http://www.springframework.org/schema/social/twitter"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:social="http://www.springframework.org/schema/social"
xmlns:linkedin="http://www.springframework.org/schema/social/linkedin"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/social/facebook
http://www.springframework.org/schema/social/spring-social-facebook.xsd
http://www.springframework.org/schema/social/linkedin
http://www.springframework.org/schema/social/spring-social-linkedin.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/social/twitter
http://www.springframework.org/schema/social/spring-social-twitter.xsd
http://www.springframework.org/schema/social
http://www.springframework.org/schema/social/spring-social.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<facebook:config app-id="${facebook.clientId}" app-secret="${facebook.clientSecret}" app-namespace="socialshowcase" />
<twitter:config app-id="${twitter.consumerKey}" app-secret="${twitter.consumerSecret}"/>
<linkedin:config app-id="${linkedin.consumerKey}" app-secret="${linkedin.consumerSecret}"/>
<!--<social:jdbc-connection-repository/>-->
<bean id="userIdSource" class="org.springframework.social.security.AuthenticationNameUserIdSource" />
<bean id="connectController" class="org.springframework.social.connect.web.ConnectController" autowire="constructor">
<property name="connectInterceptors">
<list>
<bean class="com.simpleSchedule.social.facebook.PostToWallAfterConnectInterceptor" />
<!--<bean class="org.springframework.social.showcase.twitter.TweetAfterConnectInterceptor" />-->
</list>
</property>
</bean>
<bean id="usersConnectionRepository"
class="org.springframework.social.connect.jpa.JpaUsersConnectionRepository">
<constructor-arg ref="userConnectionDao" />
<constructor-arg ref="connectionFactoryLocator" />
<constructor-arg ref="textEncryptor" />
</bean>
<bean class="org.springframework.social.connect.jpa.JpaConnectionRepository"
id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg value="#{request.userPrincipal.name}" />
<aop:scoped-proxy proxy-target-class="true" />
</bean>
<bean id="psc" class="org.springframework.social.connect.web.ProviderSignInController" autowire="constructor" />
<bean id="signInAdapter" class="com.simpleSchedule.social.singin.SimpleSignInAdapter" autowire="constructor" />
<bean id="disconnectController" class="org.springframework.social.facebook.web.DisconnectController"
c:_0-ref="usersConnectionRepository" c:_1="${facebook.clientSecret}" />
Michael Lavelle very kindly replied to a comment I posted on gitbub.
The solution was to add org.springframework.social.connect.jpa.hibernate.UserConnection as a mapping in my persistence.xml.
Full details can be viewed at the github issue

How to pass message from activemq queue to cxf client rest

I am creating a text message and put it in the activemq queue and i display it in the log. Now i need to pass this message to the cxf rs client to use it in the parameter. I am using blueprint to define the camel routes and cxf client.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
default-activation="eager" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"
xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint/cxf
http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd
http://cxf.apache.org/blueprint/jaxrs
http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd">
<!-- Beans -->
<bean id="myTransform" class="cxfcamel.MyTransform"/>
<bean id="serviceBean" class="cxfcamel.GreetingService" />
<bean id="rsprocessor" class="cxfcamel.RSProcessor"/>
<!-- Web Services -->
<jaxrs:server id="customerService" address="http://localhost:7171 /customers">
<jaxrs:serviceBeans>
<ref component-id="serviceBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<cxf:rsClient id="rsClient"
address="http://localhost:7171/customers/entry-point/register/nosJ"
serviceClass="cxfcamel.GreetingService">
</cxf:rsClient>
<!-- Camel Routes -->
<camelContext id="camel"
xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="timer://projectTimer?repeatCount=1" />
<bean ref="myTransform" method="transform" />
<to uri="activemq:queue:LOG.ME" />
</route>
<route>
<from uri="activemq:queue:LOG.ME" />
<to uri="log:ExampleActiveMQRouterBlueprint" />
</route>
<route>
<from uri="activemq:queue:LOG.ME" />
<setHeader headerName="Content-Type">
<constant>application/json</constant>
</setHeader>
<setHeader headerName="CamelHttpMethod">
<constant>PUT</constant>
</setHeader>
<to uri="cxfrs:bean:rsClient" />
</route>
</camelContext>
Can any one help me please?
Thanks
Both routes listen to activemq:queue:LOG.ME . A queue in ActiveMQ will consume the message and any other queue will not receive the message. You need to do 1 of 2 things:
Turn your queue into a topic so that both routes will receive the message. Topic vs Queue
Arrange your routes so only one route is listening to activemq:queue:LOG.ME.
There are two ways to accomplish this:
Turn your cxfrs:bean:rsClient invocation into a cxfrs:http://localhost:7171/customers/entry-point/register/nosJ and append the parameters at the end.
The documentation on this isn't very clear, but you might be able to use setHeader:
<setHeader headerName="CamelCxfRsQueryMap">
expression which returns a map
</setHeader>
This expression can be <bean>, a <groovy> embedded expression, etc.

Need help setting variable in Camel

I am trying to set a variable inside of my camel code so I can call this variable when I log my route execution. This variable needs to be set from an xpath statement.
Below is the code that is not working and I suspect that I need to set a variable that is equal to my xpath statement that is found in the log message but I don't know how to do that.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616"/>
<property name="userName" value="user"/>
<property name="password" value="password"/>
</bean>
<camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint">
<route id="Test_Message_Content_Route">
<from uri="activemq:queue:FirstQueue?username=user&password=password&concurrentConsumers=1&maxConcurrentConsumers=5"/>
<choice>
<when>
<xpath>//destination[text()='TEST']</xpath>
<log message="Test route invoked"/>
<split>
<xpath resultType="java.lang.String">//message_payload/text()</xpath>
<log message="Routed $xpath{//id/text()} to TEST QUEUE"/>
<to uri="activemq:queue:TestQueue?username=user&password=password"/>
</split>
</when>
<when>
<xpath>//destination[text()='DEV']</xpath>
<log message="Dev route invoked"/>
<split>
<xpath resultType="java.lang.String">//message_payload/text()</xpath>
<log message="Routed $xpath{//id/text()} to DEV QUEUE"/>
<to uri="activemq:queue:DevQueue?username=user&password=password"/>
</split>
</when>
<otherwise>
<log message="Sending message to DL Queue"/>
<to uri="activemq:queue:DLQueue?username=user&password=password"/>
</otherwise>
</choice>
</route>
</camelContext>
</blueprint>
I now have this working by using setHeader in my camel context like the following:
<setHeader headerName="id"><xpath>//id/text()</xpath></setHeader>
<log message="Routed ${header.id} to Test queue"/>

RabbitMQ and Camel with Multiple connection factories

I am trying to implement routing solution in which i need to read messages from one queue of rabbit mq and put message on different rabbit mq/different queue.
I was able to make read and write separately from queues but it is not working together.
Here is camel configuration file :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="amqp.spring.camel.component"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<jmxAgent id="agent" createConnector="false" disabled="true" />
<template id="wfcTemplate" />
<template id="routerTemplate" />
<route>
<from uri="spring-amqp:exchange1:queue1:ABCD?type=topic&autodelete=false&durable=true" />
<log message="Message available on a RabbitMQ Queue : ${body}" />
<to uri="spring-amqp:exchange2:queue2:EFGH?type=topic&autodelete=false&durable=true" />
</route>
</camelContext>
<rabbit:connection-factory id="producerConnectionFactory" connection-factory="producerConnectionFactory" />
<rabbit:template id="routerTemplate" connection-factory="producerConnectionFactory" message-converter="messageConverter" exchange="exchange2" />
<rabbit:admin connection-factory="producerConnectionFactory" />
<bean id="producerConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<property name="host" value="10.0.10.100"/>
<property name="port" value="5672"/>
<property name="username" value="shailesh"/>
<property name="password" value="shailesh"/>
<property name="virtualHost" value="vh1"/>
</bean>
<rabbit:connection-factory id="consumerConnectionFactory" connection-factory="consumerConnectionFactory"/>
<rabbit:template id="wfcTemplate" connection-factory="consumerConnectionFactory" message-converter="messageConverter" exchange="exchange1" />
<rabbit:admin connection-factory="consumerConnectionFactory"/>
<bean id="consumerConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<property name="host" value="10.0.10.101"/>
<property name="port" value="5672"/>
<property name="username" value="shailesh"/>
<property name="password" value="shailesh"/>
<property name="virtualHost" value="vh2"/>
</bean>
<!-- converters -->
<bean id="jsonMessageConverter" class="amqp.spring.converter.XStreamConverter"/>
<bean id="textMessageConverter" class="amqp.spring.converter.StringConverter"/>
<bean id="messageConverter" class="amqp.spring.converter.ContentTypeConverterFactory">
<property name="converters">
<map>
<entry key="application/json" value-ref="jsonMessageConverter"/>
<entry key="application/xml" value-ref="textMessageConverter"/>
</map>
</property>
<property name="fallbackConverter" ref="textMessageConverter"/>
</bean>
</beans>
There error I am getting is as follows :
[pache.camel.spring.Main.main()] SpringCamelContext INFO Total 1 routes, of which 1 is started.
[pache.camel.spring.Main.main()] SpringCamelContext INFO Apache Camel 2.10.3 (CamelContext: camel-1) started in 0.589 seconds
[PConsumer.SpringAMQPExecutor-1] route1 INFO Message available on a RabbitMQ Queue : Hello, world! Fri Feb 08 14:14:33 CST 2013
[l-1) thread #0 - amqp-producer] SpringAMQPProducer ERROR Could not deliver message via AMQP
java.lang.NullPointerException
at amqp.spring.camel.component.SpringAMQPProducer$AMQPProducerTask.run(SpringAMQPProducer.java:150)[camel-spring-amqp-1.4.jar:]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)[:1.7.0_11]
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)[:1.7.0_11]
at java.util.concurrent.FutureTask.run(FutureTask.java:166)[:1.7.0_11]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)[:1.7.0_11]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)[:1.7.0_11]
at java.lang.Thread.run(Thread.java:722)[:1.7.0_11]

mybatis configuration with spring3

I am trying to configure mybatis with spring 3. I am getting the following error while building my project.
Error creating bean with name 'datasource' defined in ServletContext resource [/WEB- INF/spring-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'driver' of bean class [org.apache.commons.dbcp.BasicDataSource]: Bean property 'driver' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
My spring-servel.xml is
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />
<context:component-scan
base-package="com.mycom.mycontroller.controller" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mydatabase"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mycom.mydatabase.db.mybatis.sqlmap" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
Jar files. I have added are
commons-dbcp-1.4.jar
commons-pool-1.6.jar
mybatis-3.1.0.jar
mybatis-spring-1.1.1.jar
mysql-connector-java-5.1.18-bin.jar
org.springframework.transaction-3.1.1.RELEASE.jar
and other spring jars
Please let me know if you need anything for more clarification
Problem has nothing to do with myBatis.
org.apache.commons.dbcp.BasicDataSource has not any "driver" property. I think you should user driverClassName instead.
See doc.

Resources