What's New in Mule 2.0?

XML Schema

The principal new feature of Mule 2.0 is a powerful new schema-based configuration style leveraging Spring's Extensible XML Authoring

The new format doesn't change too much. It should be readable by anyone familiar with Mule 1.x, and conversion is usually simple. To get started, check out Migrating Mule 1.x to 2.0.

For more examples of the new configuration style, take a look at the example apps which come in the Mule distribution or some of the functional tests, especially for transports (transports/xxx/src/test/resources/*.xml)

Configuring your Mule is now easier than ever before!

  • All available config options are provided to you by your IDE (via XML schemas) and the correct syntax is auto-completed for you (tested with Eclipse and IntelliJ)
  • No need to remember, type, or copy/paste long class names, they are now hidden from the user (unless you want to provide a custom class)
  • It's harder to shoot yourself in the foot because the Namespace Handlers help validate your config before Mule even starts up.
  • No longer having class names in your config files should make upgrading Mule less likely to break your configs ("less brittle").

Transport-Specific Endpoints

Endpoint configuration has been greatly improved thanks to the benefits of schema based configuration along with our "Bean Definition Parser Toolkit" and the separation of inbound/outbound/response endpoints into their own elements and the ability to define transport specific endpoints in their own namespace. This is very powerful in that each and every endpoint type (transport + context (inbound/outbound)) can be defined in the schema(s) so that class names and properties are avoided and only the relevant transport/context attributes and elements are available. Not only does this make for a typed easier-to-read configuration file, but it also makes endpoint configuration, in combination with your favorite XML editor, a pleasure with auto-completion.

Configuration Namespaces

  • Configuration elements are organized into modular, transport-specific namespaces so that you only need to include the namespaces for those modules used by your Mule config.
  • This modularity means that new modules/transports developed by you! can have their own custom namespace.
  • For a guide on creating a new Configuration Namespace, read [Creating a Custom XML Namespace].

Bean Definition Parser Toolkit

What Spring's Extensible XML Authoring has let us do is basically create a Domain-Specific Language for configuring Mule. This DSL is based on what are called Bean Definition Parsers. Spring itself provides many classes for creating your own Bean Definition Parsers, but Mule has built on that foundation to create its own "BDP Toolkit" which helps transport authors (such as those working on MuleForge projects) easily add new configuration elements. Common cases like maps, list elements and references are handled automatically, while parsers for more complex configurations can be assembled from simpler sub-components using simple combinators.

A Spring-ier Mule

Spring being the default configuration mechanism for Mule 2.0 also brings other benefits:

  • Spring is the industry-leading framework for "wiring" and configuring Java applications, much more robust than the old Commons Digester mechanism
  • Common Mule configs are simplified by the Namespace Handlers while custom configs can use standard Spring config syntax
  • You get the full features of Spring for free within your Mule:
    • Spring AOP
    • Spring resource loading
    • Spring modules support (JNDI, Hivemind, EJB)

Architectural Improvements

In addition to the user-facing XML config, we've also been working hard on architectural improvements to make Mule more robust and to pave the way for new, powerful enterprise features in future versions of Mule. We have taken advantage of this new major release to make some API modifications which give a range of improvements that could not have been introduced with earlier versions.

MuleContext and Registry

The old monolithic MuleManager is gone in 2.0, replaced by a MuleContext and one or more internal Registries. The MuleContext is injected into any entity which implements the MuleContextAware interface, and is used to access the Registry among other things.

The SpringRegistry is basically a facade on Spring's ApplicationContext (populated at startup), and is read-only. There is also a TransientRegistry (read-write) into which entities may be registered after startup. The Registry architecture will continue to evolve a bit in future releases and will form the basis of OSGi support in Mule.

Service/Component">MuleDescriptor -> Service/Component

The MuleDescriptor in Mule 1.x combined all aspects of a Mule service/component together (routers/endpoints, exception strategy, implementation class, singleton/poooled, etc.) This has been removed in 2.0, and in its place a clearly-separated Service and Component model have been introduced. The Component consists of your "Plain Old Java Object" and any configuration having to do with the lifecycle of that object, e.g., the object might be a singleton instance, pooled, or looked up from an external source via JNDI. The Service then builds on the Component by adding inbound/outbound endpoints + routers, exception strategies, etc.

Endpoints

We took the opportunity to make some architectural improvements to endpoint creation, lookup and global endpoint configuration and usage. This work consisted of general consolidation and clean-up of endpoint creation and lookup logic through the introduction of the EndpointBuilder and EndpointFactory along with some work to ensure endpoints are immutable once created.

  • EndpointBuilder is a stateful builder which constructs endpoint instances for a given type (inbound/outbound/response) based on how the endpoint builder has been configured. When endpoints are configured via spring EndpointFactoryBean's are used which extend EndpointBuilder such that the endpoint builder is configured from spring and is then invoked to create endpoint instances.
  • EndpointFactory is a stateless factory used to obtain endpoints given the endpoint uri or global endpoint name (uri is substitutable with name). The factory deals with all the endpoint lookup and creation logic delegating to EndpointBuilder's for creation of new endpoint instance if required.

Streaming and Auto Transformations

Mule 2 features much improved streaming and transformation capabilities. Many users will notice a performance boost by upgrading. Now, any transport that supports streaming (i.e. HTTP, File, etc) will pass a stream as the message payload instead of loading the stream into memory.

Mule now also supports intelligent, efficient transformations. It can auto-detect the required type for a component and transform the stream without any extra configuration. For instance, if you have a component which receives a String and it is wired up to HTTP, Mule will take the HTTP InputStream and convert it to a String without an additional transformer configuration.

There is now no need to configure a Streaming model, implement a StreamingService API or use a UMOStreamMessageAdapter. These classes have all been removed. Data is not consumed from a stream payload until it is required. The payload of the message automatically becomes the data consumed from the stream.

MuleMessage and MessageAdapter

  • There is now a much better definition between the roles of these two classes.
  • MessageAdapter now ONLY deals with wrapping a message type. There are no methods for converting the payload to String or byte[] array. getPayloadAsString() and getPayloadAsBytes() methods have been removed.
  • MuleMessage provides access to the UMOMessageAdapter properties, payload and attachments. It also provides methods for working with and changing the message payload.
  • The MuleMessage.getPayload(Class) is used for obtaining the payload in different formats (but doesn't change the payload)
  • The MuleMessage.applyTransformers(List) will apply a list of transformers to the message payload. This WILL change the message payload. This method removes the need to copy the current message once the payload changes.
  • The MuleMessage still exposes getPayloadAsString() and getPAyloadAsBytes() methods.

API

The API was re-organised taking advantage that 2.0 is a major release to update outdated packages and interface names and improve consistency. Interfaces no longer are prefixed with "UMO", and are now in "org.mule.api" rather than "org.mule.umo. Also 'org.mule.providers' was renamed to 'org.mule.transport' and 'org.mule.samples' to 'org.mule.example'.

Spring XML Configuration

MuleXMLConfigurationBuilder in mule-core was moved to the "spring-config" module and renamed as SpringXMLConfigurationBuilder. In order to use XML configuration, you will now need to include the "spring-config" module on your classpath.

ConfigurationBuilder + MuleContextFactory

The monolithic ConfigurationBuilder API was improved so that it now simply configures an existing Mule instance and a MuleContextFactory interface was introduced for creating a new MuleContext. A DefaultMuleContextFactory is provided with methods that allow MuleContext creation and configuration in a manner similar to the old MuleXMLConfigurationBuilder. Additionally, the QuickConfigurationBuilder has been removed, as it provided minimal functionality and is no longer needed with the new

Miscellaneous improvements

  • A more consistent, extended interface to the TCP socket based transports (and the SSL/TLS configuration)
  • Moved the receive method from the Dispatcher into a new Requester interface with corresponding transport property
  • More efficient handling of notifications

Quality Assurance

We are always striving for better test coverage and overall quality in the Mule codebase, so Mule 2.0 has many new unit and functional tests across different areas of the code. We have also scaled up our Continuous Integration infrastructure since previous releases (not to mention our development team!), so the code has really been getting tested round-the-clock. We are currently running 30% more unit tests on the 2.0 codebase as compared to 1.4!

Not yet implemented

In the drive to get Mule 2.0 into your hands as soon as possible, a few things are still-to-come in future releases:

  • Alternate (non-SEDA) Models
  • Component Interceptors

Migrating Mule 1.x to 2.0


Introduction

This page describes the major configuration and code changes in Mule 2.0 to help Mule 1.x users understand what has changed between releases. For more information on new features and changes, see Whats New in Mule 2.0.

The principal new feature of Mule 2.0 is a powerful new schema-based configuration style leveraging Spring's Extensible XML Authoring.
The new format looks similar to the Mule 1.x format, and upgrading from Mule 1.x to 2.x is fairly straightforward. This page will help you get started.

Quick Reference

This section provides a quick reference to the changes from 1.x to 2.x.

XML Configuration Changes

1.x 2.x
Interceptors not supported
Mule implementations are attributes Mule implementations are elements
Mule descriptor implementation is explicitly required Service component configuration is optional. PassThroughComponent is default.
Endpoint: address or name attribute Endpoint: address, name, or new path attribute

Code Changes

For details on these changes, see What's New in Mule 2.0.

1.x 2.x
org.mule.umo.* org.mule.api.* in most cases
org.mule.providers.* org.mule.transport.*. For details on migrating 1.x transports to 2.x, click here.
org.mule.extras.* org.mule.module.NAME.*
package names are singular/plural package names are singular
MuleClient.receive(...) MuleClient.request(...)
MuleManager utility class MuleContext instance available through life cycle methods or MuleAwareContext implementation.
QuickConfigurationBuilder No longer supported
MuleXMLConfigurationBuilder DefaultMuleContextFactory
UMOMessage MuleMessage
MuleMessage DefaultMuleMessage
UMOEndpoint InboundEndpoint or OutboundEndpoint
UMOEndpointURI EndpointURI
MuleEndpoint.getOrCreateEndpointForUri(..., UMOEndpoint.ENDPOINT_TYPE_SENDER) new DefaultEndpointFactory().getOutboundEndpoint(...)
MuleEndpoint.getOrCreateEndpointForUri(..., UMOEndpoint.ENDPOINT_TYPE_RECEIVER) new DefaultEndpointFactory().getInboundEndpoint(...)

Example Configuration (Before and After)

To get an overview of the changes, compare the same configuration file in 1.4 and 2.0

Configuration Changes

This section describes the configuration changes in detail.

File Header

Mule configuration files are now based on an XML schema instead of DTDs. Therefore, you must configure the Mule core namespace plus any modules or transports as shown below in this empty configuration file.

Mule 1.4
"1.0" encoding="UTF-8"?>


"-//MuleSource //DTD mule-configuration XML V1.0//EN"
"http://mule.mulesource.org/dtds/mule-configuration.dtd">

"Samples" version="1.0">

Mule 2.0
"1.0" encoding="UTF-8"?>

"http://www.mulesource.org/schema/mule/core/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.0"
xsi:schemaLocation="
http://www.mulesource.org/schema/mule/core/2.0 http://www.mulesource.org/schema/mule/core/2.0/mule.xsd
http://www.mulesource.org/schema/mule/jms/2.0 http://www.mulesource.org/schema/mule/jms/2.0/mule-jms.xsd">

Note: This page describes the recommended approach of using mule as the default namespace, but you can also use other default namespaces, such as the Spring "beans" namespace.

Connectors

Just as with Mule 1.x, connectors are configured as top-level elements in the Mule configuration, but they now use transport-specific schemas. The connector elements have changed accordingly as shown below:

Mule 1.4
"org.mule.providers.vm.VMConnector"/>

"org.mule.providers.jms.JmsConnector"/>
Mule 2.0


The new approach provides a huge advantage in that each transport now defines its own syntax for configuring connectors, avoiding class names and untyped properties. Additionally, you can use your favorite IDE's auto-completion feature, making Mule 2.0 fast and easy to configure.

Following is another example illustrating a stdio connector taken from the echo example:

Mule 1.4
"SystemStreamConnector" className="org.mule.providers.stream.SystemStreamConnector">


"promptMessage" value="Please enter something: "/>
"messageDelayTime" value="1000"/>

Mule 2.0
"SystemStreamConnector"

promptMessage="Please enter something: "
messageDelayTime="1000"/>

Note: To use a specific transport, you must import its namespace as explained above.

Endpoints

Endpoints are now easier to configure and more context-specific in Mule 2.0, as described below.

Global Endpoints

Global endpoints act as endpoint templates, allowing you to configure and reuse an endpoint configuration for multiple logical endpoints. To configure a global endpoint, you use the "endpoint" element as a top-level element instead of on routers or exception strategies. You can configure all the same elements on a global endpoint as on a logical endpoint, including making them transport-specific.
An in 1.4 is equivalent to a global endpoint in 2.0 that just has a URI configured.

Notes:

  • Be careful defining transformers on global endpoints that are referenced by inbound and outbound endpoints, as transformers are not the same for inbound and outbound endpoints.
  • Although logical endpoints inherit and can extend a global endpoint configuration, you cannot extend properties. Properties configured on a logical endpoint will overwrite properties configured on the referenced global endpoint.

Explicit Endpoint Types

You now specify endpoint types explicitly (inbound, outbound, or response). This approach allows endpoints to have more specific configuration. For example, by specifying an endpoint as inbound, you could ensure that pollingFrequency is configured on the inbound file connector but not on its outbound counterpart.

Transport-specific Endpoints

Endpoint configuration has been improved to avoid untyped properties. Some of these properties are cross-transport attributes or elements, whereas others are defined by transport-specific endpoint definitions.

Mule 1.4
"pop3://bob:secret@localhost:62002" transformers="BytesToMime"/>
Mule 2.0
"bob" password="secret" host="localhost" port="62002">


Services and Components (Formerly MuleDescriptors)

Services and components are now configured differently. Following are the two versions of the Mule Hello example:

Mule 1.4
"ChitChatUMO" implementation="org.mule.samples.hello.ChitChatter">


"vm://chitchatter" transformers="NameStringToChatString"/>


"org.mule.routing.outbound.OutboundPassThroughRouter">
"stream://System.out" transformers="ChatStringToString" />


Mule 2.0
"ChitChatUMO">


"chitchatter" transformer-refs="NameStringToChatString"/>

"org.mule.samples.hello.ChitChatter"/>


"OUT" transformer-refs="ChatStringToString"/>


Following is a description of the changes:

New Nomenclature:

MuleDescriptor is now Service
Implementation is now Component

Extensibility:

A component is abstract, allowing multiple implementation types. By default, Mule includes two implementations: and . Other modules can add other component types.

The and elements are configured in exactly the same way, except that the has an additional optional child element that can be use to customize the pool behavior. These elements can either use the "class" attribute or define an object-factory as a child element. If you use the "class" attribute, the prototype object factory will be used by default. You can configure components with singleton, prototype, and Spring object factories.

Minimal Configuration:

"org.your.PrototypeComponent"/>

..
"org.your.PooledPrototypeComponent"/>

Complete Configuration Example:

"myPooledSpringBeanComponent" class="org.your.PooledSpringBeanComponent" />

..


"myPooledSpringBeanComponent"/>
"org.mule.config.spring.parsers.specific.TestLifecycleAdapterFactory"/>
"java.lang.String" method="setMethod">
"vm://myEndpoint" />

"WHEN_EXHAUSTED_FAIL"
initialisationPolicy="INITIALISE_ALL" maxActive="1"
maxIdle="2" maxWait="3" />

Routers and Filters

Routers and filters also take advantage of the new schema-based configuration. Most are defined in Mule, but specific modules and transports can also contribute routers or filters by defining them in their own namespace.

Mule 1.4
"org.mule.routing.inbound.SelectiveConsumer"/>

"org.mule.routing.outbound.FilteringOutboundRouter"/>
"org.mule.routing.outbound.MulticastingRouter"/>
"org.my.CustomRouter"/>
Mule 2.0




"org.my.CustomRouter"/>
Mule 1.4


"CustomerResponses" address="vm://customer.responses"/>

..
"org.mule.routing.outbound.FilteringOutboundRouter">
"CustomerResponses"/>
"org.mule.examples.loanbroker.messages.LoanQuote" className="org.mule.routing.filters.PayloadTypeFilter"/>
Mule 2.0
"CustomerResponses" path="customer.responses"/>

..

"CustomerResponses"/>
"org.mule.examples.loanbroker.messages.LoanQuote"/>

(Taken from LoanBroker ESN Example)

Transformers

Transformers also take advantage of the new schema-based configuration. Modules and transports contribute transformers by defining them in their own namespace.

Transformers are now defined directly rather than by specifying class names.

Mule 1.4
"org.mule.transformers.simple.MessagePropertiesTransformer"/>

"org.mule.transformers.simple.ByteArrayToObject"/>
"org.mule.transformers.xml.XsltTransformer"/>
"org.my.CustomTransformer"/>
Mule 2.0




"org.my.CustomTransformer"/>

Custom transformers can still be used with the "custom-transformer" element.

Transformers can be referenced from endpoints using the "transformer-refs" attribute or can be declared inline.

Mule 1.4
"CustomerRequestsREST" transformers="RestRequestToCustomerRequestTransformer"/>
Mule 2.0
"CustomerRequestsREST" transformer-refs="Transformer1 Transformer2"/>


"CustomerRequestsREST">
"RestRequestToCustomerRequestTransformer" />


"IncomingData">

Bridging

Bridging configuration has been simplified in Mule 2.0. To implement a bridge service, you simply configure inbound and outbound routers. Bridging occurs implicitly.

Mule 1.4
"bridge" implementation="org.mule.components.simple.BridgeComponent">


"vm://bridge.inbound"/>


"org.mule.routing.outbound.OutboundPassThroughRouter">
"vm://bridge.outbound"/>


Mule 2.0
"bridge">


"bridge.inbound"/>



"bridge.outbound"/>


The "bridge-component" and "pass-through-component" can still be used for backward-compatibility but are no longer needed.

Exception Strategies

Developers now have much finer control over transactions through configuration. Pattern matching filters can be used to match different types of exceptions. For example:

       


"*">
"DLQ"/>

...

This configuration tells Mule to keep any current transaction open until after we dispatch to the JMS DLQ (Dead Letter Queue), and then commit the current transaction.

For certain transactions, you may want to roll back the transaction immediately. For example:

       


"*">
"com.acme.a.*,com.acme.b.*"/>
"DLQ"/>

...

This configuration tells Mule to roll back transactions when there are exceptions with packages com.acme.a and com.acme.b. Otherwise, commit the current transaction. Note that the has priority over the element.


0 comments: