Mule esb 3.8 How to check if property exist in payload and validate it is guid (uuid) - mule

I know how to validate property if its match regexp:
regex = "^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$"
for guid, but if its not send in payload - receiving error, is it a simple way to check if property exist and do validate only then?
As per now I check with choice if its exist and if so then do validation, but interested if its more smarter way to do such as if I will have 20 properties to check its becomes very messy flow.
For example 3 validations at the moment:

You could use the Validations Module All validator which seems to cover this use case. Note that you can not customize the exception or message. If this is not acceptable then you could use individual validations in the flow instead.
Example:
<validation:all doc:name="Validation">
<validation:validations>
<validation:is-not-empty doc:name="Validation" value="#[payload.firstName]" message="Firstname cannot be empty"/>
<validation:is-not-empty doc:name="Validation" value="#[payload.lastName]" message="Lastname cannot be empty"/>
<validation:is-number message="Not an adult" value="#[payload.age]" minValue="18" numberType="INTEGER"/>
<validation:is-email email="#[payload.email]" />
<validation:matches-regex message="Invalid SSN" value="#[payload.ssn]" regex="^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$"/>
<validation:validate-size value="#[payload.ssn]" min="11" max="11" message="SSN too short"/>
</validation:validations>
</validation:all>

Related

how to pass an attribute over ActiveMQ in Mule 4

We are migrating from Mule 3 to Mule 4 and in one of our functionalities we need to publish messages to a topic and downstream another mule component is consuming from the queue which is bridged to the topic.
Nothing special here .
To ensure we are able to trace the flow via logs we were sending a 'TrackingId' attribute while publishing messages to the topic ( Mule 3 )
message.setOutboundProperty("XYZ_TrackingID", flowVars['idFromUI']);
return payload;
However when I try the same in Mule 4 we get the following exception :
ERROR 2020-12-20 10:09:12,214 [[MuleRuntime].cpuIntensive.14: [mycomponent].my_Flow.CPU_INTENSIVE
#66024695] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
Message : groovy.lang.MissingMethodException: No signature of method:
org.mule.runtime.api.el.BindingContextUtils$MessageWrapper.setOutboundProperty() is applicable for
argument types: (java.lang.String, org.mule.weave.v2.el.ByteArrayBasedCursorStream) values:
[XYZ_TrackingID, "1234567"].\nError type : (set debug level logging or '-
Dmule.verbose.exceptions=true' for
everything)\n********************************************************************************
Checked internet and it seems in Mule4 setting outbound properties is removed as per here
So how do I achieve the same in Mule 4 ?
Don't even try to do that for several reasons. For one message structure is different, so output properties doesn't exist anymore and that method doesn't even exists. On the other hand, in Mule 4 components like the Groovy component can only return a value and cannot change the event. They can not decide to what that value is going to be assigned. You can set the target in the configuration (payload or a variable) and not change the attributes. Note that variables in Mule 4 are referenced by var., not by flowVars. like in Mule 3 (ie vars.idFromUI).
There is a simpler way to set message properties in the Mule 4 JMS connector. Use the properties element and pass it an object with the properties.
For example it could be something like this:
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
XYZ_TrackingID: vars.idFromUI
}]</jms:properties>
</jms:message>
</jms:publish>
It is in the documentation: https://docs.mulesoft.com/jms-connector/1.0/jms-publish#setting-user-properties. I adapted my example from there.
I am not sure if Correlation Id serves the purpose of a tracking ID for your scenario. But you can pass a CID as below. It's there in the mule documentation.
https://docs.mulesoft.com/jms-connector/1.7/jms-publish
<jms:publish config-ref="JMS_config" sendCorrelationId="ALWAYS" destination="#[attributes.headers.replyTo.destination]">
<jms:message correlationId="#[attributes.headers.correlationId]"/>
</jms:publish>
If your priority is to customise the Tracking ID you want to publish, then try passing below format. The key names may differ as per your use case.
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
AUTH_TYPE: 'jwt',
AUTH_TOKEN: attributes.queryParams.token
}]</jms:properties>
</jms:message>
</jms:publish>
In the above the expression attributes.queryParams.token is basically trying to access a token query parameters which is passed to JMS as a property AUTH_TOKEN key-name , consumed by the API through a HTTP Listener or Requestor earlier.
However, attributes.headers.correlationId is a header. Both queryParams and headers are part of attributes in Mule 4.

attributes.headers getting lost after a http Request call in Mulesoft?

I am getting some attributes in an API but all getting lost after an HTTP request connector in mule4.
why is it happening?
Look in the connector's configuration properties -> advanced tab for the connector configuration (in this case the HTTP connector's "request" operation) and you'll find a target variable and target value. If you fill in the target with a name - this does an enrichment to avoid overwriting the Mule message. If you leave it blank (the default) it will save the message (attributes, payload) over the top of the existing one - which is what you're seeing now. This mirrors the old mule 3 functionality, but sometimes you want it to leave what you have there alone.
So for the target value you get to pick exactly what gets saved.. If you want just payload: put that in. If you want both payload and attributes - I'd use "message" as that will mean you get both payload and attributes saved in the variable. Of course you may not want as much saved, so feel free to put in whatever dataweave expression you like - so you could even create something with bits from anywhere like:
{
statusCode: attributes.statusCode,
headers: attributes.headers,
payload: payload
}
A connector operation may replace the attributes with those of the operation. If you need to preserve the previous attributes you need to save them to a variable.
This is a default behaviour of MuleSoft. Whenever request crosses to transport barrier it losses existing attributes. You need to preserve attribute before HTTP Request.

Set variable session copyonwritearraylist

Im new on Mule ESB and i have the next problem. I use connector "Collection Splitter" to separate a list of orders (books) to other things. When i do the checks i go back to join the books on the order with connector "Collection Agreggator". What i want is save the information of the payload in that moment in a session variable. The system dont do that. I think is posible because the type saves on the payload is "CopyOnWriteArrayList" type and i dont now if is posible save this type of list in a session variable.
Someone can be help me please?
Thanks!
You can also use a set-session-variable transformer. Set the name is something of your choosing and set the value to be #[payload]. That you will maintain both your payload and have a new session variable. However be very careful when using session variables, since these are serialized when sending a Mule message over a transport. If possible, try to use flow variables.
use the message enricher scope to achieve the same.
define the required component inside the message enricher scope.
in the enricher scope specify source as payload and the target as session variable.
try and let me know the status.

correct Http Request header field to pass some flags

Can someone suggest correct HTTP request header field to use to pass some flag using Rest API call. Can I use 'expect' request element for this use case?
Use Case:
Read client request header-->read the flag(say value is 1 or 0) --> do task A for value=1 or task B for value=0
No, that is not an appropriate use of the Expect header. Depending on your exact use case, you can use (a) a custom header, (b) a query parameter, or (c) embed the flag in the entity being sent to the server. Without more information, it's impossible to say which is most appropriate for your situation.

Return json encoded payload from exception strategy

I am experimenting with using Mule 3.4.0CE to provide a RESTful API and evaluating both the Jersey and Rest-router modules to handle this. That is mostly going well but I am not finding very much in terms of concrete/complete examples of implementing RESTful APIs in Mule.
At present I have simple GET and PUT endpoints for an entity working using the rest-router. The PUT flow is successfully passing stuff through to JDBC but I am fizzy about how to handle the case where the entity already exists.
I am ok with relying on SqlException to catch the pk constraint violation and have an exception strategy handling that:
<catch-exception-strategy when="#[exception.causedBy(java.sql.SQLException) and exception.getCauseException().getMessage().contains('Duplicate entry')]" doc:name="Duplicate_entry1">
<set-payload value="The request cannot be processed, the error is #[exception.getSummaryMessage()]" doc:name="Set Payload"/> <!-- [1] -->
<set-property propertyName="http.status" value="400" doc:name="Property"/> <!-- [2] -->
</catch-exception-strategy>
but am confused about 2 things:
1) Catching a more specific Exception?
I am able to get the exception strategy to match on java.sql.SQLException but would rather match on the root cause of com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException. Using that class and the various forms of casusedBy(), causedExactlyBy() and casueMatches() dont seem to find anything other than the outer SQLException.
and
2) How to return a simple json encoded payload in response to this error?
What I would like to do inside the catch-exception-strategy is to create a map of KV pairs something like status="error" and error_message="entity XX already exists" and have that json encoded as the mule payload/ response.
I am embarrassed that I cant seem to get my head around a way to do that simply with MEL or the various components in MuleStudio. Looking for pointers or docs on how to do this. I am resisting building a custom component to return the map I want and have that json encoded on the way out of Mule.
For 1) In your when clause you can make use of containsType() method of org.mule.util.ExceptionUtils (build on top of Apache ExceptionUtils class). It checks whole stacktrace for presence of specific exception.
If you don't want to provide fully qualified class name in MEL (for ExceptionUtils), you can use global imports feature, described in last part of MEL Cheat Sheet.
I have made two blog posts (here & here) about RESTful services on Mule. Maybe, you find them useful.
For 2) You can look into <json:object-to-json-transformer doc:name=“Object to JSON”/>
http://mule3.wordpress.com/2012/10/14/mule-object-to-json/
http://svn.muleforge.org/json-support/trunk/src/main/java/org/mule/module/json/transformers/JsonToObject.java
http://www.mulesoft.org/docs/site/current/apidocs/org/mule/module/json/transformers/package-summary.html
http://www.mulesoft.org/documentation/display/current/Native+Support+for+JSON#NativeSupportforJSON-Examples