<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:stdio="http://www.mulesoft.org/schema/mule/stdio"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/stdio http://www.mulesoft.org/schema/mule/stdio/3.6/mule-stdio.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.6/mule.xsd">
<stdio:connector name="stdio" promptMessage="Yes? " messageDelayTime="1000"/>
<flow name="echo">
<stdio:inbound-endpoint system="IN"/>
<stdio:outbound-endpoint system="OUT"/>
</flow>
</mule>
Understanding Mule Configuration
Mule Runtime Engine versions 3.5, 3.6, and 3.7 reached End of Life on or before January 25, 2020. For more information, contact your Customer Success Manager to determine how you can migrate to the latest Mule version. |
About XML Configuration
Mule uses an XML configuration to define each application, by fully describing the constructs required to run the application. A basic Mule application can use a very simple configuration, for instance:
We will examine all the pieces of this configuration in detail below. Note for now that, simple as it is, this is a complete application, and that it’s quite readable: even a brief acquaintance with Mule makes it clear that it copies messages from standard input to standard output.
Schema References
The syntax of Mule configurations is defined by a set of XML schemas. Each configuration lists the schemas it uses and give the URLs where they are found. The majority of them will be the Mule schemas for the version of Mule being used, but in addition there might be third-party schemas, for instance:
-
Spring schemas, which define the syntax for any Spring elements (such as Spring beans) being used
-
CXF schemas, used to configure web services processed by Mule’s CXF module
Every schema referenced in a configuration is defined by two pieces of data:
-
Its namespace, which is a URI
-
Its location, which is a URL
The configuration both defines the schema’s namespace URI as an XML namespace and associates the schema’s namespace and location. This is done in the top-level mule
element, as we can see in the configuration above:
<mule xmlns="http://www.mulesoft.org/schema/mule/core" ❶
xmlns:stdio="http://www.mulesoft.org/schema/mule/stdio" ❷
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/stdio http://www.mulesoft.org/schema/mule/stdio/3.6/mule-stdio.xsd ❸
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.6/mule.xsd" ❹>
❶ Shows the core Mule schema’s namespace being defined as the default namespace for the configuration. This is the best default namespace, because so many of the configuration’s elements are part of the core namespace.
❷ Shows the namespace for Mule’s stdio transport, which allows communication using standard I/O, being given the "stdio" prefix. The convention for a Mule module or transport’s schema is to use its name for the prefix.
The xsi:schemaLocation attribute associates schemas' namespaces with their locations. ❸ gives the location for the stdio schema and ❹ for the core schema.
It is required that a Mule configuration contain these things, because they allow the schemas to be found so that the configuration can be validated against them.
Default Values
Besides defining the syntax of the elements and attributes that they define, schemas can also define default values for them. Knowing these can be extremely useful in making your configurations readable, since thy won’t have to be cluttered with unnecessary information. Default values can be looked up in the schemas themselves, or in the Mule documentation for the modules and transports that define them. For example, the definitions of the <poll>
element, which polls an endpoint repeatedly, contains the following attribute definition:
<xsd:attribute name="frequency" type="substitutableLong" default="1000">
<xsd:annotation>
<xsd:documentation>Polling frequency in milliseconds. Default frequency is 1000ms (1s).
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
It is only necessary to specify this attribute when overriding the default value of 1 second.
Enumerated Values
Many attributes in Mule can take only a limited set of values. These are defined in the schema as enumerated values, to ensure that only those values can be specified. Here’s an example from the stdio transport:
<xsd:attribute name="system">
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="IN"/>
<xsd:enumeration value="OUT"/>
<xsd:enumeration value="ERR"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
This enforces that the only values allowed are IN
, OUT
, and ERR
, corresponding to standard input, output, and error respectively.
Advantages of a Strongly Typed Language
The requirement to reference all of the schemas may seem a bit cumbersome, but it has two advantages that far outweigh the effort.
First, it helps you create a valid configuration the first time. The major integrated development environments all provide schema-aware XML editors. Thus, as you create and edit your configuration, the IDE can prompt you with the elements and attributes that are allowed at each point, complete their names after you’ve typed a few characters, and highlight any typing errors that need correction. Likewise, it can provide the same help for filling in enumerated values.
Second, it allows Mule to validate your configuration as the application starts up. Unlike some other configuration-based systems that silently ignore elements or attributes that they don’t recognize, Mule catches these errors so that you can correct them. For example, suppose that in the configuration above, we had misspelled "outbound-endpoint". As soon as the application tries to start up, the result would be the error:
org.mule.api.lifecycle.InitialisationException: Line 14 in XML document is invalid;
nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.a:
Invalid content was found starting with element 'stdio:outbound-endpint'.
This points directly to the line that needs to be corrected. It is much more useful than simply ignoring the problem and leaving you to wonder why no output is ever written.
About Spring Configuration
The Mule facility for parsing configurations embeds Spring, so that a Mule configuration can, in addition to defining Mule-specific constructs, do anything a Spring configuration can do: create Spring Beans, configure lists and maps, define property placeholders, and so on. We will look at this in more detail in the following sections. Note that, as always, it will be necessary to reference the proper schemas.
Spring Beans
The simplest use of Spring in a Mule configuration is to define Spring Beans. These beans are placed into the Mule registry along with the Mule-specific objects, where they can be looked up by name by any of your custom Java objects, for instance, custom components. You can use the full range of Spring capabilities to create them. For example:
<spring:beans>
<spring:bean name="globalCache" class="com.mycompany.utils.LRUCache" >
<spring:property name="maxItems" value="200"/>
</spring:bean>
</spring:beans>
Spring Properties
There are many places in a Mule configuration when a custom Java object can be used: custom transformers, filters, message processors, etc. In each case, one possibility is to specify the class to instantiate and a set of Spring properties to configure the resulting object. Once again, you can use the full range of Spring syntax within the properties, including lists, maps, etc.
Here’s an example:
<custom-processor class="com.mycompany.utils.CustomerClassChecker">
<spring:property name="highPriorities">
<spring:list>
<spring:value>Gold</spring:value>
<spring:value>Platinum</spring:value>
<spring:value>Executive</spring:value>
</spring:list>
</spring:property>
</custom-processor>
The syntax for creating custom components is a bit different, to allow more control over how the Java object is created. For instance, to create a singleton:
<component>
<singleton-object class="com.mycompany.utils.ProcessByPriority">
<properties>
<spring:entry key="contents">
<spring:list>
<spring:value>Gold</spring:value>
<spring:value>Platinum</spring:value>
<spring:value>Executive</spring:value>
</spring:list>
</spring:entry>
</properties>
</singleton-object>
</component>
Property Placeholders
Mule configurations can contain references to property placeholders, to allow referencing values specified outside the configuration file. One important use case for this is usernames and passwords, which should be specified in a more secure fashion. The syntax for property placeholders is simple: ${name
}, where name
is a property in a standard Java property file.
Here is an example of a configuration that uses property placeholders, together with the properties it references:
Configuration:
<spring:beans>
<context:property-placeholder
location="classpath:my-mule-app.properties,
classpath:my-mule-app-override.properties" />
</spring:beans>
<http:endpoint name="ProtectedWebResource"
user="${web.rsc.user}"
password="${web.rsc.password}"
host="${web.rsc.host}"
port="80"
path="path/to/resource" />
Properties file:
web.rsc.user=alice
web.rsc.password=s3cr3t
web.rsc.host=www.acme.com
Note the the location given for the file is a location in the classpath. Another alternative would be a URL, for instance ` file:///etc/mule/conf/my-mule-app-override.properties `. As shown above, it is also possible to specify a list of properties files, comma-separated.
About Mule Configuration
Global Elements
Many Mule elements can be specified at the global level, that is, as direct children of the outermost mule
element. These global elements always have names, which allows them to be referenced where they’re used. Note that a Mule configuration uses a single, flat namespace for global elements. No two global elements can share the same name, even if they are entirely different sorts of things, say an endpoint and a filter.
Let’s examine the most common global elements:
Connectors
A connector is a concrete instance of a Mule transport, whose properties describe how that transport is used. All Mule endpoints use transports which inherit the connector’s properties.
Here are some examples of connectors:
<vm:connector name="persistentConnector"> ❶
<vm:queueProfile persistent="true" />
</vm:connector>
<file:connector name="fileConnector" ❷
pollingFrequency="1000" moveToDirectory="/tmp/test-data/out" />
❶ The vm connector specifies that all of its endpoints use persistent queues. ❷ The file connector specifies that each of its endpoints will be polled once a second, and also the directory that files will be moved to once they are processed.
Note that properties may be specified either by attributes or by child elements. You can determine how to specify connector properties by checking the reference for that connector’s transport.
The relationship between an endpoint and its connector is actually quite flexible:
-
If an endpoint specifies a connector by name, it uses that connector. It is, of course, an error if the endpoint and the connector use different transports.
-
If an endpoint does not name a connector, and there is exactly one connector for its transport, the endpoint uses that connector.
-
If an endpoint does not name a connector, and there is no connector for its transport, Mule creates a default connector for all endpoints of that transport to use.
-
It is an error if an endpoint does not name a connector, and there is more than one connector for its transport.
Endpoints
A Mule endpoint is an object that messages can be read from (inbound) or written to (outbound), and that specifies properties that define how that will be done. Endpoints can be specified two different ways:
-
An endpoint specified as a global element is called a global endpoint. An inbound or outbound endpoint, specified in a flow, can refer to a global endpoint using the
ref
attribute. -
An inbound or outbound endpoint, specified in a flow can be configured without referring to a global endpoint.
A global endpoint specifies a set of properties, including its location. Inbound and outbound endpoints that reference the global endpoint inherit its properties. Example:
<vm:endpoint name="in" address="vm://in" connector-ref="persistentConnector" /> ❶
<endpoint name="inFiles" address="file://c:/Orders" /> ❷
The vm endpoint in ❶ specifies its location and refers to the connector shown above. It uses the generic address
attribute to specify its location. The file endpoint at ❷ specifies the directory it reads from (or writes to), and uses the default file connector. Because it is configured as a generic endpoint, it must specify its location via address
.
Note that every endpoint uses a specific transport, but that this can be specified in two different ways:
-
If the element has a prefix, it uses the transport associated with that prefix. (❶)
-
If not, the prefix is determined from the element’s address attribute. (❷)
The prefix style is preferred, particularly when the location is complex.
<endpoint address="http://${user.name}:${user.password}@localhost:8080/services/orders/">
One of the most important attributes of an endpoint is its message exchange pattern (MEP, for short), that is, whether messages go only one way or if requests return responses. This can be specified at several levels:
-
Some transports only support one MEP. For instance, imap is one way, because no response can be sent when it reads an e-mail message. servlet, on the other hand. is always request-response.
-
Every transport has a default MEP. JMS is one-way by default, since JMS message are not usually correlated with responses. HTTP defaults to request-response, since the HTTP protocol has a response for every request.
-
Endpoints can define MEPs, though only the MRPs that are legal for their transport are allowed
Transformers
A transformer is an object that transforms the current Mule message. The Mule core defines a basic set of transformers, and many of the modules and transports define more, for instance the JSON module defines transformers to convert an object to JSON and vice-versa, while the Email transport defines transformers that convert between byte arrays and MIME messages. Each type of transformer defines XML configuration to define its properties. Here are some examples of transformers:
<json:json-to-object-transformer ❶
name="jsonToFruitCollection" returnClass="org.mule.module.json.transformers.FruitCollection">
<json:deserialization-mixin
mixinClass="org.mule.module.json.transformers.OrangeMixin" targetClass="org.mule.tck.testmodels.fruit.Orange"/>
</json:json-to-object-transformer>
<message-properties-transformer name="SetInvocationProperty" scope="invocation"> ❷
<add-message-property key="processed" value="yes" />
</message-properties-transformer>
The transformer at ❶ converts the current message to JSON, specifying special handling for the conversion of the org.mule.tck.testmodels.fruit.Orange
class. The transformer at ❷ adds an invocation-scoped property to the current message.
Like endpoints, transformers can be configured as global elements and referred to where they are used, or configured at their point of use.
For more about Mule transformers, see Using Transformers.
Filters
A filter is an object that determines whether a message should be processed or not. As with transformers, the Mule core defines a basic set of transformers, and many of the modules and transports define more. Here are some examples of filters:
<wildcard-filter pattern="* header received"/> ❶
<mxml:is-xml-filter/> ❷
The filter at ❶ continues processing of the current message only if it matches the specified pattern. The filter at ❷ continues processing of the current message only if it is an XML document.
There are a few special filters that extend the power of the other filters. The first is message-filter
:
<message-filter onUnaccepted="deadLetterQueue"> ❶
<wildcard-filter pattern="* header received"/>
</message-filter>
<message-filter throwOnUnaccepted="true"> ❷
<mxml:is-xml-filter/>
</message-filter>
As above, ❶ continues processing of the current message only if it matches the specified pattern. But now any messages that don’t match, rather than being dropped, are sent to a dead letter queue for further processing. ❷ continues processing of the current message only if it is an XML document, but throws an exception otherwise.
Other special filters are and-filter
, or-filter
, and not-filter
, which allow you to combine filters into a logical expression:
<or-filter>
<wildcard-filter pattern="*priority:1*"/>
<and-filter>
<not-filter>
<wildcard-filter pattern="*region:Canada*"/>
</not-filter>
<wildcard-filter pattern="*priority:2*"/>
</and-filter>
</or-filter>
This processes a message only if it’s either priority 1 or a priority 2 message from a country other than Canada.
Filters once again can be configured as global elements and referred to where they are used, or configured at their point of use. For more about Mule filters see Using Filters
Expressions
For a current reference to using expressions in Mule, see Mule Expression Language MEL.
Names and References
As we’ve seen, many Mule objects can be defined globally. The advantage of this is that they can be reused throughout the application, by referring to them where they’re needed. There’s a common pattern for this:
-
The global object is given a name using the
name
attribute -
It is referred to using the "ref" attribute
For each type of object, there is a generic element used to refer to it.
-
All global transformers are referred to by the
transformer
element -
All global message processors are referred to by the
processor
element -
All global endpoints are referred to by the
inbound-endpoint
oroutbound-endpoint
elements -
All global filters are referred to by the
filter
element
For example
<vm:endpoint name="in" address="vm://in" connector-ref="persistentConnector" />
<expression-filter name="checkMyHeader" evaluator="header" expression="my-header!"/>
<message-properties-transformer name="SetInvocationProperty" scope="invocation">
<add-message-property key="processed" value="yes" />
</message-properties-transformer>
<flow name="useReferences">
<vm:inbound-endpoint ref="in"/>
<filter ref="checkMyHeader"/>
<transformer ref="SetInvocationProperty"/>
</flow>
In addition, there are places where the names of global objects are the values of an attribute, for instance:
<vm:endpoint name="in" address="vm://in" transformer-refs="canonicalize sort createHeaders" />
Flows
The flow is the basic unit of processing in Mule. A flow begins with an inbound endpoint from which messages are read and continues with a list of message processors, optionally ending with an outbound endpoint, to which the fully processed message is sent. We’ve already met some types of message processors: transformers and filters. Other types include components, which process messages using languages like Java or Groovy, connectors, which call cloud services, and routers, which can alter the message flow as desired. Below is a simple flow, which we’ll be referring to as we examine its parts:
<http:listener-config name="listener-config" host="localhost" port="8081"
doc:name="HTTP Listener Configuration"/> ❶
<flow name="acceptAndProcessOrder">
<http:listener config-ref="listener-config" path="/" doc:name="HTTP Connector"/>
<byte-array-to-string-transformer/> ❷
<jdbc:outbound-endpoint ref="getOrdersById" exchange-pattern="request-response"/> ❸
<mxml:object-to-xml-transformer/> ❹
<expression-filter evaluator="xpath" expression="/status = 'ready'"/>❺
<logger level="DEBUG" message="fetched orders: #[payload]"/> ❻
<splitter evaluator="xpath" expression="/order"/> ➐
<enricher> ❽
<authorize:authorization-and-capture amount="#[xpath:/amount]" ❾
cardNumber="#[xpath:/card/number]"
expDate="#[xpath:/card/expire]" />
<enrich target="#[variable:PaymentSuccess]" source="#[bean:responseCode]"/>
</enricher>
<message-properties-transformer scope=:invocation"> ❶❶
<add-message-property key="user-email-address" value="#[xpath:/user/email]"/>
</message-properties-transformer>
<component class="org.mycompany.OrderPreProcessor"/> ❶❷
<flow-ref name="processOrder"/> ❶❸
<smtp:outbound-endpoint subject="Your order has been processed" to="#[header:INVOCATION:user-email-address]"/> ❶❹
<default-exception-strategy> ❶❺
<processor-chain> ❶❻
<object-to-string-transformer/> ❶➐
<jms:outbound-endpoint ref="order-processing-errors"/> ❶❽
</processor-chain/>
</default-exception-strategy>
</flow>
This flow accepts and processes orders. How the flow’s configuration maps to its logic:
❶ A message is read from an HTTP listener.
❷ The message is transformed to a string.
❸ This string is used as a key to look up the list of orders in a database.
❹ The order is now converted to XML.
❺ If the order is not ready to be processed, it is skipped.
❻ The list is optionally logged, for debugging purposes.
❼ Each order in the list is split into a separate message
❽ A message enricher is used to add information to the message
❾ Authorize.net is called to authorize the order
❶❶ The email address in the order is saved for later use.
❶❷ A Java component is called to preprocess the order.
❶❸ Another flow, named processOrder
, is called to process the order.
❶❹ The confirmation returned by processOrder
is e-mailed to the address in the order.
If processing the order caused an exception, the exception strategy at ❶❺ is called:
❶❻ All the message processers in this chain are called to handle the exception
❶❼ First, the message in converted to ma string.
❶❽ Last, this string is put on a queue of errors to be manually processed.
Each step in this flow is described in more detail below, organized by construct.
Endpoints
Previously, we looked at declarations of global endpoints. Here we see endpoints in flows, where they are used to receive (inbound) and send (outbound) messages. Inbound endpoints appear only at the beginning of the flow, where they supply the message to be processed. Outbound endpoints can appear anywhere afterward. The path of a message through a flow depends upon the MEPs of its endpoints:
-
If the inbound endpoint is request-response, the flow, at its completion, returns the current message to its caller.
-
If the inbound endpoint is one-way, the flow, at its completion, simply exits.
-
When the flow comes to a request-response outbound endpoint, it sends the current message to that endpoint, waits for a response, and makes that response the current message.
-
When the flow comes to a one-way outbound endpoint, it sends the current message to that endpoint and continues to process the current message.
❶ This receives a message over an HTTP connection. The message payload is set to an array of the bytes received, while all HTTP headers become inbound message properties. Because this operation is request-response (the default for HTTP), at the end of the flow, the current message returns to the caller.
❸ This calls a JDBC query, using the current message as a parameter, and replaces the current message with the query’s result. Because this endpoint is request-response, the result of the query becomes the current message.
❶❹ The confirmation for a completed order, which was returned from the sub-flow, is e-mailed. Note that we use the email-address that had previously been saved in a message property. Because this endpoint is one-way (the only MEP for email transports), the current message does not change.
❶❽ Any orders that were not processed correctly are put on a JMS queue for manual examination. Because this endpoint is one-way (the default for JMS), the current message does not change.
Thus the message sent back to the caller will be the confirmation message, in case of success, or the same string sent to the JMS error queue in case of failure.
Transformers
As described above, transformers change the current message. There are a few examples here. Note that they are defined where used. They could also have been defined globally and referred to where used.
❷ The message, which is a byte array, is converted to a string, allowing it to be the key in a database look-up.
❹ The order read from the database is converted to an XML document.
❶❶ The email address is stored in a message property. Note that, unlike most transformers, the message-properties-transformer does not affect the message’s payload, only its properties.
❶❼ The message that caused the exception is converted to a string. Note that since the same strategy is handling all exceptions, we don’t know exactly what sort of object the message is at this point. It might be a byte array, a string, or an XML document. Converting all of these to strings allows its receiver to know what to expect.
Message Enrichment
Message enrichment is done using the enricher
element. Unlike message transformation, which alters the current message’s payload, enrichment adds additional properties to the message. This allows the flow to build up a collection of information for later processing. For more about enriching messages see Message Enricher.
❽ The enricher calls a connector to retrieve information that it stores as a message property. Because the connector is called within an enricher, its return value is processed by the enricher rather than becoming the message.
Logger
The logger
element allows debugging information to be written from the flow. For more about the logger see Logger Component Reference
❻ Each order fetched from the database is output, but only if DEBUG mode is enabled. This means that the flow is silent, but debugging can easily be enabled when required.
Filters
Filters determine whether a message is processed or not.
❺ If the status of the document fetched is not "ready", its processing is skipped.
Routers
A router changes the flow of the message. Among other possibilities, it might choose among different message processors, split one message into many, join many messages into one. For more about routers, see Routing Message Processors.
❼ Split the document retrieved from the database into multiple orders, at the XML element order
. The result is zero or more orders, each of which is processed by the rest of the flow. That is, for each HTTP message received, the flow is processed once up through the splitter. The rest of the flow might be processed zero, one, or more times, depending on how many orders the document contains.
Components
A component is a message processor written in Java, groovy, or some other language. Mule determines which method to call on a component by finding the best match to the message’s type. To help tailor this search, Mule uses objects called Entry Point Resolvers, which are configured on the component. Here are some examples of that:
<component class="org.mycompany.OrderPreProcessor"> ❶
<entry-point-resolver-set>
<method-entry-point-resolver>
<include-entry-point method="preProcessXMLOrder" />
<include-entry-point method="preProcessTextOrder" />
</method-entry-point-resolver>
<reflection-entry-point-resolver/>
</entry-point-resolver-set>
</component>
<component class="org.mycompany.OrderPreProcessor"> ❷
<property-entry-point-resolver property="methodToCall"/>
</component>
<component class="org.mycompany.generateDefaultOrder"> ❸
<no-arguments-entry-point-resolver>
<include-entry-point method="generate"/>
</no-arguments-entry-point-resolver>
</component>
❶ Causes the two methods preProcessXMLOrder
and preProcessTextOrder
to become candidates. Mule chooses between them by doing reflection, using the type of the message.
❷ Calls the method whose name is in the message property methodToCall
.
❸ Calls the generate
method, even though it takes no arguments.
Entry point resolvers are for advanced use. Almost all of the time, Mule finds the right method to call without needing special guidance.
❶❷ This is a Java component, specified by its class name, which is called with the current message. In this case, it preprocesses the message. For more about entry point resolvers, see Entry Point Resolver Configuration Reference.
Anypoint Connectors
An Anypoint connector calls a cloud service.
❾ Calls authorize.net to authorize a credit card purchase, passing it information from the message. For more about connectors, see Anypoint Connectors.
Processor Chain
A processor chain is a list of message processors, which will be executed in order. It allows you to use more than one processor where a configuration otherwise allows only one, exactly like putting a list of Java statements between curly braces.
❶❻ Performs two steps as part of the exception strategy. It first transforms and then mails the current message.
Sub-flow
A sub-flow is a flow that can be called from another flow. It represents a reusable processing step. Calling it is much like calling a Java method – the sub-flow is passed the current message, and when it returns the calling flow resumes processing with the message that the sub-flow returns.
❶❸ Calls a flow to process an order that has already been pre-processed and returns a confirmation message.
Exception Strategies
An exception strategy is called whenever an exception occurs in its scope, much like an exception handler in Java. It can define what to do with any pending transactions and whether the exception is fatal for the flow, as well as logic for handling the exception.
❶❺ Writes the message that caused the exception to a JMS queue, where it can be examined. For more about exception strategies, see Error Handling.
Configuration Patterns
Flows have the advantages of being powerful and flexible. Anything that Mule can do can be put into a flow. Mule also comes with configuration patterns, each of which is designed to simplify a common use of Mule. It’s worthwhile to become familiar with the patterns and use them when possible, for the same reasons that you would use a library class rather than build the same functionality from scratch. There are currently four configuration patterns:
-
pattern:bridge
bridges between an inbound endpoint and an outbound endpoint -
pattern:simple-service
is a simple flow from one inbound endpoint to one component -
pattern:validator
is like a one-way bridge, except that it validates the message before sending it to the outbound endpoint -
pattern:web-service-proxy
is a proxy for a web service.
As of mule 3.1.1, all are in the pattern namespace as shown. In earlier Mule 3 releases, they are in the core namespace, except for web-service-proxy which is ws:proxy
. These older names will continue to work for the Mule 3.1.x releases, but will be removed after that.
Common Features
For flexibility, all of the patterns allow endpoints to be specified in a variety of ways:
-
Local endpoints can be declared as sub-elements, as in flow
-
References to global elements can be declared as sub-elements, as in flow
-
References to global elements can be declared as values of the attributes
inboundEndpoint-ref
andoutboundEndpoint-ref
-
The endpoint’s address can be given as the value of the attributes
inboundAddress
andoutboundAddress
All configuration patterns can specify exception strategies, just as flows can.
Bridge
The allows you to configure, in addition to the inbound and outbound endpoints
-
A list of transformers to be applied to requests
-
A list of transformers to be applied to responses
-
Whether to process messages in a transaction.
Examples:
<pattern:bridge name="queue-to-topic" ❶
transacted="true"
inboundAddress="jms://myQueue"
outboundAddress="jms://topic:myTopic" />
<pattern:bridge name="transforming-bridge" ❷
inboundAddress="vm://transforming-bridge.in"
transformer-refs="byte-array-to-string"
responseTransformer-refs="string-to-byte-array"
outboundAddress="vm://echo-service.in" />
❶ Copies messages from a JMS queue to a JMS topic, using a transaction. ❷ reads byte arrays from an inbound vm endpoint, transforms them to strings, and writes them to an outbound vm endpoint. The responses are strings, which are transformed to byte arrays, and then written to the outbound endpoint.
Simple Service
This allows you to configure, in addition to the inbound endpoint
-
A list of transformers to be applied to requests
-
A list of transformers to be applied to responses
-
A component
-
A component type, which allows you to use Jersey and CXF components.
Here are some examples:
<pattern:simple-service name="echo-service" ❶
endpoint-ref="echo-service-channel"
component-class="com.mycompany.EchoComponent" />
<pattern:simple-service name="weather-forecaster-ws" ❷
address="http://localhost:6099/weather-forecast"
component-class="com.myompany.WeatherForecaster"
type="jax-ws" />
❶ Is a simple service that echos requests. ❷ is a simple web service that uses a CXF component. Note how little configuration is required to create them.
Validator
This allows you to configure, in addition to the inbound and outbound endpoints
-
A list of transformers to be applied to requests
-
A list of transformers to be applied to responses
-
A filter to perform the validation
-
Expressions to create responses to indicate that the validation succeeded or failed
Example:
<pattern:validator name="validator" ❶
inboundAddress="vm://services/orders"
ackExpression="#[string:OK]"
nackExpression="#[string:illegal payload type]"
outboundAddress="vm://OrderService">❷
<payload-type-filter expectedType="com.mycompany.Order"/>
</pattern:validator>
❶ Validates that the payload is of the correct type before calling the order service, using the filter at ❷.
Web service proxy
This creates a proxy for a web service. It modifies the advertised WSDL to contain the proxy’s URL.
This allows you to configure, in addition to the inbound and outbound endpoints:
-
A list of transformers to be applied to requests
-
A list of transformers to be applied to responses
-
The location of the service’s WSDL, either as a URL or as a file name.
Example:
<pattern:web-service-proxy name="weather-forecast-ws-proxy"
inboundAddress="http://localhost:8090/weather-forecast"
outboundAddress="http://server1:6090/weather-forecast"
wsdlLocation="http://server1:6090/weather-forecast?wsdl" />
This creates a proxy for the weather forecasting service located on server1.
Custom Elements
Mule is extensible, meaning that you can create your own objects (often by extending Mule classes). After you’ve done this, there are standard ways to place them into the configuration. Assume, for instance, that you’ve created com.mycompany.HTMLCreator"
, which converts a large variety of document types to HTML. It should be a Spring bean, meaning
-
It has a default constructor
-
It is customized by setting bean properties
You can now put it into your configuration using the custom-transformer
element:
<custom-transformer mimeType="text/html" returnType="java.lang.String" class="com.mycompany.HTMLCreator">
<spring:property name="level" value="HTML5"/>
<spring:property name="browser" value="Firefox"/>
</custom-transformer>
Note that the standard Mule properties for a transformer are specified the usual way. The only differences are that the object itself is created via its class name and Spring properties rather than via schema-defined elements and attributes. Each type of Mule object has an element used for custom extensions:
-
custom-connector for connectors
-
custom-entry-point-resolver for entry point resolvers
-
custom-exception-strategy for exception strategies
-
custom-filter for filters
-
custom-processor for message processors
-
custom-router for routers
-
custom-transformer for transformers
System-level Configuration
The configuration contains several global settings that affect the entire mule application. All are children of the configuration
element, which itself is a top-level child of mule
. They fall into two groups: threading profiles and timeouts.
Threading Profiles
Threading profiles determine how Mule manages its thread pools. In most cases the default will perform well, but if you determine that, for instance, your endpoints are receiving so much traffic that they need additional threads to process all of it, you can adjust this, either for selected endpoints or, by changing the default, for all endpoints. The defaults that can be adjusted – and their corresponding elements – are:
-
default-threading-profile
for all thread pools -
default-dispatcher-threading-profile
for the thread pools used to dispatch (send) messages -
default-receiver-threading-profile
for the thread pools used to receive messages
Timeouts
Again, the default timeouts will usually perform well, but if you want to adjust them, you can do so either per use or globally. The timeouts that can be adjusted and their corresponding attributes are:
-
defaultResponseTimeout
How long, in milliseconds, to wait for a synchronous response. The default is 10 seconds. -
defaultTransactionTimeout
How long, in milliseconds, to wait for a transaction to complete. The default is 30 seconds. -
shutdownTimeout
How long, in milliseconds, to wait for Mule to shut down gracefully. The default is 5 seconds.
Managers
There are several global objects used to manage system-level facilities used by Mule. They are discussed below.
Transaction manager
Mule uses JTA to manage XA transactions; thus, to use XA transactions, a JTA transaction manager is required, and must be specified in the configuration. Mule has explicit configuration for many of these, and, as usual, also allows you to specify a custom manager. The element used to specify a transaction manager is a direct child of mule
.
-
websphere-transaction-manager
for the WebSphere transaction manager -
jboss-transaction-manager
for the JBoss transaction manager -
*
weblogic-transaction-manager
for the WebLogic transaction manager -
jrun-transaction-manager
for the JRun transaction manager -
resin-transaction-manager
for the Resin transaction manager -
*
jndi-transaction-manager
to look up a transaction manager in JNDI -
*
custom-transaction-manager
for a custom lookup of the transaction manager
The starred transaction managers allow you to configure a JNDI environment before performing the lookup. For more about transaction managers, see Transaction Management.
Security Manager
The Mule security manager can be configured with one or more encryption strategies that can then be used by encryption transformers, security filters, or secure transports such as SSL or HTTPS. These encryption strategies can greatly simplify configuration for secure messaging as they can be shared across components. This security manager is set with the global security-manager
element, which is a direct child of mule
.
For example, here is an example of a password-based encryption strategy (PBE) that provides password-based encryption using JCE. Users must specify a password and optionally a salt and iteration count as well. The default algorithm is PBEWithMD5AndDES, but users can specify any valid algorithm supported by JCE.
<security-manager>
<password-encryption-strategy name="PBE" password="mule"/>
</security-manager>
This strategy can then be referenced by other components in the system such as filters or transformers.
<decrypt-transformer name="EncryptedToByteArray" strategy-ref="PBE"/>
<flow name="testOrderService">
<inbound-endpoint address="vm://test">
<encryption-security-filter strategy-ref="PBE"/>
</inbound-endpoint>
...
</flow>
For more about Mule security, see Configuring Security.
Notifications Manager
Mule can generate notifications whenever a message is sent, received, or processed. For these notifications to actually be created and sent, objects must register to receive them. This is done via the global\{{notifications}} element, which is a direct child of mule. It allows you to specify an object to receive notifications as well as specify which notifications to send it. Note that an object will only receive notifications for which it implements the correct interface (these interfaces are defined in the org.mule.api.context.notification
package.) Here is an example:
<spring:bean name="componentNotificationLogger" ❶
class="org.myfirm.ComponentMessageNotificationLogger"/>
<spring:bean name="endpointNotificationLogger" ❷
class="org.myfirm.EndpointMessageNotificationLogger"/>
<notifications> ❸
<notification event="COMPONENT-MESSAGE"/>
<notification event="ENDPOINT-MESSAGE"/>
<notification-listener ref="componentNotificationLogger"/>
<notification-listener ref="endpointNotificationLogger"/>
</notifications>
Assume that ComponentMessageNotificationLogger
implements the ComponentMessageNotificationListener
interface and EndpointMessageNotificationLogger
implements EndpointMessageNotificationListener
.
❶ and ❷ create the listener beans. ❸ appears to register both beans for both component and endpoint notifications. But since ComponentMessageNotificationLogger
only implements the interface for component notification, those are all it will receive (and likewise for EndpointMessageNotificationLogger
.
For more about notifications, see Notifications Configuration Reference.
Agents
Mule allows you to define Agents to extend the functionality of Mule. Mule will manage the agents' lifecycle (initialize them and start them on startup, and stop them and dispose of them on sutdown). These agents can do virtually anything; the only requirement is that they implement org.mule.api.agent.Agent
, which allows Mule to manage them. For more about Mule agents, see Mule Agents.
Custom Agents
To create a custom agent, simply declare it using the global custom-agent
element, which is a direct child of mule
. The agent is a Spring bean, so as usual it requires a class name and a set of Spring properties to configure it. In addition it requires a name, which Mule uses to identify it in logging output. Here’s an example:
<custom-agent name="heartbeat-agent" class="com.mycompany.HeartbeatProvider">
<spring:property name="frequency" value="30"/>
<custom-agent>
This creates an agent that issues a heartbeat signal every 30 seconds. Since Mule will start it and stop it, the heartbeat is present precisely when the Mule server is running.
Management Agents
Mule implements various management agents in the management namespace.
-
management:jmx-server
creates a JMX server that allows local or remote access to Mule’s JMX beans -
management:jmx-mx4j-adaptor
creates a service that allows HTTP access to the JMX beans -
management:rmi-server
creates a service that allows RMI access to the JMX beans -
management:jmx-notifications
creates an agent that propagates Mule notifications to JMX -
management:jmx-log4j
allows JMX to manage Mule’s use of Log4J -
management:jmx-default-config
allows creating all of the above at once -
management:log4j-notifications
creates an agent that propagates Mule notifications to Log4J -
management:chainsaw-notifications
creates an agent that propagates Mule notifications to Chainsaw -
management:publish-notifications
creates an agent that publishes Mule notifications to a Mule outbound endpoint -
management:yourkit-profiler
creates an agent that exposes YourKit profiling information to JMX