Using Flows for Service Orchestration
A Flow is a simple yet very flexible mechanism that enables orchestration of services using the sophisticated message flow capabilities of Mule ESB. Using Flow, you may automate integration processes and construct sophisticated integration solutions by simply building them from the connectors provided by Mule. Because of the flexibility of Flow, it is much easier to create solutions that more closely match your requirements. Flow is new in Mule 3.
|A flow is the most versatile and powerful integration mechanism available in Mule.|
Flows are valuable in many situations, including:
Simple integration tasks
Scheduled data processing
Connecting cloud and on-premise applications
Event processing where multiple services need to be composed
A flow is in essence just a chain of Message Processors. Think of each Message Processor as a Lego block where a Flow is something you build with them. A flow also has a message source, the source of messages that are processed by the Message Processor chain.
A Flow is configured in XML using the <flow> element. Each flow has a name attribute, a message source (unless it’s a private flow), one or more message processors and an optional exception strategy.
1 2 3 4 5 <flow name=""> - 0..1 MessageSource - 1..n MessageProcessor(s) - 0..1 ExceptionStrategy </flow>
Flows seem simple, yet can be quite powerful. In particular, when combined with expressions in Mule, they can allow for very sophisticated processing of the message contents. There are many elements that leverage expressions, including:
Simple Book Order Processing Flow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <flow> <file:inbound-endpoint path="/myDirectory"> <file:filename-filter name="*.xml"/> </file:inbound-endpoint> <xml:xslt-transformer xsl-file="bookOrderTransformation.xsl"/> <splitter expression="xpath://order"/> <!-- The following message processors will be invoked for each order in the xml file --> <expression-filter expression="xpath://order[@type='book']"/> <component class="org.my.BookOrderProcessor"/> <smtp:outbound-endpoint subject="Order Confirmation" address=""/> <jdbc:outbound-endpoint /> <default-exception-strategy> <jms:outbound-endpoint queue="failedOrders"/> </default-exception-strategy> </flow>
When a message is received or generated by the message source the flow is started and the configured message processors are invoked in a chain in the same order as they are configured. Some message processors accept child message processor elements, in this case these are processed before returning and continuing processing the main list.
The above describes the behavior when the flow is one-way. If the flow is request-response because an inbound endpoint as a request-response exchange pattern defined then the result of the flow execution is return to the inbound endpoint and then in turn to the callee. If there are no <response> blocks in your flow and if none of the configured message processors perform any response processing then the response used is simply the result from the last Message Processor in the flow. If a <response> block is used, then any message processors configured in this element are used to process the response message. Some message processors such as CXF perform processing of the response message as part of their default configuration.
Note: When the last element in the flow configuration is a one-way <outbound-endpoint> there’s no result of it’s execution so the returned payload of the message is going to be NullPayload. If the one-way <outbound-endpoint> is followed by another processor, it receives as input the same message that the outbound-endpoint receives instead of NullPayload.
A private flow is one that cannot be accessed from outside the JVM via a Mule Endpoint because it has no message source defined.
Private Flows are therefore only used if they are referenced from another construct running in the same Mule instance. When configuring Mule using XML the <flow-ref> element is used to include one flow in another.
A private Flow differs from the use of a "Processor Chain" in that a Flow has it’s own context and exception strategy where as when a processor chain is referenced, it is executed in the context of the flow that references it.
Private Flow Example
1 2 3 4 5 6 7 8 9 10 <flow name="privateFlow"> <append-string-transformer message="b"/> </flow> <flow name="publicFlow"> <http:inbound-endpoint address="http://localhost:8080"/> <append-string-transformer message="a"/> <flow-ref name="privateFlow"/> <append-string-transformer message="c"/> </flow>
You can read more about the reason we added Flow for Mule 3 in the following blog posts:
Mule 3 Architecture, Part 1: Back to Basics
Mule 3 Architecture, Part 2: Introducing the Message Processor