I am sending a xml from a seda queue to a JMS queue. I have some metadeta in exchange's header which I want to pass to the JMS queue.
Do I have to explicitly get the metadata from exchange object's header, Then set it to the xml? Or Is there anyway if Camel can do it out of the box?
"set it to the XML"? Camel will place the headers as camel exchange headers that will be converted automatically to JMS properties. There should be no XML involved. If you need the headers to be placed in the XML body, you need to do this manually.
Related
I need to send json using rabbit mq web
I have the following structure of email json, you can see on photo. I listen queue using org.springframework.amqp.rabbit.annotation.RabbitListener;
and have the follwing exception - No method found for class java.util.LinkedHashMap
is there any way to deal with it?
I managed to manually send a message by defining a __TypeId__ header, with value corresponding to the class that represents your message payload:
__TypeId__ = your.message.class
Note that the value has to be your class' canonical name, including its package path.
When you don't specify this header, Spring tries to desserialize your payload string to a LinkedHashMap by default.
We have a simple camel route "from->to":
<from uri="cxf:bean:testServiceProvider?loggingFeatureEnabled=true" />
<to uri="cxf:bean:testServiceClient?loggingFeatureEnabled=true" />
This route acts like a router or proxy for a third party's web service:
Clients use it as endpoint.
Adds WSS headers to Soap message.
Route requests to real endpoint.
Service and client in this proxy are created with cxf beans.
The endpoint's web service seems to require Content-Length HTTP header, but cxf requests to endpoint does not contain this header by default. All the requests done by this proxy receive the same response:
HTTP response '411: Length required' when communicating with https://host:port/testService
We tried to add this header with an OutInterceptor, adding it to PROTOCOL_HEADERS:
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
headers.put("Content-Length", Collections.singletonList(String.valueOf(messageLength)));
Two questions:
How to know the value of messageLength?
Is there an easier way to do this?
Thanks!
You can try with http:conduit, disabling AllowChunking. This will force cxf to include Content-Length header in the request. By default cxf behaviour is to allow chunking, so it can be generating the problem you're facing, even specifying the Content-length header.
<http:conduit name="{http://namespace}WebService.http-conduit">
<http:client AllowChunking="false" CacheControl="No-Cache"
ContentType="text/xml;charset=UTF-8" ConnectionTimeout="900000"
ReceiveTimeout="900000" Connection="Keep-Alive" />
</http:conduit>
Looking at the CXF documentation you may be able to use the relayHeaders functionality to propogate headers from the "from" endpoint to the "to" endpoint.
CXF Bean Docs
Alternatively you could copy the value of the content-length from the inbound message as suggested here...
"If you want to keep those headers in the old version of camel, you need
to put the headers into a map and put this map into message header with
the key "org.apache.cxf.message.PROTOCOL_HEADERS"."
Copy headers
Following on from this question Messages DO NOT appear in the Spring Integration (Kafka) ErrorChannel when Broker is unavailable
I now have it working nicely and the spring integration Kafka default ErrorChannel is being called when there is an error state, with the associated ErrorMessage. My problem now, is that I need to determine the Topic of the message and there is no way to do this, other than including it in the Message Header.
What is the best approach for doing this - shall I create a special errorChannel that is associated with one and only one Topic?
The payload.failedMessage property of the error message is the original message that arrived at the adapter.
You could use a <header-enricher /> upstream of the adapter, to set header kafka_topic to the topic. That is the default mechanism used if no topic or topic-expression is configured on the adapter.
I'm working with a Camel application that is taking messages from one JMS queue and writing them to another JMS queue.
The output messages are JMS TextMessages which are not quite preferred for this particular JMS broker. I've determined for this product, and for the downstream (non-JMS) consumers, we'd like Camel to produce javax.jms.BytesMessages, but populate their data as a string via Message.writeUTF(String).
I have found that the Spring JMSConfiguration does allow me to set a property jmsMessageType="Bytes" which gets me halfway there, but is there any other configuration to make it write my String payload via writeUTF? Currently it appears to be encoding the string down to a byte array then setting it via BytesMessage.writeBytes(byte[]).
See the documentation how to use a custom message converter
http://camel.apache.org/jms
Then you can do the mapping to JMS Message yourself and use the writeUTF method
I have a rabbitmq listener as a separate class and JSF 2 managed bean.
In my bean I send a message and need to wait for result. I can't use sendAndReceive... because I send the message to one queue but receive from another queue, so I assign correlationId before sending.
So I need to wait asynchronously, I need to wait until right message comes to the listener. How to do it in rmq?
Looking at javadoc and source of RabbitTemplate it seems that he waits for response in reply queue. Do you set 'reply-to' property in your messages? If yes, then RabbitTemplate sendAndReceive methods should wait for response in 'reply-to' queue. Be sure to populate replyTo field correctly and test it.
Side note:
In RabbitMQ you do not send messages to the queue.
You send messages to the exchanges. Exchanges are routing messages to the queue(s) using bindings. With default or direct exchange type it looks like you send directly to the queue, but this is over-simplification.
See https://www.rabbitmq.com/tutorials/amqp-concepts.html for details.
Edit:
It seems there are some fix for that in AMQP 1.4.5.RELEASE
https://spring.io/blog/2015/05/08/spring-amqp-1-4-5-release-and-1-5-0-m1-available
Configurable Exchange/Routing Key for Replies
Previously, when using request/reply messaging with the
RabbitTemplate, replies were routed to the default exchange and routed
with the queue name. It is now possible to supply a reply-address with
the form exchange/routingKey to route using a specific exchange and
routing key.