Mule Message Inbound Outbound Scope

0

Mule supports four property scopes.

  1. Inbound
  2. Outbound
  3. Invocation
  4. Session

In this article we will discuss about inbound and outbound scopes. We start with a simple flow with one inbound endpoint. Message posted to inbound endpoint is then passed on to a java component that simply prints the inbound property injected thru the setter.

Inbound scoped property

muleContext.xml:

	<flow name="flow1">
		<vm:inbound-endpoint path="in" exchange-pattern="request-response" />
		<custom-transformer class="com.javarticles.mule.PrintInboundProperty">
			<spring:property name="property" value="inbound_property" />
		</custom-transformer>
	</flow>

Here is the java component.

PrintInboundProperty:

package com.javarticles.mule;

import org.mule.api.MuleMessage;
import org.mule.transformer.AbstractMessageTransformer;

public class PrintInboundProperty extends AbstractMessageTransformer {
    private String property;

    @Override
    public Object transformMessage(MuleMessage message, String encoding) {
        Object inboundProperty = message.getInboundProperty(property);
        System.out.println(getProperty() + ": "+ inboundProperty);
        return message;
    }

    public String getProperty() {
        return property;
    }

    public void setProperty(String property) {
        this.property = property;
    }
}

Let’s now start the flow by sending a message to the endpoint. We also set an outbound property called inbound_property. The outbound property set will be available as an inbound property within the flow.

MuleMessageExchangeExample:

package com.javarticles.mule;

import org.mule.DefaultMuleMessage;
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 MuleMessageExchangeExample {
    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);
            sendMsgAndVerifyProperties("vm://in", ctx, muleClient, "inbound_property");
        } finally {
            ctx.dispose();
        }
    }
    
    private static void sendMsgAndVerifyProperties(String endpointUri, MuleContext ctx,
            MuleClient muleClient, String...inboundProperties) throws Exception {
        System.out.println("send message to " + endpointUri);
        MuleMessage message = createOutboundMessage(ctx);
        MuleMessage response = muleClient.send(endpointUri, message);
        printInboundProperties(response, inboundProperties);        
    }
    
    private static void printInboundProperties(MuleMessage response,
            String...inboundProperties) throws Exception {
        System.out.println("Verify properties after response");
        System.out.println("Response: " + response.getPayloadAsString());
        for (String inboundProperty : inboundProperties) {
            System.out.println(inboundProperty + ": " + response.getInboundProperty(inboundProperty));
        }
    }

    private static MuleMessage createOutboundMessage(MuleContext ctx)
    {
        MuleMessage msg = new DefaultMuleMessage("XYZ", ctx);
        msg.setOutboundProperty("inbound_property", "ABC");
        return msg;
    }
}

We create a message, set its outbound property inbound_property to value ‘ABC’. We the post the message to the inbound endpoint vm://in, which in turn is passed on to the java component which simply prints the property available within the flow as an inbound property.

Output:

send message to vm://in
inbound_property: ABC
Verify properties after response
Response: XYZ
inbound_property: null

After analyzing the output, we can derive the below:

    1. Properties are added in outbound scope to the message. The message is sent to the inbound endpoint which in turn can access using the inbound scope
      Below is the code that adds properties in outbound scope.

      MuleMessage msg = new DefaultMuleMessage("XYZ", ctx);
      msg.setOutboundProperty("inbound_property", "ABC");
      
          <vm:inbound-endpoint path="in" exchange-pattern="request-response" />
          <custom-transformer class="com.javarticles.mule.PrintInboundProperty">
              <spring:property name="property" value="inbound_property" />
          </custom-transformer>
      

Outbound scoped property

We will modify the flow by introducing an outbound endpoint with an exchange pattern of request-response. After the message is sent to outbound endpoint, the inbound properties are no more available.

muleContext.xml:

	<flow name="flow2">
		<vm:inbound-endpoint path="in_out_res"
			exchange-pattern="request-response" />
		<message-properties-transformer scope="outbound">
			<add-message-property key="outbound_property"
				value="#[header:INBOUND:inbound_property]" />
			<add-message-property key="outbound_property1"
				value="123" />
		</message-properties-transformer>
		<vm:outbound-endpoint path="out_res"
			exchange-pattern="request-response" />
		<custom-transformer class="com.javarticles.mule.PrintInboundProperty">
			<spring:property name="property" value="inbound_property" />
		</custom-transformer>		
		<custom-transformer class="com.javarticles.mule.PrintOutboundProperty">
			<spring:property name="property" value="outbound_property" />
		</custom-transformer>
		<custom-transformer class="com.javarticles.mule.PrintInboundProperty">
			<spring:property name="property" value="outbound_res_property" />
		</custom-transformer>
		<response>
			<message-properties-transformer scope="outbound">
				<add-message-property key="outbound_property"
					value="NEW" />
			</message-properties-transformer>	
		</response>			
	</flow>
	<flow name="flow3">
		<vm:inbound-endpoint path="out_res"
			exchange-pattern="request-response" />
		<custom-transformer class="com.javarticles.mule.PrintInboundProperty">
			<spring:property name="property" value="outbound_property" />
		</custom-transformer>
		<custom-transformer class="com.javarticles.mule.PrintInboundProperty">
			<spring:property name="property" value="outbound_property1" />
		</custom-transformer>
		<message-properties-transformer scope="outbound">
			<add-message-property key="outbound_res_property"
				value="456" />
		</message-properties-transformer>		
	</flow>

We now send a message to endpoint vm://in_out_res.

sendMsgAndVerifyProperties("vm://in_out_res", ctx, muleClient, "inbound_property",
                    "outbound_property", "outbound_property1", "outbound_res_property");

Output:

send message to vm://in_out_res
outbound_property: ABC
outbound_property1: 123
inbound_property: null
outbound_property: null
outbound_res_property: 456
Verify properties after response
Response: XYZ
inbound_property: null
outbound_property: NEW
outbound_property1: null
outbound_res_property: null

Boundaries of inbound and outbound scoped properties

Thus we can define inbound properties as the one received in an Inbound Endpoint. It also gets manufactured as a response of a call to an Outbound Endpoint.

Inbound and Outbound Scope

Dispatch

In the below example, we dispatch a message to a one-way inbound endpoint in_out. Within the flow, we add couple of outbound properties to the message and then post the message to another one-way outbound endpoint.

	<flow name="flow4">
		<vm:inbound-endpoint path="in_out"
			exchange-pattern="one-way" />
		<message-properties-transformer scope="outbound">
			<add-message-property key="outbound_property"
				value="#[header:INBOUND:inbound_property]" />
			<add-message-property key="outbound_property1"
				value="123" />
		</message-properties-transformer>
		<vm:outbound-endpoint path="out"
			exchange-pattern="one-way" />
	</flow>

Below we retrieve the message posted to the outbound endpoint vm://out and print the inbound properties.

    dispatchMsgAndVerifyProperties("vm://in_out", ctx, muleClient, "inbound_property",
                    "outbound_property", "outbound_property1"); 
    private static void dispatchMsgAndVerifyProperties(String endpointUri, MuleContext ctx,
            MuleClient muleClient, String...inboundProperties) throws Exception {
        System.out.println("Dispatch message to " + endpointUri);
        MuleMessage message = createOutboundMessage(ctx);
        muleClient.dispatch(endpointUri, message);
        MuleMessage response = muleClient.request("vm://out", 3000);
        printInboundProperties(response, inboundProperties);        
    }

As you can see from the output, caller is able to access the outbound properties added in the flow, using the inbound scope.

Output:

Dispatch message to vm://in_out
Verify properties after response
Response: XYZ
inbound_property: null
outbound_property: ABC
outbound_property1: 123

Download the source code

This was an article about inbound and outbound scope, and their boundaries.

You can download the source code here: muleInboundOutboundScopeExample.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.