Camel CXF consumer, webservice method has no response - cxf

I'm trying to consume a webservice from camel using the cxf component, like this:
<cxf:cxfEndpoint id="webservice"
address="http://webservice.url.com/webservice"
serviceClass="com.url.webservice.MyWebService"/>
<camel:camelContext>
<camel:route>
<camel:from uri="direct:a"/>
<camel:inOnly uri="cxf:bean:webservice?defaultOperationName=sendMessage"/>
</camel:route>
</camel:camelContext>
The sendMessage method has no response, hence the inOnly rather than to (although I have the same problem when I try to instead). The problem is that apparently camel still expects a response, and the route hangs while waiting for one. I suppose if I let it try long enough, it would eventually time out.
To be clear, I'm running a test method:
/* ... */
#Produce(uri = "direct:a")
protected ProducerTemplate directA;
#Test
public void sendMessage() throws Exception {
directA.sendBody(new String[] {"client id", "message"});
directB.sendBody(new String[] {"client id", "message 2"});
}
And I'm seeing the effect of the first call (that is, the message arrives at the server), but not the second, and the method doesn't finish running (again, I'm assuming it'll timeout at some point... if so, the timeout's pretty long: I ran the test as I started writing this, and it's still running).
Am I missing something? Is it a bug? Is it just bad practice to have webservice methods with no response?
By the way, when testing methods which have a response, it works fine.

I think Willem Jiang recently fixed some issue with one-way CXF in Camel recently. Maybe try Camel 2.6-SNAPSHOT from trunk.
I personally prefer two-way with web services, just returning some ACK back in case there is no data to return back. The client most often want some confirmation the server has received and acknowledged the data.

camel-cxf producer decides if it will handle the response message by checking if the operation is oneway. Even the sendMessage operation is oneway invocation, your server should send Http states 202 message to the client according the HTTP protocol, otherwise camel-cxf producer will still wait for the response.
BTW, I think the issue[1] that Claus said was related to async invocation of camel-cxf producer with one way message, not sure if it's the same issue as you mentioned(I didn't know which version of camel are you using).
[1]https://issues.apache.org/jira/browse/CAMEL-3426
Willem

Related

No endpoint could be found for - Camel Http Integration

I'm trying to run a simple test with Apache Camel:
from("http://localhost:61554/api/v1/MyController/my-endpoint")
.to("direct:a")
.log("$({body}");
I'm getting the following error: "No endpoint could be found for: http://localhost:61554/api/v1/MyController/my-endpoint, please check your classpath contains the needed Camel component jar"
I'm very new to Camel and Java. Can someone please tell me why this error is coming up? Should I be using from("direct:x")... ? If, so where do I map my "direct" endpoints to concrete ones?
Thanks
You cannot use the http component as consumer (eg in from) - its a http client for calling HTTP servers (so its a producer, eg to).
Instead to have HTTP as consumer you can use camel-servlet, camel-jetty, camel-undertow, etc.

Produce messages to IBM MQ using REST API. Apache Camel

I have to send messages to IBM MQ by hitting a rest service. Below is the code I came up with, using Camel XML DSL.
<rest path="/basePath">
<post uri="/path" consumes="application/xml" produces="application/xml">
<to uri="ibmmq:QUEUE.NAME"/>
</post>
</rest>
When I try to post the message, I get the following exception
org.apache.camel.RuntimeExchangeException: Failed to resolve replyTo destination on the exchange
Is the post method expecting response back from QUEUE, so that it can respond back to rest client?
I only need the post service to reply with 200, if the message is successfully produced to QUEUE, 500 otherwise.
How to solve this problem?
Pattern of your exchange is InOut so this is default behavior for your jms producer. Try change it for specific endpoint like this:
<to uri="ibmmq:QUEUE.NAME" pattern="InOnly"/>

Camel netty4-http client handling of http 100-Continue

We are using netty4-http as a client and have a problem when the server side answers with a http 100-Continue.
I expected the client to handle that internally and continue the call but it's actually returning http 100.
The test org.apache.camel.component.netty4.http.NettyHttpClientExpectContinueTest in the Camel code seems to test exactly that situation but it's ignored with the comment "TODO Fix it, need to send the response back". So I guess it has been a plan to implement it.
I'm new too Netty I wondering if it's possible to handle that in the Netty pipeline by overriding the ClientInitializerFactory (I found out it's the HttpObjectAggregator that returns 100)?
So any help how do achieve that in the Netty pipeline or any tips how to achieve that in some other way is welcome.

Camel ProducerTemplate versus Spring JMSTemplate

I am using camel to send message to an IBM MQQueue.
The MDB listening to this queue expects messages of the type com.ibm.jms.JMSMapMessage.
When I use camel producerTemplate, an exception is thrown.
I am doing this
producerTemplate.sendBody("wmq:queue",hashMap);
Exception data: java.lang.ClassCastException: com.ibm.jms.JMSMapMessage incompatible with javax.jms.ObjectMessage
So I tried Spring jmsTemplate, and it worked.
jmsTemplate.send(new MessageCreator() {
#Override
public Message createMessage(Session session)
throws JMSException {
return session.createObjectMessage((Serializable) sctHmap);
}
});
Question:
The jms component documentation says
It uses Spring's JMS support for declarative transactions, including
Spring's JmsTemplate for sending and a MessageListenerContainer for
consuming.
I tried with disabling camels auto conversion using mapJmsMessage=false.
I realised it would not help as it would have sent a hash map, I still got the same exception. Is there any way I can get the producerTemplate to work in the same way as JMSTemplate? ProducerTemplate seems to be more elegant, atleast in terms of my unit tests
It seems I misinterpreted the classcast exception message. Camel was correctly sending, com.ibm.jms.JMSMapMessage, the MDB at the consumer application was expecting javax.jms.ObjectMessage.
I resolved it by setting jmsMessageType=object in the endpoint URI. :)

Camel execution handling based on http response code

I am using http4 component and multicasting the msg to multiple routes. Each route is calling a Rest service. Based on http response code I want to handle the exception. I am getting httpOperationFailedException for all 400,500 response code but for 404 case I want to continue the routing and for other cases the execution should stop. How can I achieve this?
Thanks.
You can use Camel's error handling
http://camel.apache.org/error-handling-in-camel.html
There is a bit of documentation there to read and understand. But then you can do onException where you then have onWhen where you can then use the http status code to determine what to do, such as continue, or handle and return a specific error message etc.

Resources