How to create a timer based camel polling route? - apache-camel

i created a route that is supposed to read from an OPC-UA endpoint. The read operation should be performed every second, based on a timer. Every example i found shows that the route can only have one from item. My route looks like this:
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route id="opctorest">
<from uri="timer://simpleTimer?period=1000"/>
<log message="Triggered Route: opctorest: Sensorreading body: ${body}"/>
<to uri="milo-client:tcp://0.0.0.0:4840/freeopcua/server?nodeId=2&namespaceUri=http://examples.freeopcua.github.io"/>
<convertBodyTo type="java.lang.String"/>
<to uri="stream:out"/>
</route>
</camelContext>
When i deploy the route, it gets called every second, but it writes to the endpoint, since the call is declared in a to element. How can i turn this into a read? I could not find a solution so far. Thanks!

Use the .enrich() to turn it into a read when you want to read in the middle of a route.
http://camel.apache.org/content-enricher.html
For your example something similar to (not tested):
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route id="opctorest">
<from uri="timer://simpleTimer?period=1000"/>
<log message="Triggered Route: opctorest: Sensorreading body: ${body}"/>
<enrich uri="milo-client:tcp://0.0.0.0:4840/freeopcua/server?nodeId=2&namespaceUri=http://examples.freeopcua.github.io"/>
<convertBodyTo type="java.lang.String"/>
<to uri="stream:out"/>
</route>
</camelContext>

Related

Camel blueprint <setHeader headerName="CamelHttpPath" id="_setHeader1"><el>${header.uriPattern}</el></setHeader> waiting for dependencies

I have the following Camel Context.
<camelContext id="_camuatomicservicecontext" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_camuatomicserviceroute1">
<from id="_from1" uri="direct-vm:camuatomicservice">
<description>accepts vm messages directly </description>
</from>
<log id="_log1" message="Camu Atomic Service body = ${body}, header= ${header.uriPattern}"/>
<!-- <to id="_to1" uri="restlet:protocol:localhost:8189/"/> -->
<setHeader headerName="api.key" id="_setHeader1">
<constant>replace later with properties api.key Does not matter for this poc</constant>
</setHeader>
<setHeader headerName="CamelHttpPath" id="_setOutHeader1">
<el>${header.uriPattern}</el>
</setHeader>
<to id="_to1" pattern="InOut" uri="netty4-http:http:localhost:8189/path"/>
<log id="_log2" message="CamuAtomicService Response body ${body}"/>
</route>
</camelContext>
From the documentation I expect the CamelHttpPath header to override the endpoint configuration "/path" such that calling Facade Services can pass the header.uriPattern in and dynamically change the resource they want to access. The bundle worked fine until I added the setHeader for CamelHttpPath and now getting "Waiting for dependencies." I assume I need to install a feature, but Simple EL in other bundles on that server work already so not sure what feature I need to install.
Instead of I used and it worked fine. The choice was farther down in the options.

How can I fail a camel-route when exec returns nonzero?

I'm processing files with a Camel route like this:
<route>
<from uri="file:inbox?delete=true"/>
<recipientList>
<simple>exec://process.sh?args=inbox/${file:name}</simple>
</recipientList>
<log message="processed ${file:name}: ${body.stdout} ${body.stderr}"/>
</route>
Now I'd like the route to fail when process.sh finishes with nonzero exit-code. I found ${headers.CamelExecExitValue} but don't really know what to do with it.
In the example above, the file should not get deleted when process.sh fails. In my actual use-case, the route consumes files from a JMS queue and I want the file to stay in the queue. I think this can be done with <transacted/> but need to know how to fail the route.
I found How to define exception to be thrown through ref in Apache Camel which in combination with CamelExecExitValue lets me abort this way:
<route>
<from uri="file:inbox?delete=true"/>
<to uri="exec://process.sh"/>
<choice>
<when>
<simple>
${headers.CamelExecExitValue} != 0
</simple>
<throwException exceptionType="java.lang.RuntimeException" message="failed importing ${file:name}: ${body.stdout} ${body.stderr}"/>
</when>
</choice>
<log message="processed ${file:name}"/>
</route>
A bit verbose for my taste but works fine.

Calling route after previous one finishes in camel context

I'm writing one camel application using blueprint.I have two routes which calls same class beans but for different case(Handled that in class based on route id).I want to start second route only when first route completes it's execution(sequentially instead of parallel).So is there any way to do the same.Following is my code-
<camelContext id="test"
xmlns="http://camel.apache.org/schema/blueprint">
<route id="1">
<from uri="timer"/>
<to uri="bean:test"/>
</route>
<route id="2">
<from uri="timer"/>
<to uri="bean:test"/>
</route>
</camelContext>
Thanks
Routes are started when camel context is bootstrapped. You're probably looking for the exchange to be routed to "route2" after it's been processed by "route1"
That sounds like the same route. You have a few options for reusing a bean while implementing different behavior. The easiest one IMO from where you are is using different methods:
class TestBean {
void test1(){}
void test2(){}
}
Then changing your route config:
<route id="1">
<from uri="timer"/>
<to uri="bean:test?method=test1"/>
<to uri="bean:test?method=test2"/>
</route>
Of course you can change to make these be different beans...

camel when/otherwise for activemq and seda

I have a route where I'd like to compute if "from" is activemq or something else. I found replaceFromWith, but it seems to be used for testing only. I tried using camel's choice when/otherwise to switch between "from activemq" and "from seda", but that errors out as invalid syntax. I'm looking for something that would do the following:
<route id="doPost">
<choice>
<when>
<groovy>exchange.getIn().getHeader("sometest") != null</groovy>
<from uri="activemq:doPost?..."/>
</when>
<otherwise>
<from uri="seda:doPost?....."/>
</otherwise>
</choice>
Thanks in advance, appreciate the help.
You cannot dynamically select a consumer based on the exchange, the exchange wont exist before consuming it using the <from .../> tag.
Instead, you can construct a route for each consumer, normalize the exchange you receive from different types of consumers, and forward them to a common route for processing.
<route id="activemqConsumerRoute">
<from uri="activemq:doPost?..."/>
<!-- normalize the exchange to be understandable by the next route -->
<to uri="direct:commonProcessingRoute" />
</route>
<route id="sedaConsumerRoute">
<from uri="seda:doPost?....."/>
<!-- normalize the exchange to be understandable by the next route -->
<to uri="direct:commonProcessingRoute" />
</route>
<route id="commonProccessingRoute">
<from uri="direct:commonProcessingRoute" />
<!-- whatever business logic you have -->
</route>

Apache camel: Multiple executions with onCompletion mode="BeforeConsumer"

Sorry for my english, I'll make my best effort for write this.
I have a xml file like this:
<routes>
<route id="id1">
<from uri="timer://foo?fixedRate=true&period=60s"/>
<onCompletion mode="BeforeConsumer">
<log message="finish"/>
</onCompletion>
<setBody>
<simple>Probando 1</simple>
</setBody>
<log message="working1"/>
<to uri="direct:test1"/>
</route>
<route id="id2">
<from uri="direct:test1"/>
<setBody>
<simple>Test2</simple>
</setBody>
<log message="working2"/>
<to uri="direct:test2"/>
</route>
<route id="id3">
<from uri="direct:test2"/>
<setBody>
<simple>Test3</simple>
</setBody>
<log message="working3"/>
</route>
</routes>
if remove mode="BeforeConsumer" from the first route i get one "finish" in the log, but if i use the xml with mode="BeforeConsumer" i get the message 3 times (one per each route). Is that the behavior expected?
I need that the onCompletion code runs one time but i need too the mode="BeforeConsumer"

Resources