This part of the puzzle is my nightmare, I have deployed ServiceMix, and 2 Java apps on 2 different tomcat instances :
First app :
http://localhost:8080/textmsgClient
Second app :
http://localhost:8181/textmsgServer
Now my two apps need to communicate, though I want that communication to go through ServiceMix, so I can do some logs and everything.
I've created a blueprint XML file in the ./deploy directory, but what routes should I put in them?
I can't do this :
<route>
<from uri="http://localhost:8080/textmsgClient"/>
<log message="Test log"/>
<to uri="http://localhost:8181/textmsgServer"/>
</route>
so what is the correct thing to do ?
by the way, my XML file looks like this :
<?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"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="file:camel/input"/>
<log message="Moving ${file:name} to the output directory"/>
<to uri="file:camel/output"/>
</route>
</camelContext>
</blueprint>
Take a look at the list of Camel Components. Not knowing what type of data you are sending between services, it is difficult to recommend which one to use. However, theres a component for pretty much every data type you can imagine, and even support to make your own!
Edit
An example might be:
<route>
<from uri="direct:textmsgClient"/>
<log message="Test log"/>
<to uri="direct:textmsgServer"/>
</route>
Related
I want to log the incoming SOAP in my beans setup but I don't know how to intercept the requested body.
I found out if I add ?dataFormat=MESSAGE to my CxfEndpoint it shows the xml input but messes up the dataFormat that provides the addBookTransformer.
<from uri="cxf:bean:CxfEndpoint?dataFormat=MESSAGE" />
This is my setup
<cxf:cxfEndpoint id="CxfEndpoint"
address="/host/addBook"
endpointName="a:addBookEndpoint"
serviceName="a:addBookService"
wsdlURL="wsdl/add-book.wsdl"
serviceClass="com.library.AddBookEndpoint"
xmlns:a="http://library.com"/>
<bean id="addBookTransformer" class="com.library.bookshelf.AddBookTransformer"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="addBook" streamCache="true">
<from uri="cxf:bean:CxfEndpoint" />
<process ref="addBookTransformer" />
<log message="${body}"/>
</route>
</camelContext>
Is there a way to itercept and log the incoming post request data?
You could do wiretap for this
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="addBook" streamCache="true">
<from uri="cxf:bean:CxfEndpoint" />
<process ref="addBookTransformer" />
<wireTap uri="direct:tap"/>
<to uri="mock:result"/>
<log message="${body}"/>
</route>
</camelContext>
A copy of the exchange is sent to direct:tap which you can read and process however you want.
For example we could just log the message like this. You could also add another processor.
<route id="wiretapped" streamCache="true">
<from uri="direct:tap" />
<log message="${body}"/>
</route>
Here is the documentation for this.
What you are looking for is a very well known requirement. The pattern that provides the solution is a Filter and exists as a concept in the very early versions of J2EE spec. Back in times when we (the dinosaurs) wrote servlets, you could add a Filter to your servlet that intercepts both, request before it gets to your servlet and response after it is generated by your servlet but before it is sent to the client-side. In your Filter, you can log info, redirect it to a different destination, deny it or do anything you like. The same concept remains intact. You need to define a filter for all or some of your end-points and in your filter do the logging. If you work with Spring boot here is the article that describes how to add Filters for end-points in Spring Boot: How to Define a Spring Boot Filter?
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://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">
<camelContext id="cbr-example-context" xmlns="http://camel.apache.org/schema/blueprint">
<route id="cbr-route">
<from id="_from1" uri="file:///d:/inxslt"/>
<transform.xslt from="_from1" to="_to3" xsltFile="src/main/java/com/xslt/converterXsl.xsl"/>
<to id="_to3" uri="file:///d:/outxslt"/>
</route>
</camelContext>
i want to use my converterXsl.xsl format class to transform xml which is in file:///d:/inxslt this path
i tried this further here not not working
try to use the following definition of the Camel route.
<camelContext id="_context1" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_route1">
<from id="_from1" uri="file:src/data?noop=true"/>
<to id="_to1" uri="xslt:file:src/xml2html.xsl"/>
<to id="_to2" uri="file:target/output"/>
</route>
</camelContext>
Please, adjust file paths to your needs. Especially, notice notation of XSLT component.
I hope it helps ;-)
A short question about Apache Camel.
I have the following scenario, where my server receives jms messages and then transform to csv file and then insert DB.
For this purpose i have 2 beans:
xml2csv
insertDB
I use routing like:
<route id="route1" errorHandlerRef="myErrorHandler">
<from uri="file://{someFolder1}}
?...
<to uri="bean:xml2csv" />
<log message="transformed to xml file" />
</route>
<route id="route2" errorHandlerRef="myErrorHandler">
<from uri="file://{{someFolder2}}
?...
<to uri="direct:csvOnboardingChannel" />
</route>
<route id="csvOnboarding" errorHandlerRef="myErrorHandler">
<from uri="direct:csvOnboardingChannel" />
<to uri="bean:insertDB" />
</route>
When "route" a file from-to, is it move like a message? or putting the question different, does Apache Camel take a file, wrap it as a message and route it to a bean or a component?
Do I understand it correct or am in a wrong directation.
Yes, your understanding is correct. Camel reads in the file's data and sends it as a message through the route to a bean. Might also be simpler as a single route, like so:
<route id="route1" errorHandlerRef="myErrorHandler">
<from uri="file://{someFolder1}}">
<to uri="bean:xml2csv" />
<to uri="bean:insertDB" />
</route>
I have a Camel route that dequeues a message off a queue, sends it to a bean for processing, then enqueues the message back onto a different queue.
I am trying to eliminate "duplicate messages" on the 2nd queue. Does Camel have any endpoints, processors, EIPs, etc. that I could configure to dedupe message en route, before they get sent to the 2nd queue?
Example:
<route id="myRoute">
<from uri="{{queue-1-uri}}" />
<to uri="bean:myBean?method=process" />
<!-- How to dedupe right here??? -->
<to uri="{{queue-2-uri}}" />
</route>
Update: perhaps something like this:
<route id="myRoute">
<from uri="{{queue-1-uri}}" />
<to uri="bean:myBean?method=process" />
<filter>
<method>what goes here???</method>
<to uri="{{queue-2-uri}}" />
</filter>
</route>
Per Ralf's suggestion, I could then reference a bean inside <method></method> that then used a cache to keep messages in memory.
Say this new bean was called FilterBean and it had a dedupe() method on it: how do I wire it up in the Spring XML, and what classes/interfaces does the bean need to implement to be called from inside the route?
I think you are looking for the Idempotent Consumer that Camel provides. There are different approaches depending on your needs like Memory, JDBC, Hazelcast... I am not really sure if it will work for you since you are using a bean after the consumer but it worth to give it a try. Simple example from Camel website is as follows:
<!-- repository for the idempotent consumer -->
<bean id="myRepo" class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:start"/>
<idempotentConsumer messageIdRepositoryRef="myRepo">
<!-- use the messageId header as key for identifying duplicate messages -->
<header>messageId</header>
<!-- if not a duplicate send it to this mock endpoint -->
<to uri="mock:result"/>
</idempotentConsumer>
</route>
</camelContext>
You can find more info here: Idempotent Consumer
I've got my route's autoStart set to false:
<route id="myRoute" autoStartup="false">
Everything I can find online about how to start it after that is for starting it in java and says to call startRoute("myRoute"); on the camelContext.. but I can't find anything about how to call that from within a route in Spring XML.
Here's my setup:
<route id="myRoute" autoStartup="false">
<from uri="ftp://remote/dir" />
<to uri="file:///local/dir" />
</route>
<route id="kickOff">
<from uri="timer://runOnce?repeatCount=1&delay=30000" />
<!-- START myRoute HERE -->
<to uri="bean:postProcessor?method=postProcess" />
</route>
My goal is to have the FTP get all the files on the FTP once, then stop that route. Currently it'll continue polling the FTP indefinitely. I tried adding a org.apache.camel.impl.LimitedPollingConsumerPollStrategy with a limit of 1 but that didn't seem to change anything.
See the controlbus eip / component where you can start routes:
http://camel.apache.org/controlbus.html
The code should be something alike:
<route id="kickOff">
<from uri="timer://runOnce?repeatCount=1&delay=30000" />
<to uri="controlbus:route?routeId=myRoute&action=start" />
<to uri="bean:postProcessor?method=postProcess" />
</route>