This page describes the major configuration and code changes in Mule 2.1 to help Mule 2.0 users understand what has changed between releases. If you are migrating from an earlier 1.x version of Mule ESB, please read Migrating Mule 1.x to 2.0 first.
To facilitate better out-of-the-box compatibility with existing Spring configurations when using PropertyPlaceholderConfigurer
or <context:property-placeholder>
(see MULE-3706), the syntax has changed from $\{} to #[ ]. Spring and Mule placeholders can now co-exist in the same configuration without startup exceptions. A great rule of thumb is as follows:
Syntax | Resolver | Config/Runtime |
---|---|---|
${foo} |
Spring |
configuration, typically from an external properties file |
#[header:foo] |
Mule |
runtime, using the full power of expressions in Mule |
Note: at the moment some global HTTP endpoint definitions need to have # symbol escaped according to URI requirements. Therefore, this:
http://example.com/service=#[header:serviceName]
becomes this:
http://example.com/service=%23[header:serviceName]
We may improve this in the future to perform this escaping automatically.
The table below lists the schema changes that have been made since 2.0 and describes how to migrate this change in your application.
Old Tag | New Tag | Notes |
---|---|---|
|
Deleted |
The |
|
|
This tag can only be set within a |
|
|
Updated to use 'service' because the service, not the component, does threading. |
|
|
The word 'component' was removed from the name. |
|
same |
Moved to the last element position within the |
|
same |
This element has moved to the 'mule' namespace (mule.xsd) |
(added in 2.1) |
|
An added feature from Mule 1.x to allow event interceptors to be configured on a component. |
(added in 2.1) |
|
These are available on the |
(added in 2.1) |
|
This element has been added to the Message Properties Transformer so that users can rename properties on the current message using this transformer. |
@honorSynchronicity |
Removed from the Message Splitter router configuration |
All outbound routers now honour the synchronous flag on outbound endpoints (see below). |
(added in 2.1) |
|
This is a new Message Splitter router that will split the message based on an expression. The expression needs to return one or more message parts in order to be effective. |
|
|
The expression recipient list router can be used to send the same message to multiple endpoints over the same endpoint or to implement routing-slip behaviour where the next destination for the message is determined from message properties or the payload. It uses a list of recipients endpoints which are extracted from the message using an expression. |
(added in 2.1) |
@xaTransactedMessageReceiver attribute added to the |
Allows users to override a transports' message receiver used when receiving messages using XA transactions. |
|
Deprecated in 2.1.1 |
This property is no longer relevant with the new retry policies implementation. |
One of the important changes made in Mule 2.1 is that event synchronicity must now be defined explicitly on each endpoint. In earlier versions of Mule, the synchronicity of an event would be inherited from the inbound to the outbound. This is no longer the case.
Requiring the explicit configuration of the synchronous attribute removes much of the ambiguity of configuring new event flows, especially for beginners. The best way to think about event synchronicity in Mule is that synchronous="true"
will return a result from the call, whereas synchronous="false"
will never return a result.
In the following example, the synchronous
attribute on the inbound endpoint would be carried over to the outbound endpoint, so a response from the VM endpoint foo.bar
would be routed back via the TCP enpoint.
<service name="fooService">
<inbound>
<tcp:inbound-endpoint host="localhost" port="32422" synchronous="true"/>
</inbound>
<component class="com.foo.MyComponent"/>
<outbound>
<pass-through-router>
<vm:outbound-endpoint path="foo.bar"/>
</pass-through-router>
</outbound>
</service>
In Mule 2.1, this configuration will result in the response from com.foo.MyComponent
being routed back to the caller, and the result will also be dispatched asynchronously on the VM endpoint foo.bar
.
To get a response from the VM endpoint foo.bar
routed back to the caller (TCP endpoint), you must make the endpoint synchronous.
<service name="fooService">
<inbound>
<tcp:inbound-endpoint host="localhost" port="32422" synchronous="true"/>
</inbound>
<component class="com.foo.MyComponent"/>
<outbound>
<pass-through-router>
<vm:outbound-endpoint path="foo.bar" synchronous="true"/>
</pass-through-router>
</outbound>
</service>
Note that the default synchronous
attribute value for endpoints in Mule is false
. You can change this default to true
by adding the following to your configuration file:
<configuration defaultSynchronousEndpoints="true"/>
Also note that the honourSynchronicity
router attribute has been removed since all routers in Mule now must use the synchronous
flag on the endpoint when dispatching events.
Tip
|
Recommended Reading For a better understanding of configuring event flows in Mule, we strongly recommend that you familiarize yourself with the patterns defined in the Mule Messaging Styles page. This provides a description and example configuration for each pattern. |
By default, multicast routers now aggregate the responses in a list before returning them. You can override this behavior by setting the synchronous
attribute to true
on any router whose response you want to return as a separate response. For example:
<multicasting-router>
<vm:outbound-endpoint path="orders" synchronous="true"/>
<jms:outbound-endpoint queue="order.request" synchronous="false"/>
</multicasting-router>
This example would return the response for the first router as a separate response.
Some outbound routers such as the List Message Splitter, Multicaster and Recipient List may return more that one result message if:
-
There is more than one endpoint configured on the router
-
More than one of the endpoints has the
synchronous
attribute set totrue
To handle situations where multiple results occur, Mule has introduced a new message type:
This type of message contains all message results in the order in which they were received. Note that the class:
extends:
So the interface is similar. If there are multiple results, the MuleMessage.getPayload()
method will return a java.util.List
containing the payloads of each of the returned messages.
If you are using the Mule client, you can cast the message return type to get access to all messages.
MuleClient client = new MuleClient();
MuleMessage result = client.send("myEndpoint", "some data", null);
if(result instanceof MuleMessageCollection)
{
MuleMessageCollection resultsCollection = (MuleMessageCollection)result;
System.out.println("Number of messages: " + resultsCollection.size());
}
Reconnection strategies have been redesigned and renamed to "retry policies".
If you are using the Enterprise Edition of Mule, there are several standard retry policies available that you can configure using the new Retry schema. If you are using the Community Edition of Mule, you must create your own policies and configure them using standard Spring syntax rather than the Retry schema. For more information, see Configuring Retry Policies.
As of 2.1, Mule has a collection of Registry’s with a facade in front of them called `RegistryBroker
, so when you make a call to muleContext.getRegistry().lookupObject("foo")
that actually looks for "foo"
in each of the `Registry’s in the collection until it finds it.
These internal changes were necessary in order to support hot deployment. The relevant API is in org.mule.api.registry
and implementation classes in org.mule.registry
This change may affect you if you were passing an existing Spring ApplicationContext to Mule at startup.
The Splitter Router API has been modified to allow greater control over how split messages are routed. It is very easy to create custom splitter routers that can route specific parts to specific endpoints, or perform round robin distribution. It is even possible to make round robin deterministic.
The previous API for the Splitter router defined the following interface:
protected abstract MuleMessage getMessagePart(MuleMessage message, ImmutableEndpoint endpoint);
The problem was that this method was called for each endpoint and required that either the message was split ahead of time, in which case this method would just return the correct part, or that message segments would have to be split on every invocation of this method.
In Mule 2.1 this method has been replaced with the following:
protected abstract SplitMessage getMessageParts(MuleMessage message, List <OutboundEndpoint> endpoints);
This method is called once per message. It allows the router to split the message and optionally assign a specific endpoint to each part. The new
class just maintains a list of SplitMessage.MessagePart
objects, each holding a message fragment and an endpoint destination for the message part.
In addition to the AbstractMessageSplitter class:
…there is now a new AbstractRoundRobinMessageSplitter class:
This base class should be used for splitter routers that want to use round robin to distribute message parts.