Mule async block example

0

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>

Mule Async Block

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.

You can download the source code here: muleAsyncExample.zip

About Author

Ram’s expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring.
You can reach him at [email protected]

Comments are closed.