Apache Camel - Quartz2 with mybatis using onConsume - apache-camel

My Camel:
<from uri="quartz2://processTimers?cron=5+*+*+*+*+*" />
<to uri="mybatis:selectProducts?statementType=SelectList&onConsume=consumeProduct"/>
<bean ref="productService" method="process" />
<to uri="mq:queue:my.queue"/>
When using a Quartz from, the selectProducts returns the expected results but the onConsume for some doesnt execute at the end, I suspect this is because its a "to" and not a "from" method.
Is there anyway to have a cron scheduled mybatis select with an onConsume?
Updated:
<from uri="mybatis:selectProducts?statementType=SelectList&onConsume=markProductAsExtracted&maxMessagesPerPoll={{MAX_RECORDS_PER_PROCESS}}&scheduler=quartz2&scheduler.cron=5+*+*+*+*+?"/>
<bean ref="productService" method="process" />
<to uri="mq:queue:my.queue"/>

Yes see the scheduled polling consumer: http://camel.apache.org/polling-consumer.html
You can specify on the mybatis endpoint that the scheduler is cron and then setup the cron value as well. See that doc for more details.
Also I wrote a little blog once: http://www.davsclaus.com/2013/08/apache-camel-212-even-easier-cron.html its about the file component but its the same for mybatis.

Related

Camel activemq component - TTL

I want old messages to be automatically removed from topic so I'm using the option timeToLive which is described in the Camel ActiveMQ component documentation. However, it only works with queue and not with topic. Any idea why?
For testing purposes I made this simple route:
<route>
<from uri="timer://foo?repeatCount=1"/>
<to uri="activemq:topic:test?timeToLive=10000"/>
</route>
Route sends message to my test topic with TTL=10seconds. I would expect that after 10 seconds message would disappear.
When I use queue instead everything works as expected ( <to uri="activemq:queue:test?timeToLive=10000"/> )

Using Circuit Breaker with camel -ThrottlingExceptionRoutePolicy

There is a route which is consuming messages from a jms queue and after doing some processing sending a request to unreliable web service(Which can be down at times).
So in case of service is down then i need to stop consuming from queue for some time. I tried to use ThrottlingExceptionRoutePolicy . It will stop route as per configuration but issue is for the current message which gets the error as message is getting moved to dead letter queue. I've gone through the code of ThrottlingExceptionRoutePolicy as per code this will be called after all error handling is done for route.
So i need to modify default error handling of camel to avoid putting message to DLQ for some specific cases. I tried to configure various error handlers provided by camel but in all cases camel is putting messages to DLQ.
Is there some configuration or i need to write custom error handler to achieve the same.
<camel:route id="someroute" routePolicyRef="throttlingExceptionRoutePolicy"
errorHandlerRef="myTransactionErrorHandlerErrorHandler">
<camel:from uri="activemq:inputQueue" />
<camel:transacted />
<camel:bean ref="afterQueueProcessor" />
<camel:setHeader headerName="CamelHttpMethod">
<camel:constant>POST</camel:constant>
</camel:setHeader>
<camel:setHeader headerName="Content-Type">
<camel:constant>application/xyz</camel:constant>
</camel:setHeader>
<camel:to
uri="http://localhost:8080/some-ws/newOrder?orderId=dd&productName=bb&quantity=1" />
</camel:route>
This questions is related to async communication

How to commit a MQ transaction in a camel route?

There is a camel route, which is transacted and exceptions are handled by a TransactionErrorHandler. The code looks something like this:
...
<bean
id="errorHandler"
class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
</bean>
...
<camelContext errorHandlerRef="errorHandler">
...
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<!-- do some exception handling -->
</onException>
<route>
<from uri="mq:queue://QMgr/Q?exchangePattern=InOut" />
<transacted />
<!-- some routing that throws an Exception -->
</route>
</camelContext>
It works and there is a commit for the transaction after the error has been handled: Transaction commit (0xfab75a3a) redelivered(true) for ..., but then the message is placed in the input queue again and the transaction starts from the beginning (endless loop).
We are using IBM MQ and I think this rollback is performed by MQ and not from the camel route. So the question is: Can I tell MQ that I handled the exception and that it should not rollback again?
IBM MQ is resending the message to the consumer by design. To have the broker stop after X number of tries, configure a 'backout threshold' and a 'blackout queue' for IBM MQ to move the messages out of the way after failed delivery attempts.

JBoss Fuse Camel Route Editor: How to write multicast doing request-response fanout calls, and aggregating all responses into one message sent on?

I'm using "Fuse Tooling Routes Editor" (aka "Fuse Integration Editor", aka "JBoss Fuse Tooling Apache Camel Editor"), described for example here. The version is "Nightly build version 8.0.0.v20150805-1820-H573-MASTER".
I'd like to create a Camel route having a multicast which aggregates the responses it receives from the components it sends a message to, and then forwards the aggregate to a single final receiver. This is certainly doable in Camel, as one of the parameters of a multicast, strategyRef, has the description:
Refers to an AggregationStrategy to be used to assemble the replies from the multicasts, into a single outgoing message from the Multicast. By default Camel will use the last reply as the outgoing message.
However, when I write the following set of routes in my camel-context.xml (which compiles and runs fine):
<route>
<from uri="direct:a"/>
<setExchangePattern pattern="InOut"/>
<multicast strategyRef="x">
<to uri="direct:b"/>
<to uri="direct:c"/>
</multicast>
<log message="This flow works!"/>
<to uri="mock:p"/>
</route>
<route>
<from uri="direct:b"/>
<to uri="mock:q"/>
</route>
<route>
<from uri="direct:c"/>
<to uri="mock:r"/>
</route>
and then click to go to the visual editor, it produces the following (incorrect) picture:
When I switch back to the XML editing, my routes are automatically changed to:
<route>
<from uri="direct:a"/>
<setExchangePattern pattern="InOut"/>
<log message="This flow works!"/>
<to uri="mock:p"/>
</route>
<route>
<from uri="direct:b"/>
<to uri="mock:q"/>
</route>
<route>
<from uri="direct:c"/>
<to uri="mock:r"/>
</route>
And on switching to the editor once again, I get the picture:
This seems like a bug in the editor, but perhaps I'm doing something wrong here?
Many thanks!
Edit:
We found that indeed this used to be an issue logged with the Fuse Camel editor, which however should have been fixed in version 7.1 of the tooling.
that seems to be a bug in the editor. Thank you for reporting it.
I reopened the original issue in Jira. You can track the progress there.
Lars

How I can create a camel globalObject?

I need a global Object for all routes, processes and Components. In this global Object I would save configuration parameters. But I don't know how and where I can set a global Object, and how I can read it in my own process and my own components.
I create the camel Context in Spring and have a RouteBuilder to build my routes.
Thank you
If you want to setup your route, then you may use PropertyPlaceholderConfigurer, see here:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
<route>
<from uri="activemq:${someQueueName}"/>
<to uri="mock:results"/>
</route>
</camelContext>
Alternatively, you may use ApplicationContextRegistry that allows you to look up beans in the Spring ApplicationContext. This implementation is automatically used when you’re using Camel in a Spring environment, see here. E.g., access the registry as follows:
String myValue = exchange.getContext().getRegistry().lookupByNameAndType("myKey", String.class);

Resources