hotmeatballsoup
hotmeatballsoup

Reputation: 625

Getting Apache Camel to conditionally inject headers on the onException route

Java 8/Camel 2.19.x here. I have the following route 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:spring="http://camel.apache.org/schema/spring"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring-2.0.0.xsd"
>
    <routeContext id="myRoute" xmlns="http://camel.apache.org/schema/spring">

        <route id="doStuff">
            <from uri="activemq:input"/>

            <onException useOriginalMessage="true">
                <exception>java.lang.Exception</exception>
                <redeliveryPolicy logStackTrace="true"/>
                <handled>
                    <constant>true</constant>
                </handled>

                <log message="${exception.stacktrace}" loggingLevel="ERROR"/>

                <!-- we get the original XML message - convert it to an object -->
                <unmarshal ref="xstream"/>

                <wireTap uri="bean:errorProcessor" copy="true"/>

                <rollback markRollbackOnly="true"/>
            </onException>

            <transacted ref="shared"/>
            <doTry>
                <unmarshal ref="xstream"/>
                <to uri="bean:thingProcessor"/>
        <marshal ref="xstream"/>
                <to uri="activemq:output"/>
            </doTry>
        </route>
    </routeContext>
</beans>

So, pretty simple:

  1. On happy path, consume from the input queue on AMQ, deserialize it (via XStream) into a Java object, send it to the thingProcessor, and place the result of that processor on the output queue.
  2. If an exception occurs, say the thingProcessor throws a RuntimeException, we log the exception stacktrace to the app logs, then we convert the original XML (that we consumed off the input queue), deserialize it into a POJO, and send it to the errorProcessor for handling. Finally we rollback the JMS transaction.

There will be times when the CamelFilePath header will be present on the message at the time of failure, and I'd like the errorProcessor to accept this and perform special logic if the header is present.

Currently my errorProcessor looks like:

@Component("errorProcessor")
public class ErrorProcessor {

    private static final Logger log = LoggerFactory.getLogger(ErrorProcessor.class);

    private final ErrorHelper errorHelper;

    public ErrorProcessor(final ErrorHelper errorHelper) {
        this.errorHelper = errorHelper;
    }

    public void handleErrors(
            final Fizzbuzz fizzbuzz,
            @Header("CamelFilePath") final String camelFilePath,
            @ExchangeProperty(Exchange.EXCEPTION_CAUGHT) final Exception exception) {

        // If camelFilePath is non-null and non-empty, do stuff with it here.

    }
}

Above, the fizzbuzz is the original (deserialized) XML/POJO that was consumed off the input queue.

My question

Sometimes the CamelFilePath header will be present on the message/exchange, and sometimes it won't be. How can I tweak my route so that if it exists on the "happy path" route, it will be copied over and present on the "error" route (that is, from inside the <onException> definition) as well?

Thanks in advance!

Upvotes: 2

Views: 1451

Answers (1)

Anatoly Utkin
Anatoly Utkin

Reputation: 112

You may use choice and simple clause in your route.
I just know on java dsl, but to xml convert simply

.choice().when().simple("${header.CamelFilePath} != null && ${header.CamelFilePath} not contains ''").wireTap("bean:errorProcessor");


On xml it would be something like that:

<choice>
 <when>
  <simple>
    ${header.CamelFilePath} != null &amp;&amp; ${header.CamelFilePath} not contains ''
  </simple>
  <wireTap uri="bean:errorProcessor" copy="true"/>
 </when>

Upvotes: 1

Related Questions