Mule Tutorial Series: Using Mule’s Fork and Join Component

So far the HTTP endpoint demonstrated in this tutorial series had inbound HTTP endpoints. The HTTP endpoint also supports outbound endpoint. This example illustrates two functionalities one displays use of HTTP endpoint as outbound endpoint and second demonstrates the ‘fork and join’ flow control.

The Mule flow for this example is shown below:

Flow Component Fork N Join Image 1
Flow Component Fork N Join Image 1
Flow Component Fork N Join Image 2
Flow Component Fork N Join Image 2

The starting point of this Mule flow the HTTP endpoint is configured as below in the General tab: Exchange-patterns – Request-response

Host – localhost
Port – 8090
Path – fnjp
MIME type – text/xml

The next component Body to Parameter Map converts the HTTP request and query parameters into Map. The Map serves as input to the next endpoint which is an outbound HTTP endpoint. This endpoint’s configuration is as below for general tab:

Exchange-patterns – Request-response
Host – api.geonames.org
Port – 80
Path – postalCodeSearch?placename=#[payload.placename]&maxRows=40&username=
Method – GET

The geonames.org site provides free public RESTful web services API to obtain information such as postalcodes, geocoding, country, country code etc. For our demonstration purposes, the example uses its postalcodesearch API. The <userid> is a free user registered on the geonames site. Alternatively the developer can use the user named demo. However ‘demo’ user is configured with a daily limit, hence it is advisable to create your own user.

To understand the information gathered hit the site using the following URL:

<geonames>
	<totalResultsCount>2939</totalResultsCount>
	<code>
		<postalcode>15301</postalcode>
		<name>Washington</name>
		<countryCode>US</countryCode>
		<lat>40.17169</lat>
		<lng>-80.25596</lng>
		<adminCode1>PA</adminCode1>
		<adminName1>Pennsylvania</adminName1>
		<adminCode2>125</adminCode2>
		<adminName2>Washington</adminName2>
		<adminCode3/>
		<adminName3/>
	</code>
	<code>
		<postalcode>52353</postalcode>
		<name>Washington</name>
		<countryCode>US</countryCode>
		<lat>41.30145</lat>
		<lng>-91.69867</lng>
		<adminCode1>IA</adminCode1>
		<adminName1>Iowa</adminName1>
		<adminCode2>183</adminCode2>
		<adminName2>Washington</adminName2>
		<adminCode3/>
		<adminName3/>
	</code>
	<!—Limited results to two records-->
</geonames>

The next area of flow is displayed below:

Splitter Aggregator Flow
Splitter Aggregator Flow

The first component Object to String component converts the response XML into a string. The component following is Splitter. The configuration of splitter is shown below.

Tab – General
Expression – #[xpath(‘//geonames/code/name’)]

The expression essentially retrieves the name values for each code element retrieved in the response. The next component is Java.

Tab – General
Class Name – com.vinraj.integration.forknjoin.DOMTranslator

The source code of DOMTranslator is as below:

package com.vinraj.integration.forknjoin;

import java.util.Collection;
import org.dom4j.tree.DefaultElement;

public class DOMTranslator {
	
	public String processElement(DefaultElement element) {
		if (element == null) {
			return "<Name/>";
		} else {
			String val = element.asXML();
			return val;
		}
	}
	
	public String processElements(Collection<String> names) {
		StringBuffer sb = new StringBuffer();
		sb.append("<Names>\n");
		for (String name : names) {
			sb.append(name);
			sb.append("\n");
		}
		sb.append("</Names>\n");
		return sb.toString();
	}
}

The processElement method is relevant for this aspect of our demonstration. The Splitter returns the XML element matching the Splitter expression. The value of the element (i.e. place name) is passed on to the Collection Aggregator component. The aggregator collects the individual place name in a collection object.

The aggregator output (i.e. Collection of Strings) is passed to the java component configured as below:

Tab – General
Class Name – com.vinraj.integration.forknjoin.DOMTranslator

The processElements method accepts collection of strings and programmatically converts them into a response XML.
To test the flow type in the following URL in browser window

http://localhost:8090/fnjp?placename=york

The output generated is shown below:

<Names>
	<name>New York City</name>
	<name>New York City</name>
	<name>New York City</name>
	<name>York</name>
	<name>New York City</name>
	<name>New York City</name>
	<!—The results have been trimmed -->
</Names>

The source code of Mule flow is as below:

<mule>
    <flow name="http_flowcontrol_propforknjoinFlow1" doc:name="http_flowcontrol_propforknjoinFlow1">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8090" path="fnjp" 
        	 doc:name="HTTP" mimeType="text/xml"/>
        <http:body-to-parameter-map-transformer doc:name="Body to Parameter Map"/>
        <response>
            <component class="com.vinraj.integration.forknjoin.DOMTranslator" doc:name="Java"/>
        </response>
        <response>
            <object-to-string-transformer doc:name="Object to String"/>
            <splitter expression="#[xpath('//geonames/code/name')]" doc:name="Splitter"/>
            <component class="com.vinraj.integration.forknjoin.DOMTranslator" doc:name="Java"/>
            <collection-aggregator failOnTimeout="true" doc:name="Collection Aggregator"/>
        </response>
        <http:outbound-endpoint exchange-pattern="request-response" host="api.geonames.org" 
        	port="80" path="postalCodeSearch?placename=#[payload.placename]&amp;maxRows=40&amp;username=###" 
method="GET" doc:name="HTTP" contentType="text/xml"/>
    </flow>
</mule>

Note: the XML namespaces added within the mule element tag has been removed for code legibility.

That’s all for 2014 folks. Writing this blog after a long time. Feels nice.

Advertisements

One thought on “Mule Tutorial Series: Using Mule’s Fork and Join Component

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s