How to retain inbound properties across transport barrier - properties

I am building a restful proxy using mule where I have a need to call two web services in a single flow. The call to the first WS is supposed to do user authentication and if the authentication succeeds, then the ORIGINAL HTTP request will be proxied to the correct REST end point by a second WS call. I have a problem after the first authentication web service call returns. When this call returns, the original HTTP request is lost.
How do I retain the original HTTP request that comes in, save it across the first authentication web service call and then set the original headers just before the second web service call?
Please suggest to me the right approach to achieve this.

I would suggest to go with enricher in this case.
The scenario here looks like the first call is only to authenticate. So use and enricher to call the first WS and save the response as a flow varaible.
This way u still have your payload and all the properties same as they came in from the original request. You can the enriched flow varaible to decide on whether to call the second WS or not.
Here is a sample flow.
<flow>
<http:inbound ... />
...
<enricher target="#[variable:authenticationSuccessful]" source="#[payload]" >
<processor-chain>
<!-- YOu call to first WS and then the status whether authentication is succesful or not.
</processor-chain>
</enricher>
<choice>
<when expression="#[flowVars['authenticationSuccessful']]" />
<http:outbound to second WS />
</when>
<otherwise>
<logger level="INFO" message="Authentication Failed" />
</otherwise>
</choice>
</flow>
Hope this helps.

save the original request in flow variable before the first web-service call.
After first web-service call drag set-payload component to flow and assign the value to it from the flow variable which contains the original request.

As Mohan suggested save the inbound properties in variables..
There are 2 type of variables in Mule :- 1) Flow Variables 2) Session variables
So as per your requirement if you want to retain your inbound properties across the transport barrier then use Session variable as it is global and can be used in any of the flows
Flow variables on the other hand in local to the flow in which it is defined..
You can check this to see how to save in a variable :- http://www.mulesoft.org/documentation/display/current/Variable+Transformer+Reference

As the Mohan and Anirban suggested, you're able to make use of flow variables or session variables to keep a reference to your HTTP request. I suggest using flow variables since session variables are serialized and sent off as part of the message.
You can also make use of the enricher scope to "enrich" your current Mule message with the data from the first HTTP request.

Related

Calling a flow using Groovy Script in Mule 4

I need to make a call to a flow using groovy script in mule 4. Can someone let me know if they have tried it using Mule 4
It is possible, but I would HIGHLY recommend that you do NOT do it.
You will have to dig deep down into the Mule Java APIs and couple yourself to them and also add a lot of your own error handling etc. and be wary of platform updates and the if the Java API changes.
Personally I would restructure you app to only have 'business logic' in scripts and let Mule do the flow lookups elsewhere.
You can even lookup flows in dataweave.
But here is a rough working example(Note you will have to harden this code yourself):
<flow name="test-flow">
<scheduler>
<scheduling-strategy>
<fixed-frequency frequency="100000"></fixed-frequency>
</scheduling-strategy>
</scheduler>
<set-payload value="bla bla" />
<scripting:execute engine="groovy" doc:name="Toggle flow" doc:id="2eb6f071-bdef-4d3d-926d-2565fcd62d33">
<scripting:code>
import org.mule.runtime.api.message.Message;
import org.mule.runtime.core.api.event.CoreEvent;
import org.mule.runtime.core.api.event.EventContextFactory;
flow=registry.lookupByName("another-flow").get();
thisflow=registry.lookupByName("test-flow").get();
msg = Message.builder().value(payload).build();
event =CoreEvent.builder(EventContextFactory.create(thisflow,
org.mule.runtime.dsl.api.component.config.DefaultComponentLocation.fromSingleComponent("add-location"))).message(msg).build();
result =flow.process(event);
</scripting:code>
</scripting:execute>
</flow>
<flow name="another-flow">
<logger level="ERROR" message="Another Flow #[payload]" />
</flow>
You need to fetch the current flow and the flow you want to call.
Using the Mule APIs - construct a Mule Event, Messgae, payload etc. You will also need to add any attributes you need etc.
Is there any way to call mule "static flow" like When I use the above groovy script and it will call the flow ( its starting the called flow and get the values) and get the values.
Requirement :
Like, Mule Flow A is running independently.
Mule flow B wants to access the Flow A variable with out starting the flow A using groovy or python Script.
Note: Can do with flow reference and lookup but would like to implement using script.

How to make a call to multiple rest service in mulesoft

I have a requirement where i need to call multiple rest service.
currently I am invoking only one rest service, as the file is huge we have splitted into parts (like 1 to 10k , 10k to 20k, 20k to 30k...so on)
the flow is designed to read the complete file and now it has been splitted.
Flow goes like this:
HTTP requester(WS call)----businesslogic.
I want to invoke multiple services(1 to 10k , 10k to 20k, 20k to 30k...so on )and use the same common business logic flow.
how to configure?
If you need to call rest api's in sequence for every record the you can do that inside batch steps.
If you need to make rest api call's with out any sequence then you can use scatter gather inside batch.
Number of records to be processed in parallel can be set by configuring batch size.
References: https://docs.mulesoft.com/mule-user-guide/v/3.6/scatter-gather
https://dzone.com/articles/part-1-mule-batch-processing-introduction
Mule allows this by using the scatter-gather component. Be aware of exception handling in this use case. In case one or more routes fails, you need to control this.
<scatter-gather timeout="6000">
<!-- custom-aggregation-strategy class="implement and place your class here if you need a custom strategy"/-->
<http:request config-ref="requestConfig1" path="/path1" method="POST" doc:name="HTTP"/>
<http:request config-ref="requestConfig2" path="/path2" method="POST" doc:name="HTTP"/>
<http:request config-ref="requestConfig3" path="/path3" method="POST" doc:name="HTTP"/>
</scatter-gather>

Message Enricher in Mule

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.

Mule modularising/invoking private and sub flows

I am modularising my mule configuration into multiple private and sub flows for common tasks such as a common notification/logging flow for example.
These flows require multiple different pieces of information in order to be invoked from various different flows.
What is the best practice to pass this information to the private/sub modularised flow?
Is it flow variables? session variables? create a map of these values as the payload?
I am currently using flow variables, but this makes the configuration very verbose.
Taking my logging flow as an example, I have multiple set-variable processors followed a flow-ref multiple times:
<set-variable variableName="loggingEndpoint" value="xx" />
<set-variable variableName="loggingPriority" value="INFO" />
<set-variable variableName="loggingSubject"
value="xxx" />
<set-variable variableName="loggingBody"
value="xxxxx" />
<set-variable variableName="loggingCC"
value="xx" />
<flow-ref name="LoggingService" doc:name="Logging service" />
I do this multiple times so theres a lot of XML. But if flowVars is the best way to pass info to a private flow then I don't mind. Just want to know best practice.
For logging purposes I would use a logging interceptor, as explained here:
http://www.mulesoft.org/documentation/display/current/Using+Interceptors
http://www.mulesoft.org/documentation/display/current/Java+Component+Reference
If you have something more general, like sending an email or persisting info in a database you can put a and send information in session variables. This way those time consuming tasks do not block your main flow.
Regards.

Maintain Payload State during mule flow execution

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