The Content Enricher is a useful content transformation pattern that elaborates a basic message with information from another system. A typical use case is described in the seminal work on integration patterns: Enterprise Integration Patterns, Gregor Hohpe and Bobby Woolf. Addison-Wesley Professional; October 20, 2003. It describes a scenario where one system may provide a customer ID, but the target system requires the customer name and address. This additional information must be retrieved from another system and combined with the customer ID to form the information required by the target system.
How to implement the Enricher pattern in Mule 3
In Mule 3, we translate this to the following:
- The flow receives a payload containing the basic message.
- We want to keep the payload in its current format, but we need to add some extra information to it, without losing its current content.
- However, if we call another Event processor, such as an http:request or a flow-ref (that retrieves extra information about the employee) the existing payload will be overridden with this extra information.
- The problem is how to keep our existing payload while calling out to another processor and storing the result without overwriting our existing payload.
Let’s start by looking at how the enricher content transformation pattern is implemented in Mule 3. We will use a basic message that contains only an employee ID and name and a target system that requires the addition of a role and location.
The input payload provides just the employee’s name and id, and we want to enrich this information with the employee’s role and location that is persisted in a different system.
{ "id": "001", "name": "Max Mule" }
Figure 1: Input payload.
The flow needs to call another processor for this additional information. When this call is made we want to keep the input payload and enrich it with the result of the call to the other system.
The component that achieves this is the Enricher, it calls another system and stores the resulting payload as a flow variable, ensuring that the input payload is not overridden. This flow variable is accessible in the flow and, with the help of the DataWeave transformer, the input payload and the flow variable can be combined to create the required enhanced message.
{ "id": "001", "name": "Max Mule", "role": "Mule Guru", "location": "Wherever a system needs integration" }
Figure 2: Expected enhanced message.
Mule 3 Enricher Flow
The Set Payload component sets the payload to the JSON shown in figure 1 above.
The Enricher component calls an external system (simulated by calling the subflow resource-system) and sets the returning payload to the flow variable configured in the component — in this case, flowVars.employee. It’s worth noting that the target variable can also be a session variable and be defined like so: sessionVars.employee.
The subflow sets the payload to the JSON shown in figure 2.
The DataWeave component aggregates data from the input payload and the employee flow variable to produce the required enhanced message.
%dw 1.0 %output application/json --- { id: payload.id, name: payload.name, role: flowVars.employee.role, location: flowVars.employee.location }
The console output for the two loggers shows that the input payload remains untouched because the data from the external system is stored as a flow variable.
Input payload: {name=Max Mule, id=001} Enricher flow variable: {location=Where ever a system needs integration, role=Mule Guru, id=001}
You can find the full code source here.
Mule 4 Enricher Flow
In Mule 4 the enricher scope has been removed. To replace it, almost every Event processor comes with the optional attributes: target and targetValue.
The target attribute specifies the name of the variable into which the targetValue will be stored.
The targetValue attribute specifies what data gets stored in the target variable. By default, it will be the payload of the event processor, however, this can be customized with a DataWeave expression that selects a specific field from within the payload returned by the processor.
In the above example, it references the resource-system private flow and sets the target variable to employee and the target value to the payload returned. The configuration of this is shown in the screenshot below.
You will notice that in Mule 4, there is no need to prepend the variable with vars (in Mule 3 variables could have either flow scoped or session scoped and it was, therefore, necessary to prefix variable names with either flowVars or sessionVars) this is because there is only one type of variable in Mule 4.
The DataWeave transformer is employed to enrich the original message with the data returned by the call to the resource system.
%dw 2.0 output application/json --- { id: payload.id, name: payload.name, role: vars.employee.role, location: vars.employee.location }
The original payload remains intact and the enhancement data is referenced by vars.employee.
You can find the full code source here.
Conclusion
So as you can see enrichment is far simpler to implement in Mule 4. There is no need for the verbose enricher scope, you can use the new target and targetValue attributes on any Event processors, with the added bonus that there is no need to specify the variable type.
For more information see the full code source examples for both the Mule 3 and Mule 4 examples.