Camel + sql + error handling - apache-camel

I have a task to handle all incoming messages within the route and save them to database.
My route starts with webservice (camel-cxf), and then process to ejb and return soap response.
I've decided to use camel-sql component. As far as I don't have any problems with logging incoming message:
<camelContext id="InstitutionContext" xmlns="http://camel.apache.org/schema/spring">
<onException>
<exception>org.example.MyException</exception>
<continued><constant>true</constant></continued>
<to uri="bean:myExceptionHandler?method=handle" />
</onException>
<route id="InstitutionRoute" >
<from uri="direct:start" />
<to uri="sql:insert into translog(id,type,data) values(2,'IN',#)" />
<split>
<tokenize token="\n" />
<unmarshal>
<csv delimiter=";" />
</unmarshal>
<process ref="InstitutionProcessorTest" />
</split>
<to uri="bean:myExceptionHandler?method=checkErrors" />
</route>
</camelContext>
but I don't have idea how to handle exceptions and save them in the form of SOAP message.
<onCompletion onFailureOnly="true">
<to uri="sql:insert into translog(id,type,data) values(2,'ERROR',#)" />
</onCompletion>
but it saves original message in data column. Is there any body who can help?

I might be misunderstanding the question but it looks you are trying to save the SOAP message in XML format if there is a exception.
By default the dataFormat for CXF is POJO meaning it sends a POJO around the camel route i.e. the SOAP XML is converted to a POJO.
Two options come to mind:
Set the dataformat to message or payload. This will send the XML message across the camel route instead of a POJO
Marshall the POJO into a XML message and save it.

Related

Is it possible to read a file after receiving an event?

I'm using a ActiveMQ Broker with built-in Camel Routes. I want to read a file after an Event received.
<pseudo>
from Event A
read File XY
to Event B with Body from File XY
</pseuod>
I simple tried moving files from a temporary directory based on an event but only event B is written. In the Log file are no Exceptions or Error messages.
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<!-- You can use Spring XML syntax to define the routes here using the <route> element -->
<route>
<description>Example Camel Route</description>
<from uri="activemq:example.A"/>
<from uri="file://tmp/a?delete=true"/>
<to uri="file://tmp/b?overruleFile=copy-of-${file:name}"/>
<to uri="activemq:example.B"/>
</route>
</camelContext>
Update with working solution for single file:
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<!-- You can use Spring XML syntax to define the routes here using the <route> element -->
<route>
<description>Example Camel Route</description>
<from uri="activemq:example.A"/>
<pollEnrich>
<constant>file:///tmp/a?fileName=file1</constant>
</pollEnrich>
<log message="file content ${body}"/>
<to uri="activemq:example.B"/>
</route>
</camelContext>
You need to use Content Enrichers for this. This is exactly what you are looking for.
<route>
<from uri="activemq:example.A"/>
<pollEnrich>
<constant>file://tmp/a?delete=true</constant>
</pollEnrich>
<to uri="activemq:example.B"/>
</route>
Please be aware that for camel version 2.15 or older
pollEnrich does not access any data from the current Exchange which
means when polling it cannot use any of the existing headers you may
have set on the Exchange. For example you cannot set a filename in the
Exchange.FILE_NAME header and use pollEnrich to consume only that
file. For that you must set the filename in the endpoint URI.

Camel exchange failed without an exception

After upgrading from Camel 2.1 to 2.17 and some code modification we are having some problems with the exception handling in Camel. We send message from app A to app B. The happy flow works fine, but the unhappy flow doesn't.
We send the message to cause an exception but it is not correctly handled in the onexception block.
Actually, we see the following tracelog: ProcessTaskEx - message received, but I don't see: ProcessTaskEx - exception
The exception we get from Camel is:
camel exchange failed without an exception: <SOAP-ENV:Fault xmlns:SOAP-ENV>
Our route looks like this, any idea what the problem could be? Thank you very much for your time community! :)
<?xml version="1.0" encoding="ASCII"?>
<routes xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="switchyard://ProcessTaskEx"/>
<log message="ProcessTaskEx - message received: ${body}" loggingLevel="DEBUG" logName="WebServiceQueues" />
<to uri="switchyard://RequestCapacity"/>
<onException>
<exception>java.lang.Exception</exception>
<exception>webservicequeues.utilities.WebServiceQueueException</exception>
<log message="ProcessTaskEx - exception" loggingLevel="DEBUG" logName="WebServiceQueues" />
<redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="60000" maximumRedeliveryDelay="900000" retriesExhaustedLogLevel="INFO" retryAttemptedLogLevel="INFO"/>
<handled>
<constant>true</constant>
</handled>
<log message="Failed after Retry.Sending ProcessTask Request to Error Queue" loggingLevel="ERROR" logName="WebServiceQueues" />
<to uri="switchyard://ErrorProcessTaskExQueue"/>
</onException>
</route>
</routes>
As fas as I remember, faults are not handled by default. In order to enable this a property must be set: handleFault="true". It can be set for the whole Camel context or for individual routes.
Example for a route in XML:
<route handleFault="true">
...
</route

Extracting the body from an ActiveMQ message via Camel

I have a route using the Spring DSL as such
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="activemq:queue:worker?mapJmsMessage=false" />
<convertBodyTo type="java.lang.String"/>
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<to uri="http://localhost/queue" />
</route>
</camelContext>
The message type is an ActiveMQTextMessage. I am able to POST the message to the HTTP URL, but what I get seems to be the toString() output:
ActiveMQTextMessage {commandId = 5, responseRequired = false, message....
I would like to call the getText() method on the ActiveMQTextMessage instance to populate the route, but I cannot figure out how to get that method called. I am quite sure I could get this to work in code, but I need to do everything via XML.
Figured out the problem. I had mapJmsMessage=false set to handle an exception a few days ago. I removed it and suddenly it worked fine.

rabbitMQ message forwarding from one queue to another

Could you please help me to resolve the problem I am facing?
When forwarding message from one queue to another ( no message seems to be published ) ,
steps:
timer publish current date to queue 'inbox'- this part working
from 'inbox' to 'outbox' - this is not working
from 'outbox' to print console
Follows the spring xml.
<route>
<camel:from
uri="rabbitmq://localhost:5672/outBox?sername=guest&password=guest" />
<camel:to uri="stream:out" />
</route>
<route>
<camel:from
uri="rabbitmq://localhost:5672/inbox?username=guest&password=guest" />
<camel:to
uri="rabbitmq://localhost:5672/outBox?username=guest&password=guest" />
</route>
<route>
<camel:from uri="timer:foo?period=10" />
<setBody>
<simple>${body}Message at ${date:now:yyyy-MM-dd HH:mm:ss}</simple>
</setBody>
<to
uri="rabbitmq://localhost:5672/inbox?username=guest&password=guest" />
</route>
According to http://camel.apache.org/rabbitmq.html the URI format is
rabbitmq://hostname[:port]/exchangeName?[options]
Thus inbox in your code is not queue name but exchange.
Use queue= option to specify the queue

Want to build a route which will check contents of Soap request and pass the request to appropriate URI

I am Ashish from Mumbai and very new to Apache Camel.
Currently I am building a route in XML which will scan the SOAP request and will redirect the request to appropriate URI.
My Soap request isn as follows:
<service xmlns="http://ws.madcomum.comprova.com">
<request>
<keysValues>
<item>
<bytesValue
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<dateValue
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<doubleValue
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<key>validatesOriginIntegrity</key>
<longValue
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<stringValue>z4x/FOOR+EPQ0vD9+itPSCBeNR4=</stringValue>
</item>
</keysValues>
<actionId>1</actionId>
<clientId>ARGO</clientId>
</request>
</service>
From this SOAP envelope, I want to parse out value of actionId tag using Camel Route.
If actionId has value of 1 then route must be redirected to callService else to another service.
I developed logic of route as folows:
<route>
<from uri="cxf:bean:comprovaWS?dataFormat=MESSAGE" />
<when>
<xpath>//actionId=1</xpath>
<to uri="log:input" />
<to ref="callService" />
<to uri="log:output" />
</when>
<otherwise>
<to uri="log:input" />
<to ref="otherService"/>
<to uri="log:output" />
</otherwise>
</choice>
</route>
But this logic is not working.
Is there any error in my route?
Though I am Java guy, I don't want to use Java here. I want to rely on Camel itself.
Please help me ASAP.
Regards,
Ashish
When you use xpath then 95% of the times when people have trouble its often due to namespaces. Your SOAP message is defined using a namespace - "http://ws.madcomum.comprova.com". The xpath expression must use this namespace to make it work.
See more details at: http://camel.apache.org/xpath, there is an example at the section Using XML configuration
Also as you use CXF in MESSAGE mode, then read about stream caching as the message is stream based: http://camel.apache.org/stream-caching.html

Resources