Trying to understand when to use Message Enricher in Mule? Can someone explains with real usage would be great. I already gone through mule documentation examples
Mule message enricher is best used in the case when you do not to lose your existing payload.
For example, let's consider, you need to call a DB in the middle of the flow and by doing this you will loose your current payload with the data from the DB and you don't want this to happen.
So, here you need your DB component wrapped with message enricher. By doing that you will get the data from DB as well as you will not lose your existing current payload.
<enricher target="#[flowVars.recordFound]" doc:name="Message Enricher">
<db:select config-ref="Derby_Configuration1" doc:name="DB_Details">
<db:parameterized-query><![CDATA[select * from Table1]]></db:parameterized-query>
</db:select>
</enricher>
Since message enricher takes a copy of the current payload, your existing payload will not lost
For more idea you can refer here:- http://www.slideshare.net/anir37/mule-message-enricher
Message Enricher will be used to store the data and to check that data in future processing like if you have to do batch processing so that it has to check the data whether present or not in first batch, if not we can insert that data in second batch.
It is like enrich the message which does not have in source system.
One common scenario involves the need to enrich an incoming message with information that isn’t provided by the source system. You can use a content enricher if the target system needs more information than the source system can provide.
Consider a message from a source system contains a zip code but the target system needs the two letter state. A message enricher can be used to lookup the state using the zip code from an enrichment resource. The enricher calls out to the enrichment resource with the current message (containing the zip code) then enriches the current message with the result.
This is a very simple flow with one-way inbound and outbound endpoints, and which acts as part of an order processing pipeline. This flow uses an enricher to add a state flow variable to the current message with the state that the stateLookup endpoint returns. The ‘target’ attribute defines how the current message is enriched using a MessageEnricher which uses the same syntax as expression evaluators.
Mule Enricher is a component, whole idea of using an enricher is to maintain the payload transaction intact and use it's content to apply some logic and store the result in a variable.
e.g. can be a xml payload, used to derive a complex logic result like discount calculation and then result of it can be stored in a variable and can be used further.
To add to these answers, you may also set the returning message (e.g. payload) to either payload, flow variables and outbound properties by simply defining the source and target within the Message Enricher.
The main purpose of the Message Enricher in Mule is to carry the same payload even after calling another flow by using flow reference.
Use Case: If you wanna use the same payload data through out the flow then you should go for Message Enricher
As you can see in the attached screenshot, here I have two flow references one is under Message Enricher i.e the Message Enricher flow reference will prevent the payload to be overridden by the payload from the referenced flow(overridenFlow), the original payload is maintained so that it can be used further
enter image description here
After second flow reference the payload is overridden and original payload can't be accessed further.
Message enricher is mainly used to extract something(eg. xpath) from payload and store it into flow/session variable, without actually changing the payload.
More advantages:
1) The source can be anything(i.e. payload, variables etc)
2) The source can also be modified to be able to extract info from it.
3) Multiple sources and target option is also available.
Also, as only one component can reside inside Message Enricher. Use of processor chain is recommended if more components are needed to reside inside Message Enricher.
Message Enricher in Mule is used to carry the same payload even after calling another flow by using flow reference.
Example use case: If you are taking data from some SaaS application and then want to store that data in Database, such that there is no duplicate entry in the Database. In this case you can check for Duplicate Data with the help of message Enricher before inserting it into Database.
Message enricher is one of the important components with Mulesoft. There are various scenarios in which you can use the message enricher component.
When synchronizing data between data sources, you often check to see if a record already exists in the target resource.
If you simply add an endpoint to query the target resource first before adding it, the response will become the payload. This is not what you want!
You want the external call to act as an enrichment of the existing message with the original payload retained.
Message Enricher in Mule is used to carry the same payload even after calling another flow by using flow reference.
Related
I have common scenario but I am not able to figure out the solution in Mule 4 batch. In my flow I have a http listner which invokes the flow and then I am calling DB select and then using a batch to upsert data into salesforce.
by default batch will create stats in On-Complete phase and my requirement is to send exact stats as response but I am not able to access it outside of batch. Tried with vars, attributes and even tried VM publish (in this case response will not go back to listner)
Can someone please guide me on this? I'm attaching the flow design for reference.
flow design
Thanks.
You can't. Batch works in the background, your flow will be long gone before your batch is done.
My suggestion is you (1) Store the reporting data somewhere and (2) get to the data using another request/way.
Here's the documentation: https://docs.mulesoft.com/mule-runtime/4.2/batch-processing-concept
You can store the payload in on-complete phase in an objectStore and can retrieve it later to build your report. The payload stored in the on-complete phase is a java object that has properties that you would need to build your report. (For e.g.loadedRecords, failedRecords etc)..
I am using Mule 4 and Anypoint 7.
In my flow I want to insert records into a database but still keep the original payload in the message.
Previously I would have placed the database connector into an enricher scope so that the original payload is not replaced after the database action has completed.
How can I do this using Mule 4?
I do have the alternative of saving the payload as a variable and then use set payload after the database action but there are a few different database actions and thought the enricher scope made the flow look cleaner so just wanted to see if the functionality was still there somewhere.
Thanks
As you've seen, Enrichers are no longer a scope in Mule 4. We need to use Targets now to achieve similar functionality. Go to the 'Advanced' tab of the Insert configuration and in the Output section specify the 'Target Variable' and 'Target Value'. This provides the same functionality as an enricher.
We are programming a MULE REST service which is divided in several layers.
The API layer (RAML-based) receives the inbound requests and prepares some flowVars so that the lower layers know how to proceed.
The second layer is also service defined, so there's one flow for each service oferred.
Finally, the third layer contains a unique flow and is the one which, depending on the flowVars configured in the upper layer, carries out a call using a HTTP Request component to the third-party service needed.
In this third layer, some audit registers are made in order to know what we are sending and what we are receiving. So, our audit component (a custom MULE connector) needs to write the content of the payload to our database, so a message.getPayloadAsString() (or similar) is needed. If we use a clean getter (like message.getPayload()), only the data type is obtained and thus written into the database.
The problem lays right in here. Every single payload received seems to be a BufferInputStream and, when doing the message.getPayloadAsString(), an inner casting seems to be affecting the payload. This, normally, wouldn't be a problem except for one of the cases that we have found: one of the services we invoke returns a PNG file, so message.getPayloadAsString() turns it into a String and breaks the image.
We've tried to clone the payload in order to keep one of the copies safe from the casting but, as an Object, it's not implementing Cloneable interface; we've tried to make a copy of the payload in any other single way, but only a new reference is generated; we've tried to serialize the payload to create a new copy from the serialized data but the Object doesn't either implement Serializable interface... Everything useless.
Any help, idea or piece of advice would be appreciated.
We finally managed to solve the problem by using message.getPayloadAsBytes();, which return value is a brand new byte[] object. This method doesn't either alter the payload within the message. By using the byte array we can create a String object to be written in our audit like this:
byte[] auditByteArray[] = message.getPayloadAsBytes();
String auditString = new String(auditByteArray);
Moreover, we tried a test consisting in stablishing that byte array as the new payload in the message and both JSON and PNG responses are managed correctly by the browser.
what is the best way to ensure payload state is maintained during a flow execution. I have a flow that performs multiple database and webservice executions, but everytime i perform a connector execution my payload gets lost. to maintain this.
To maintain state, all my connector executions are being performed in a message enricher scope and the responses from these outbound connectors are populated in variables. Even though I feel these are a complete waste of memory.
kindly advise.
regards
Santosh
What would you be doing with the results of these other db / ws calls if you didnt put them in flowVars? Where would you like to hold them?
You are probably doing the right thing to use MessageEnricher if you dont want to loose the original payload.
If you didnt want to put the results of each enricher in vars, you could add them to the message payload itself. If the payload is an instance of map or a pojo with a setter, you can simply add an enrichers result as in:
<enricher source="#[message.payload]" target="#[message.payload.enricherResult]" doc:name="Message Enricher">
If you wanted to keep the payload original, you could move it into a map as key "original" or something and then add each enrichers result as a new key.
Either way, the fact that you plan to hold on to each enrichers result probably means the same amount of memory is being used whether you put them in flowVars or stuff them into the payload itself.
An alternate and simple approach will be, save the message payload into some variable before a DB call or external service call.
You can later retrieve the value from the variable and set it as payload
I have previously only used Mule 2.2.1, but i'm now reading up on Mule 3.4/3.5.
One major change between theses versions is the introduction of flows.
In the documentation of the Mule configuration i found this:
A flow begins with an inbound endpoint from which messages are read and continues with a list of message processors
However, in this post i came across the invoke-element. It appears that a flow can also begin with an invoke-element.
I was searching the Mule documentation for documentation of the invoke element, but was not able to find it. Can someone help explaining the semantics of the invoke-element, or point to any relevant documentation?
The "invoke" element is a message processor and not a message source.
The quote "A flow begins with an inbound endpoint from which messages are read and continues with a list of message processors" is not quite true as flows such as sub-flows or private flows that are referenced via other flows using flow-refs do not need an inbound-endpoint and can just have a list of message processors.
So it cannot be used to trigger a flow. However the example above seems to be a private flow which would be referenced from another flow via flow-ref so hence why it starts with a message processor. More eon private and sub-flows here: http://www.mulesoft.org/documentation/display/current/Using+Flows+for+Service+Orchestration
Back to the invoke message processor. THere is lacking documentation around this, but simply put, it calls the specified method for the given object using the given arguments.
From the javadoc: invokes a specified method of an object. An array of argument expressions can be provided to map the message to the method arguments. The method used is determined by the method name along with the number of argument expressions provided. The results of the expression evaluations will automatically be transformed where possible to the method argument type. Multiple methods with the same name and same number of arguments are not supported currently - http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/processor/InvokerMessageProcessor.html