In this article we see an example of Mule async block where we want a set of message processors to be processed asynchronously in a separate thread.
Mule Async Block
The message passed to an inbound endpoint is then passed on to a async
block which contains a set of message processors. These message processors within the <async>
block are processed in a separate thread.
muleContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:test="http://www.mulesoft.org/schema/mule/test" xsi:schemaLocation=" http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/test http://www.mulesoft.org/schema/mule/test/current/mule-test.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.8/mule-vm.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.8/mule.xsd "> <flow name="async-block-flow"> <vm:inbound-endpoint path="in" exchange-pattern="request-response" /> <async> <custom-processor class="com.javarticles.mule.PrintThreadName"> <spring:property name="tag" value="asyncBlock.1"/> </custom-processor> <custom-processor class="com.javarticles.mule.PrintThreadName"> <spring:property name="tag" value="asyncBlock.2"/> </custom-processor> <vm:outbound-endpoint path="async-out" /> </async> <custom-processor class="com.javarticles.mule.PrintThreadName"> <spring:property name="tag" value="sync-flow"/> </custom-processor> <vm:outbound-endpoint path="sync-out" /> </flow> </mule>
The message processor used within the async
block simply prints the thread name and also adds the thread to an outbound property which we will retrieve from the outbound endpoint.
PrintThreadName:
package com.javarticles.mule; import org.mule.api.MuleEvent; import org.mule.api.MuleException; import org.mule.api.processor.MessageProcessor; public class PrintThreadName implements MessageProcessor { private String tag; public String getTag() { return tag; } public void setTag(String tag) { this.tag = tag; } public MuleEvent process(MuleEvent event) throws MuleException { String threadDetails = getTag() + ": "+ Thread.currentThread().getName(); System.out.println(threadDetails); event.getMessage().setOutboundProperty("thread-name", Thread.currentThread().getName()); return event; } }
Mule async example
Let’s trigger the flow by sending a message to the inbound endpoint vm://in
.
MuleAsyncExample:
package com.javarticles.mule; import org.mule.api.MuleContext; import org.mule.api.MuleMessage; import org.mule.api.context.MuleContextBuilder; import org.mule.api.context.MuleContextFactory; import org.mule.config.DefaultMuleConfiguration; import org.mule.config.spring.SpringXmlConfigurationBuilder; import org.mule.context.DefaultMuleContextBuilder; import org.mule.context.DefaultMuleContextFactory; import org.mule.module.client.MuleClient; public class MuleAsyncExample { public static void main(String[] args) throws Exception { DefaultMuleConfiguration dmc = new DefaultMuleConfiguration(); dmc.setId("muleexample"); dmc.setWorkingDirectory("/esb/mule"); SpringXmlConfigurationBuilder configBuilder = new SpringXmlConfigurationBuilder( "muleContext.xml"); MuleContextBuilder contextBuilder = new DefaultMuleContextBuilder(); contextBuilder.setMuleConfiguration(dmc); MuleContextFactory contextFactory = new DefaultMuleContextFactory(); MuleContext ctx = contextFactory.createMuleContext(configBuilder, contextBuilder); ctx.start(); try { MuleClient muleClient = new MuleClient(ctx); String endpointUri = "vm://in"; System.out.println("send message to " + endpointUri); MuleMessage response = muleClient.send(endpointUri, "Hello", null); System.out.println("Response: " + response.getPayloadAsString()); MuleMessage asyncOutMsg = muleClient.request("vm://async-out", 4000); System.out.println("Async block's thread name: " + asyncOutMsg.getInboundProperty("thread-name")); MuleMessage syncOutMsg = muleClient.request("vm://sync-out", 4000); System.out.println("Main flow's thread name: " + syncOutMsg.getInboundProperty("thread-name")); } finally { ctx.dispose(); } } }
As you can see from the output the message processors within the async
block gets called asynchronously in a separate thread async-block-flow.1.02 whereas the message processors in the main flow are invoked in the main thread itself.
Output:
send message to vm://in sync-flow: main asyncBlock.1: async-block-flow.1.02 asyncBlock.2: async-block-flow.1.02 Response: Hello Async block's thread name: async-block-flow.1.02 Main flow's thread name: main
Download the source code
This was an example about Mule’s async block.