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 basic Message Sources and Message Processors 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.|
In contrast to the use of Services, which define a component with explicit inbound and outbound phases that allow a limited amount of flexibility, a Flow does not define anything and is completely free-form. This means that if your solution requires multiple steps you won’t need to use multiple services glued together with the vm transport or a chaining router. Instead you’ll be able to configure everything in the same flow.
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
Before you create flows be sure to take a look at the ready-to-use configuration patterns. They can save you a great amount of configuration effort for common use cases.
You still may choose to use Services in some cases. For example, if all you wish to do is expose a single service backed by a service component and your requirements are more complex than Simple Service supports, then a Mule Service is still a good choice. Existing Mule services can also be easily integrated into a flow. Finally, flows do not yet support all features of Mule. In particular, services are still required if you want to do any of the following:
Transactions configured anywhere other than on endpoints e.g. on routers (including local, multi-tx, and XA)
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 will accept child message processor elements, in this case these will be 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 will be used to process the response message. Some message processors (e.g. 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 will receive as input the same message that the outbound-endpoint received instead of NullPayload.
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 or service 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: