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
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.
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.
I have a couple of flows that rely on session variables that are generated in one flow and then passed to the other. Is it safe to rely on session variables used by two asynchronous flows? I guess I don't fully understand the scope of 'sessionVars' in a mule application or in a given mule message.
The mule session has nothing to do with the Java EE session that is shared across threads. The mule session is part of the MuleMessage and how they works is explained here, therefor if you want to share something across multiple flows processing the same message that is the way to go.
If instead you are looking into a way to store a value from a flow processing the message A and pick that value from a flow processing the message B you should consider store this value into the objectstore
I am pretty sure that session variables are returned to http endpoints that are request-response. This could expose sensitive data. I am trying to locate the original mention and official mitigation strategy but have yet to locate it again.
But an easy solution is to remove them at return point of a flow
Edit:
Found the thing I was looking for...
`
<http:connector name="NoSessionConnector">
<service-overrides sessionHandler="org.mule.session.NullSessionHandler"/>
</http:connector>
`
found here under 'HTTP Response Header'
http://www.mulesoft.org/documentation/display/current/HTTP+Transport+Reference
Or, you can also create a custom SessionHandler