[mule-user] Asynchronous Request Response using Mule 3

18 views
Skip to first unread message

Emmanuel Becerra

unread,
Oct 8, 2010, 4:40:28 PM10/8/10
to us...@mule.codehaus.org
ok guys, I have managed to do the following configuration but I have not been able to make it work with Mule 3:

<jms:activemq-xa-connector name="xaConnector" maxRedelivery="2" brokerURL="tcp://localhost:61616">
<dispatcher-threading-profile doThreading="false" />
</jms:activemq-xa-connector>

<flow name="AsynchRequestHandler">
<inbound-endpoint address="http://localhost:8888/converter" exchange-pattern="one-way"/>
<cxf:jaxws-service serviceClass="com.delphi.sdt.transformers.Converter"/>
<component>
<singleton-object class="com.delphi.sdt.transformers.Converter" />
</component>
<multicasting-router>
<reply-to address="jms://reply.queue"/>
<jms:outbound-endpoint queue="service1" exchange-pattern="one-way"/>
<jms:outbound-endpoint queue="service2" exchange-pattern="one-way"/>
</multicasting-router>
<async-reply timeout="5000">
<collection-async-reply-router/>
<jms:inbound-endpoint queue="reply.queue" exchange-pattern="one-way"/>
</async-reply>
</flow>
Mule is complaining about the multicasting-router: Invalid content was found starting with element 'multicasting-router'

What am I doing wrong!? Any ideas??

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Daniel Feist

unread,
Oct 8, 2010, 5:15:04 PM10/8/10
to us...@mule.codehaus.org
We changed some of the element names for <flow>

Use <all> instead of <multicasting-router>. Also async-reply isn't supported in the same way it was with <service>, the current support is much more explicit and doesn't support the use of the ReplyTo property.

<request-reply timeout="5000">
<all>


<jms:outbound-endpoint queue="service1" exchange-pattern="one-way"/>
<jms:outbound-endpoint queue="service2" exchange-pattern="one-way"/>

</all>


<jms:inbound-endpoint queue="reply.queue" exchange-pattern="one-way"/>

</request-reply>

If you need the replyTo address property set you can add this with a message property transformer.

Does this help?

Dan

Emmanuel Becerra

unread,
Oct 8, 2010, 6:02:27 PM10/8/10
to us...@mule.codehaus.org
Thanks Daniel, it seems to work!

Basically what I'm trying to do is create a webservice that invokes a mule service, and then have mule publish the message (Using ActiveMQ) to other two mule services and have them perform some logic on the message (Asynchronously) and then use the response from the two services to generate one final response to the user. I just got stuck on the first part.

I will continue with my example and I'm sure I will have more questions.

Thanks again for your help!

Emmanuel Becerra

unread,
Oct 11, 2010, 11:47:45 AM10/11/10
to us...@mule.codehaus.org
OK, I managed to do most of what I want to accomplish.

I can receive a message by a Web Service, send it to two different queues.
I have some other services transform the data.
I placed a component in the middle to do more fancy stuff.
I can put one final response into my reply.queue.
The response queue is processed (I checked on ActiveMQ).

The problem I have is that the response is not sent back to the HTTP requester :S I'm sure I'm missing something very simple but I'm not sure what it is... here is my configuration:

<flow name="AsynchRequestHandler">
<inbound-endpoint address="http://localhost:8888/converter"
exchange-pattern="one-way" />

<cxf:jaxws-service serviceClass="com.components.Converter" />

<request-reply timeout="10000">


<all>
<jms:outbound-endpoint queue="service1"
exchange-pattern="one-way" />
<jms:outbound-endpoint queue="service2"
exchange-pattern="one-way" />
</all>
<jms:inbound-endpoint queue="reply.queue"
exchange-pattern="one-way" />
</request-reply>

</flow>

I'm guessing that I need to put an endpoint(to HTTP??) inside the request-reply section after I read the reply.queue because I see that the reply IS being read. Am I correct? How do I do that?

Thanks!

Andrew Perepelytsya

unread,
Oct 11, 2010, 11:53:29 AM10/11/10
to us...@mule.codehaus.org


On Mon, Oct 11, 2010 at 11:47 AM, Emmanuel Becerra <mule.us...@mulesource.com> wrote:
<inbound-endpoint address="http://localhost:8888/converter"
                       exchange-pattern="one-way" />

Shouldn't this be the request-response exchange pattern if you want the reply be sent back to the caller?

Andrew

Emmanuel Becerra

unread,
Oct 11, 2010, 12:58:21 PM10/11/10
to us...@mule.codehaus.org
Well, I tried putting that and it didn't work, from my Website (.NET) application I get the following exception:

Response timed out (10000ms) waiting for message response id "ac28f0d6-18ac-42b7-bee0-d99733517660" or this action was interrupted. Failed to route event via endpoint: null. Message payload is of type: String

thanks!

Emmanuel Becerra

unread,
Oct 11, 2010, 2:02:33 PM10/11/10
to us...@mule.codehaus.org
Reading through this example http://www.mulesoft.org/documentation/display/MULE3USER/Service+Messaging+Styles I noticed that they use a REPLY-TO address. I tried to do the same thing inside my ALL section, but Mule complains that it cannot be there. My question is, in order to be able to get the response from mule through HTTP, do I need to specify a reply-to address?? Once I get this example working I think I'm all set to start embracing Mule to its fullest.

Thanks!

Emmanuel Becerra

unread,
Oct 11, 2010, 2:05:23 PM10/11/10
to us...@mule.codehaus.org
Forgot to mention that I am looking at the last example on that website.

Emmanuel Becerra

unread,
Oct 11, 2010, 5:34:33 PM10/11/10
to us...@mule.codehaus.org
How can I set the message property transformer? I'm lost :(

Emmanuel Becerra

unread,
Oct 12, 2010, 12:37:59 PM10/12/10
to us...@mule.codehaus.org
Ok guys, I think I'm getting close, after reading some of the ActiveMQ documentation, I found out that in order to be able to use the same ID of the messages as reply, you need to set some configuration on the JMS connector (which I think is my problem). Look in the following address for the text *Returning the Original Message as a Reply*:

http://www.mulesoft.org/documentation/display/MULE3USER/JMS+Transport

which basically says to do the following configuration on the connector:

<jms:connector ...>
<spring:property name="disableTemporaryReplyToDestinations" value="true" />
<spring:property name="returnOriginalMessageAsReply" value="true" />
</jms:connector>

I tried doing that in my activemq connector but again, Mule complains that my configuration is wrong. Here is what I have:

<jms:activemq-xa-connector name="xaConnector"
maxRedelivery="2" brokerURL="tcp://localhost:61616">
<dispatcher-threading-profile doThreading="false" />

<spring:property name="disableTemporaryReplyToDestinations" value="true" />
<spring:property name="returnOriginalMessageAsReply" value="true" />
</jms:activemq-xa-connector>

Does anyone have any idea on how to configure my connector to return the original message as reply?

Thanks!

David Dossot

unread,
Oct 12, 2010, 12:52:54 PM10/12/10
to us...@mule.codehaus.org
Try with dispatcher-threading-profile below the spring:properties.

HTH
D.

Emmanuel Becerra

unread,
Oct 12, 2010, 2:06:23 PM10/12/10
to us...@mule.codehaus.org
Thanks, it seems like Mule doesn't complain anymore but I still have the same problem. The message is not being replied with the same ID.

I managed to look at the messages that get sent in activeMQ and I noticed that there are some important differences between them. The main one that I think is the problem is the MULE_CORRELATION_ID which one of the messages has it, and the reply doesn't!

I have attached some screenshots of the messages for you to see.

*Here is my complete configuration:*

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:script="http://www.mulesoft.org/schema/mule/scripting"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.0/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/3.0/mule-http.xsd
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/3.0/mule-cxf.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/3.0/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.0/mule-vm.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/3.0/mule-jms.xsd">

<jms:activemq-xa-connector name="xaConnector"
maxRedelivery="2" brokerURL="tcp://localhost:61616">

<spring:property name="disableTemporaryReplyToDestinations" value="true" />
<spring:property name="returnOriginalMessageAsReply" value="true" />

<dispatcher-threading-profile doThreading="false" />
</jms:activemq-xa-connector>

<custom-transformer name="StringToFloatTransformer"
class="com.myjavastuff.StringToFloatTransformer" />


<flow name="AsynchRequestHandler">


<inbound-endpoint address="http://localhost:8888/converter"

exchange-pattern="request-response" />
<cxf:jaxws-service serviceClass="com.myjavastuff.Converter" />

<request-reply timeout="20000">


<all>
<jms:outbound-endpoint queue="service1" exchange-pattern="one-way" />

</all>
<jms:inbound-endpoint queue="reply.queue"
exchange-pattern="one-way" />
</request-reply>
</flow>

<flow name="ProcessRequestHandler">
<jms:inbound-endpoint queue="service1"
transformer-refs="StringToFloatTransformer" />
<component>
<singleton-object class="com.myjavastuff.Converter" />
</component>
<jms:outbound-endpoint queue="reply.queue" exchange-pattern="one-way" />
</flow>
</mule>


*My Converter.java component is this one (doesn't really do anything special, I am calling the +celsiusToFarenheit+ method from my .NET application):*

package com.myjavastuff;
import javax.jws.WebService;

@WebService
public class Converter
{
public String celsiusToFarenheit ( String celsius )
{
try {
Thread.sleep(5000); //This was used to be able to see the messages in ActiveMQ before they get dequeued (I'm a newbie sorry).
} catch (InterruptedException e) {

}
return celsius + " Converted";
}

public float farenheitToCelsius ( Float farenheit )
{
return (farenheit - 32) * 5 / 9;
}
}

*What I did in my .NET app, was to add a Service reference using this address: http://localhost:8888/converter?wsdl and then I did a very simple form like that when I click a button it does the following:*

protected void Button1_Click(object sender, EventArgs e)
{
ConverterService.ConverterClient converter = new ConverterService.ConverterClient();
String number = TextBox1.Text;
object mResults = converter.celsiusToFarenheit(number);
txtResult.Text = "" + mResults.ToString();

/*ServiceReference1.EchoClient mClient = new ServiceReference1.EchoClient();
String mCommand = TextBox1.Text;
object mResult = mClient.echoWorld(mCommand);
txtResult.Text = "" + mResult.ToString();*/
}

Does anyone see anything wrong in my configuration as to why I don't get a response from my Webservice call in my .NET application?

Thanks in advance for all your help!

response.JPG
request.JPG

Emmanuel Becerra

unread,
Oct 13, 2010, 10:43:41 AM10/13/10
to us...@mule.codehaus.org
OK so I managed to propagate the same mule message id using the following configuration that I found in another thread:

...


<all>
<jms:outbound-endpoint queue="service1" exchange-pattern="one-way">

*<message-properties-transformer>*
*<add-message-property key="MULE_CORRELATION_ID" value="#[mule:message.correlationId]"/>*
*</message-properties-transformer>*
</jms:outbound-endpoint>
</all>
...

then on my other flow on the outbound:


<jms:outbound-endpoint queue="reply.queue" exchange-pattern="one-way">

*<message-properties-transformer scope="outbound">*
*<add-message-property key="MULE_CORRELATION_ID" value="#[mule:message.correlationId]"/>*
*</message-properties-transformer>*
</jms:outbound-endpoint>

However it doesn't work haha, but I think I'm getting close. I think the message is replied correctly since I now get a different error in mule, actually an exception:

java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.cxf.databinding.AbstractWrapperHelper.createWrapperObject(AbstractWrapperHelper.java:99)
at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:103)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:74)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:89)
at org.mule.module.cxf.CxfInboundMessageProcessor.sendToDestination(CxfInboundMessageProcessor.java:277)
at org.mule.module.cxf.CxfInboundMessageProcessor.process(CxfInboundMessageProcessor.java:133)
at org.mule.module.cxf.config.FlowConfiguringMessageProcessor.process(FlowConfiguringMessageProcessor.java:50)
at org.mule.processor.builder.InterceptingChainCompositeMessageProcessor.process(InterceptingChainCompositeMessageProcessor.java:65)
at org.mule.construct.AbstractFlowConstruct$1$1.process(AbstractFlowConstruct.java:103)
at org.mule.processor.AbstractInterceptingMessageProcessor.processNext(AbstractInterceptingMessageProcessor.java:57)
at org.mule.processor.builder.InterceptingChainMessageProcessorBuilder$InterceptingMessageProcessorAdapter.process(InterceptingChainMessageProcessorBuilder.java:188)
at org.mule.processor.AbstractInterceptingMessageProcessor.processNext(AbstractInterceptingMessageProcessor.java:57)
at org.mule.processor.builder.InterceptingChainMessageProcessorBuilder$InterceptingMessageProcessorAdapter.process(InterceptingChainMessageProcessorBuilder.java:188)
at org.mule.processor.AbstractInterceptingMessageProcessor.processNext(AbstractInterceptingMessageProcessor.java:57)
at org.mule.processor.builder.InterceptingChainMessageProcessorBuilder$InterceptingMessageProcessorAdapter.process(InterceptingChainMessageProcessorBuilder.java:188)
at org.mule.processor.AbstractInterceptingMessageProcessor.processNext(AbstractInterceptingMessageProcessor.java:57)
at org.mule.processor.builder.InterceptingChainMessageProcessorBuilder$InterceptingMessageProcessorAdapter.process(InterceptingChainMessageProcessorBuilder.java:188)
at org.mule.processor.AbstractInterceptingMessageProcessor.processNext(AbstractInterceptingMessageProcessor.java:57)
at org.mule.processor.ExceptionHandlingMessageProcessor.process(ExceptionHandlingMessageProcessor.java:22)
at org.mule.processor.builder.InterceptingChainCompositeMessageProcessor.process(InterceptingChainCompositeMessageProcessor.java:65)
at org.mule.processor.builder.InterceptingChainMessageProcessorBuilder$InterceptingMessageProcessorAdapter.process(InterceptingChainMessageProcessorBuilder.java:185)
at org.mule.processor.builder.InterceptingChainCompositeMessageProcessor.process(InterceptingChainCompositeMessageProcessor.java:65)
at org.mule.transport.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:186)
at org.mule.transport.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:159)
at org.mule.transport.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:146)
at org.mule.transport.http.HttpMessageReceiver$HttpWorker.doRequest(HttpMessageReceiver.java:247)
at org.mule.transport.http.HttpMessageReceiver$HttpWorker.processRequest(HttpMessageReceiver.java:206)
at org.mule.transport.http.HttpMessageReceiver$HttpWorker.run(HttpMessageReceiver.java:164)
at org.mule.work.WorkerContext.run(WorkerContext.java:309)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Unknown Source)


What's the missing piece of the puzzle?

Any advice would be appreciated

Emmanuel Becerra

unread,
Oct 13, 2010, 11:50:22 AM10/13/10
to us...@mule.codehaus.org
OK I finally got it!!!

The problem was in my Java class that was exposed as the web service.... I had wrong types in there and that is why I was getting the exception!

So in general, what I've learned is that I DO have to set manually the Mule correlation ID in order to be able to get the same message as reply. I wonder if that is how it really has to be done or if I just made that up and it worked....

Anyway, thanks to those of you who did replied to my thread, I think I pretty much solved the last few questions I had by myself... :P

I hope this helps others who want to do the same thing.

If anyone has a better idea on how to do this please post it, I would love to see it!

Andrew Perepelytsya

unread,
Oct 13, 2010, 2:16:48 PM10/13/10
to us...@mule.codehaus.org

I think it was just a coincidence that it worked this way, but hey, whatever works ;)

Andrew

Reply all
Reply to author
Forward
0 new messages