Nav
You are viewing an older version of this section. Click here to navigate to the latest version.

Understanding Mule Configuration

Mule XML Configuration File

Mule runtime uses an XML file to define the constructs required to validate and run a Mule application.

A developer can configure a basic Mule application by writing a simple configuration XML file, for instance:


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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/current/mule-stdio.xsd
        http://www.mulesoft.org/schema/mule/core  http://www.mulesoft.org/schema/mule/core/current/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>

In this document we examine all the pieces of this configuration in detail. Note that this is a simple, yet complete application, and has the additional benefit of being readable: even a brief acquaintance with Mule makes it clear that this application copies messages from standard input to standard output.

For more detail see About the XML Configuration File.

How Mule Syntax is Defined Using Schemas

The syntax of Mule configurations is defined by a set of XML schemas. Each configuration lists the schemas it uses and provides their designated URLs. The majority of these are the Mule schemas for the version of Mule being used. 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.

In addition, there might be third-party schemas to reference, 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.

The configuration file 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 below:

          
       
1
2
3
4
5
6
<mule xmlns="http://www.mulesoft.org/schema/mule/core" (1)
      xmlns:stdio="http://www.mulesoft.org/schema/mule/stdio" (2)
      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/current/mule-stdio.xsd (3)
        http://www.mulesoft.org/schema/mule/core  http://www.mulesoft.org/schema/mule/core/current/mule.xsd"> (4)
1 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
2 Shows the namespace for Mule’s stdio transport, which allows communication using standard I/O. It has the prefix "stdio". The convention for a Mule module or transport’s schema is to use its name as the prefix.
The xsi:schemaLocation attribute associates schemas' namespaces with their locations.
3 The location for the Mule stdio schema.
4 The last line provides the location for the Mule core schema.

A Mule application’s configuration file must contain the aforementioned pieces as shown. In this way, the schemas can be found, and the application’s configuration can be validated against them.

Defining Default Values Using Schemas

Besides defining the syntax of various elements and attributes, schemas can also define default values. Knowing these can be extremely useful in making your configurations readable, since thy don’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. For example, the definitions of the <poll> element, which polls an endpoint repeatedly, contains the following attribute definition:


          
       
1
2
3
4
5
6
<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.

Defining Enumerated Values in Schemas

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:


          
       
1
2
3
4
5
6
7
8
9
<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 look at Spring in more detail in the following sections. Note that, as always, it is 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 in 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:


          
       
1
2
3
4
5
<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:


          
       
1
2
3
4
5
6
7
8
9
<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:


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
<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:


          
       
1
2
3
4
5
6
7
8
9
10
11
12
<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:


          
       
1
2
3
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:


           
        
1
2
3
4
5
6
<vm:connector name="persistentConnector"> (1)
  <vm:queueProfile persistent="true" />
</vm:connector>
 
<file:connector name="fileConnector" (2)
                pollingFrequency="1000" moveToDirectory="/tmp/test-data/out" />
1 The vm connector specifies that all of its endpoints use persistent queues.
2 The file connector specifies that each of its endpoints be polled once a second, and also the directory that files are 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 occurs 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 to create the message.

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:


           
        
1
2
3
<vm:endpoint name="in" address="vm://in" connector-ref="persistentConnector" /> (1)
 
<endpoint name="inFiles" address="file://c:/Orders" /> (2)

The vm endpoint in <1> specifies its location and refers to the connector shown above. It uses the generic address attribute to specify its location. The file endpoint at <2> 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. (<1>)

  • If not, the prefix is determined from the element’s address attribute. (<2>)

The prefix style is preferred, particularly when the location is complex. 


           
        
1
<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), 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:


           
        
1
2
3
4
5
6
7
8
9
<json:json-to-object-transformer (1)
      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"> (2)
  <add-message-property key="processed" value="yes" />
</message-properties-transformer>

The transformer at <1> converts the current message to JSON, specifying special handling for the conversion of the org.mule.tck.testmodels.fruit.Orange class. The transformer at <2> 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:


           
        
1
2
3
<wildcard-filter pattern="* header received"/> (1)
 
<mxml:is-xml-filter/> (2)

The filter at <1> continues processing of the current message only if it matches the specified pattern. The filter at <2> 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:


           
        
1
2
3
4
5
6
7
<message-filter onUnaccepted="deadLetterQueue"> (1)
  <wildcard-filter pattern="* header received"/>
</message-filter>
 
<message-filter throwOnUnaccepted="true"> (2)
  <mxml:is-xml-filter/>
</message-filter>

As above, <1> 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. <2> 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:


           
        
1
2
3
4
5
6
7
8
9
<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 information, see 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 or outbound-endpoint elements.

  • All global filters are referred to by the filter element.

For example


           
        
1
2
3
4
5
6
7
8
9
10
11
<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 refer to as we examine its parts:


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<http:listener-config name="listener-config" host="localhost" port="8081" 
   doc:name="HTTP Listener Configuration"/> (1)
<flow name="acceptAndProcessOrder">
<http:listener config-ref="listener-config" path="/" doc:name="HTTP Connector"/>
  <byte-array-to-string-transformer/> (2)
  <jdbc:outbound-endpoint ref="getOrdersById" exchange-pattern="request-response"/> (3)
  <mxml:object-to-xml-transformer/> (4)
  <expression-filter evaluator="xpath" expression="/status = 'ready'"/> (5)
  <logger level="DEBUG" message="fetched orders: #[payload]"/> (6)
  <splitter evaluator="xpath" expression="/order"/> (7)
 
  <enricher> (8)
    <authorize:authorization-and-capture amount="#[xpath:/amount]" (9)
              cardNumber="#[xpath:/card/number]"
              expDate="#[xpath:/card/expire]" />
    <enrich target="#[variable:PaymentSuccess]" source="#[bean:responseCode]"/>
  </enricher>
  <message-properties-transformer scope=:invocation"> (10)
    <add-message-property key="user-email-address" value="#[xpath:/user/email]"/>
  </message-properties-transformer>
  <component class="org.mycompany.OrderPreProcessor"/>  (11)
  <flow-ref name="processOrder"/> (12)
  <smtp:outbound-endpoint subject="Your order has been processed" 
   to="#[header:INVOCATION:user-email-address]"/> (13)
 
  <default-exception-strategy> (14)
    <processor-chain> (15)
      <object-to-string-transformer/> (16)
      <jms:outbound-endpoint ref="order-processing-errors"/> (17)
    </processor-chain/>
  </default-exception-strategy>
</flow>

This flow accepts and processes orders. How the flow’s configuration maps to its logic:

1 A message is read from an HTTP listener.
2 The message is transformed to a string.
3 This string is used as a key to look up the list of orders in a database.
4 The order is now converted to XML.
5 If the order is not ready to be processed, it is skipped.
6 The list is optionally logged, for debugging purposes.
7 Each order in the list is split into a separate message.
8 A message enricher is used to add information to the message.
9 Authorize.net is called to authorize the order.
10 The email address in the order is saved for later use.
11 A Java component is called to preprocess the order.
12 Another flow, named processOrder, is called to process the order.
13 The confirmation returned by processOrder is e-mailed to the address in the order.
14 If processing the order caused an exception, the exception strategy is called.
15 All the message processers in this chain are called to handle the exception.
16 First, the message in converted to ma string.
17 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 message exchange pattern (MEP) 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.

In #1 in Flows, the example 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.

In #3 in Flows, the example 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.

In #13 in Flows, the example gets 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.

In #17 in Flows, 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 is 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.

In #2 in Flows, the message, which is a byte array, is converted to a string, allowing it to be the key in a database look-up.
In #4 in Flows, the order read from the database is converted to an XML document.
In #10 in Flows, 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.
In #16 in Flows, 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.

In #8 in Flows, 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

In #6 in Flows, 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.

In #5 in Flows, 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.

In #7 in Flows, 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:


           
        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<component class="org.mycompany.OrderPreProcessor"> (1)
<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"> (2)
  <property-entry-point-resolver property="methodToCall"/>
</component>
 
<component class="org.mycompany.generateDefaultOrder"> (3)
  <no-arguments-entry-point-resolver>
    <include-entry-point method="generate"/>
  </no-arguments-entry-point-resolver>
</component>
1 Causes the two methods preProcessXMLOrder and preProcessTextOrder to become candidates. Mule chooses between them by doing reflection, using the type of the message.
2 Calls the method whose name is in the message property methodToCall.
3 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.

1 and <2> are Java components, specified by each’s 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.

In #9 in Flows, the example 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 that execute in order. The chain 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.

In #15 in Flows, the example 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.

In #12 in Flows, the example 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.

In #14 in Flows, the example 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.

All are in the pattern namespace as shown.

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 and outboundEndpoint-ref

  • The endpoint’s address can be given as the value of the attributes inboundAddress and outboundAddress

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:


           
        
1
2
3
4
5
6
7
8
9
10
<pattern:bridge name="queue-to-topic" (1)
        transacted="true"
        inboundAddress="jms://myQueue"
        outboundAddress="jms://topic:myTopic" />
 
<pattern:bridge name="transforming-bridge" (2)
        inboundAddress="vm://transforming-bridge.in"
        transformer-refs="byte-array-to-string"
        responseTransformer-refs="string-to-byte-array"
        outboundAddress="vm://echo-service.in" />
1 Copies messages from a JMS queue to a JMS topic, using a transaction.
2 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:


           
        
1
2
3
4
5
6
7
8
<pattern:simple-service name="echo-service" (1)
                endpoint-ref="echo-service-channel"
                component-class="com.mycompany.EchoComponent" />
 
<pattern:simple-service name="weather-forecaster-ws" (2)
                address="http://localhost:6099/weather-forecast"
                component-class="com.myompany.WeatherForecaster"
                type="jax-ws" />
1 Is a simple service that echos requests.
2 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:


           
        
1
2
3
4
5
6
7
<pattern:validator name="validator" (1)
           inboundAddress="vm://services/orders"
           ackExpression="#[string:OK]"
           nackExpression="#[string:illegal payload type]"
           outboundAddress="vm://OrderService"> (2)
  <payload-type-filter expectedType="com.mycompany.Order"/>
</pattern:validator>
1 Validates that the payload is of the correct type before calling the order service.
2 Uses the filter.

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:


           
        
1
2
3
4
<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.

For more about configuration patterns, see Using Mule Configuration Patterns.

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:


          
       
1
2
3
4
<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 performs well, but if you determine that, for instance, your endpoints are receiving so much traffic that they need additional threads to process all of the traffic, 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 usually performs 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.


           
        
1
2
3
<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.


           
        
1
2
3
4
5
6
7
8
<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 only receives notifications for which it implements the correct interface (these interfaces are defined in the org.mule.api.context.notification package.)

Here is an example. Assume that ComponentMessageNotificationLogger implements the ComponentMessageNotificationListener interface and EndpointMessageNotificationLogger implements EndpointMessageNotificationListener.


           
        
1
2
3
4
5
6
7
8
9
10
11
12
<spring:bean name="componentNotificationLogger" (1)
             class="org.myfirm.ComponentMessageNotificationLogger"/>
 
<spring:bean name="endpointNotificationLogger" (2)
             class="org.myfirm.EndpointMessageNotificationLogger"/>
 
<notifications> (3)
  <notification event="COMPONENT-MESSAGE"/>
  <notification event="ENDPOINT-MESSAGE"/>
  <notification-listener ref="componentNotificationLogger"/>
  <notification-listener ref="endpointNotificationLogger"/>
</notifications>
1 Creates a listener beans.
2 Creates another listener bean.
3 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 receives (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 manages the agents' lifecycle (initializes them and starts them on startup, and stops them and disposes of them on shutdown). 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:


           
        
1
2
3
<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 starts it and stops 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-log4j2 allows JMX to manage Mule’s use of Log4j2.

  • management:jmx-default-config allows creating all of the above at once.

  • management:log4j2-notifications creates an agent that propagates Mule notifications to Log4j2.

  • 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.