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
Related
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 am modeling a complex process using BPMN 2.0
I have split the process into multiple global processes which can reference one another through call activity.
However, in one or two special cases, I would like to actually call directly into the middle of one of the other processes. I do not want to have to create an entirely duplicate [sub]process with just the first couple nodes missing and would also prefer not to split those couple nodes into their own little process.
I don't think common BPMN 2.0 tools support this, but is it explicitly disallowed by the spec? For instance, I read through http://www.omg.org/spec/BPMN/2.0.2/PDF and I don't see anywhere that it claims that a sequenceFlow's targetRef must be within the same FlowElementsContainer. Maybe it is just implied?
The correct way to do this would be to create several "none" start events in the global process and then reference the correct one via the targetRef attribute of a sequence flow incoming to the call activity. The spec says on p. 239:
"If the Process is used as a global Process (a callable Process that
can be invoked from Call Activities of other Processes) and there are
multiple None Start Events, then when flow is transferred from the
parent Process to the global Process, only one of the global Process’s
Start Events will be triggered. The targetRef attribute of a Sequence
Flow incoming to the Call Activity object can be extended to identify
the appropriate Start Event."
I need to discard a message if a specific header is present.
I tried to implement a IMutateTransportMessages and call DoNotContinueDispatchingCurrentMessageToHandlers() method inside MutateIncoming but the message is dispatched to handlers anyway.
I can discard the message using an handler but I don't like it because I need also to specify the handlers' order.
Any solution?
Thanks,
Federico
I don't think this will be possible from a message mutator. After all, this isn't really the kind of activity a message mutator should be doing - it has nothing to do with changing the structure of the message.
I agree with you that it sounds messy to do this in a handler, because you're right - then you are very dependent upon the handler order.
Discarding a message due to the presence (or absence) of a header is an infrastructure concern, and since you are using NServiceBus V5, the best way to customize the infrastructure is by customizing the message handling pipeline.
Here's the relevant documentation that covers creating a behavior and inserting it into the pipeline but here's the short version:
You need to create a behavior that implements IBehavior<IncomingContext>. All of the behaviors together form a behavior chain that progress to the next step by calling next() - an Action present in the implementation) method.
Within the behavior, check for your header. To stop processing the message, just don't call next() and call context.DoNotInvokeAnyMoreHandlers() instead.
Create a class inheriting RegisterStep which, from its constructor, will define where in the pipeline to insert your behavior. You could register it right before the MutateIncomingTransportMessage step.
Create a class implementing INeedInitialization (note that this could be the same as the RegisterStep class) which calls busConfig.Pipeline.Register<TClassThatInheritsRegisterStep>().
Again, that's the short version. Check out the docs for the full story and an example.
Shameless plug: This process is also described in detail in Learning NServiceBus - Second Edition in Chapter 7, with an example.
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