Camel not publishing to RabbitMQ queue - java

I have a simple route defined in a routeContext in Camel (this route will be used in multiple routes).
<route id="sendToRabbitQueue">
<from uri="direct:sendToQueue" />
<convertBodyTo type="java.lang.String"/>
<setHeader headerName="rabbitmq.ROUTING_KEY">
<constant>my.routing.key</constant>
</setHeader>
<to uri="ref:genericRabbitEndpoint"/>
</route>
And I have an endpoint (defined in an endpoints file)
<endpoint id="genericRabbitEndpoint" uri="rabbitmq://${rabbitmq.host}:${rabbitmq.port}/${rabbitmq.exchange.name}">
<camel:property key="autoDelete" value="false" />
<camel:property key="connectionFactory" value="#rabbitConnectionFactory" />
</endpoint>
Yes - I have seen the http://camel.apache.org/rabbitmq.html page - that's where I got the idea to set the header on the exchange. However no message is being published on the queue. I'm clearly overlooking something and any help would be appreciated.

So this seems like a bit of a gotcha and the answer relates to part of the route I didn't include in the question because I didn't think it was relevant.
The route starts at a RabbitMQ endpoint (not included above). As a result the exchange has some RabbitMQ headers set when it arrives:
rabbitmq.ROUTING_KEY
rabbitmq.EXCHANGE_NAME
rabbitmq.DELIVERY_TAG
These headers are used across the life of the route and appear to override the values when I try to publish at a different RabbitMQ endpoint. The way I've fixed is by introducing a bean which strips the headers out. Not ideal behaviour in my opinion...
public void stripRabbitHeaders(#Headers Map headers)
{
headers.remove("rabbitmq.ROUTING_KEY");
headers.remove("rabbitmq.DELIVERY_TAG");
headers.remove("rabbitmq.EXCHANGE_NAME");
}

Related

In a CXF based Camel route, unable to return the response body from a remote service after post-processing

What i'm trying to do is create a proof-of-concept Camel route, that exposes a cxfrs service endpoint. Requests to this endpoint are routed to another service on a different server using cxf client. After i get the xml response, i need to do some stuff with it, lets say save the response body to a DB for example. And of course the original requestor needs to receive the response as well.
If i don't do any post-processing of the response, then i get the response xml in the browser as expected. But any time i try to add another step to my route for processing the response, the browser gets a response that is empty. As you can see in the commented out lines, it doesn't matter which camel component i use the call the bean. I tried bean, process, and to. Even if i comment out all the code from the bean so it does nothing, the result is the same.
Here's my route:
<cxf:rsServer address="{{base.url}}/employeeservicecxf" id="restServiceCxf">
<cxf:serviceBeans>
<bean class="com.kf.camel.sample.EmployeeServiceResource"/>
</cxf:serviceBeans>
</cxf:rsServer>
<cxf:rsClient
address="http://{{remote.server}}/adminrest/jaxrs/projects/10475/products"
id="rsClient" loggingFeatureEnabled="true" />
<bean class="com.kf.camel.sample.CamelProcessor" id="processor"/>
<bean class="com.kf.camel.sample.CamelResponseProcessor" id="responseProcessor"/>
<camelContext id="_camelContext1" trace="true" xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="app.properties"/>
<route id="_route1">
<from id="_from1" uri="cxfrs://bean://restServiceCxf"/>
<process id="_process1" ref="processor"/>
<setHeader headerName="CamelHttpMethod" id="_setHeader1">
<constant>GET</constant>
</setHeader>
<to id="_to1" uri="cxfrs://bean://rsClient"/>
<!-- to id="_to3" uri="bean://com.kf.camel.sample.CamelResponseProcessor?method=process"/-->
<bean id="_bean1" ref="responseProcessor" method="process"/>
<!-- process id="_process2" ref="responseProcessor"/-->
</route>
</camelContext>
</beans>
Response Headers
Response Body with content length mismatch error
Have you tried to enable stream caching?
Sounds like any first operation you do on the response is consuming the stream and any further attempt to read the stream again gets an empty result.
When you want to read a stream multiple times in Camel you have to enable stream caching.

Camel CXF REST: Setup then poll

The problem is simple but the implementation seems elusive. I want to send only once a few setup POSTs to a REST server and then begin polling every 5 seconds with GETs right afterward the POSTs was successful. What would the implementation for this look like in Camel Spring XML using the Camel CXFRS component? I don't want to write new code or a camel endpoint and would like to do this with the existing camel tools.
You could try something like below. For details on camel components refer to Apache camel documentation
<camelContext xmlns="http://camel.apache.org/schema/spring"
<route id="abc" shutdownRoute="Default" streamCache="true">
<from uri="timer://foo?fixedRate=true&period=100000" />
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
--setheader for Content-Type
<recipientList>
<simple>https4://post url</simple>
</recipientList>
<log message="After Transmission " loggingLevel="DEBUG"
logName="com.domain" />
<recipientList>
<simple>https4://get url</simple>
</recipientList>
--unmarshall
</route>
</camelContext>

Using controlBus from spring DSL with parameters

I need to control my routes and I am using spring DSL for Camel.
I need to exposed a service which will perform thoses actions to the routeId given in paramaters.
The following code does not work (the body contain the routeId)
<route id="stopRoute">
<from uri="direct:stopRoute"/>
<log message="about to stop a route"/>
<to uri="controlbus:route?routeId=${body}&action=stop"/>
<to uri="controlbus:route?routeId=${body}&action=status"/>
</route>
I also tried with simple language but I can't figure out the correct syntax
See this FAQ
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
Use <toD> to make the to dynamic.

Apache Camel WebService consumer

I have created a route
cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9003/ws"
serviceClass="pl.test.ws.testImpl"
wsdlURL="/META-INF/wsdl/test.wsdl"
endpointName="s:testSoap"
serviceName="s:testService"
xmlns:s = "https://test.pl/wsdl"/>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:sendToTest" />
<to uri="cxf:bean:testEndpoint" />
</route>
</camelContext>
How can i call this webservice by putting object in the direct:sendToTest route?
I would like to be able to make a soap request some criteria will be met however I do not knew how can I put from java class message on the route.
can anyone give me a hint?
You can use a ProducerTemplate to send message to any Camel endpoint from Java code.
A little example from the getting started guide
http://camel.apache.org/walk-through-an-example.html
And to get more familiar with Apache Camel I recommend people to read this article
http://java.dzone.com/articles/open-source-integration-apache

camel generic producer (to be routed via spring xml config)

I want to send a generic message from from java, that is then routed by camel. So far the messages always went to an activemq topic (Example 1) but in future I want to be able to change the route (i.e. sending the message to a rest webservice instead) without modifing the source code (via spring xml configuration). So I expect to do ~something like~ Example 2. How would I do this?
Example 1: (how it's done so far)
#EndpointInject(uri="activemq:topic:IMPORTANTEVENTS")
ProducerTemplate producer;
producer.sendBody("Hello world!");
Example 2: (how it is supposed to look like - more or less)
#EndpointINject(uri="myevents")
... (as above)
XML config:
<route id="SysoutRoute">
<from uri="myevents"/>
<to uri="activemq:topic:IMPORTANTEVENTSS"/>
</route>
You can use property placeholders: http://camel.apache.org/using-propertyplaceholder.html - then the java source code do not need to be changed, but the uri is defined in a .properties file which you can then easily change
Ok got it working. It es actually quite easy by using direct: component(http://camel.apache.org/direct.html)
#EndpointInject(uri="direct:outMessage")
ProducerTemplate producer;
Now I can send messages:
producer.sendBody("Hello world!");
And route them via Spring xml config e.g. like this:
<route id="outMessage">
<from uri="direct:outMessage"/>
<to uri="stream:out"/>
<to uri="activemq:topic:IMPORTANTEVENTS"/>
<to uri="restlet:http://localhost:8888/status/?restletMethod=post"/>
</route>

Categories

Resources