Mule Soft Data Weave - mule

I want to write a Data Weave Code wherein if the data is null then it should route to 400. How do I write this in Mule Soft?
My flow is as follows:
HTTP -->Transfomer-->Logger
Tranformer DW code
{
event_ops_type: payload.EDM_generic_consumer_message.event_meta_data.event_operation_type
}
Now what I want to implement is if "event_ops_type" is null then route to 400(Exception Handling)?

You may want to try using a validation module. MuleSoft documentation here.
<validation:is-not-null message="event_ops_type is null!" value="#[flowVars.event_ops_type]" exceptionClass="com.example.MyException" doc:name="Validation"/>
You can also use a Groovy script in a choice block to throw any exception you'd like. Here, it will actually throw a 404 with the API generated exception handling. You could switch this to any exception you'd like.
<choice doc:name="Choice">
<when expression="#[flowVars.event_ops_type != null]">
<logger message="#[flowVars.event_ops_type]" level="INFO" doc:name="Logger"/>
</when>
<otherwise>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[throw new org.mule.module.apikit.exception.NotFoundException(flowVars['event_ops_type'] + " is null!"); ]]></scripting:script>
</scripting:component>
</otherwise>
</choice>
<exception-strategy ref="api-apiKitGlobalExceptionMapping" doc:name="Reference Exception Strategy"/>

You can use choice router after transformer to check payload.event_ops_type == "400". Then either raise custom exception for exception handling or set response status and reason based on event_ops_type 400.

Related

Mulesoft - How to find Http error payload in exception object?

How to find Http error payload in exception object ?
System 1 -> Call's Mule server . Mule server -> Docusign / some one else.
Docusign / some one returns 400 error with json payload (includes errorCode etc)
I need to return the exact details back to System 1.
how will i do this?
1) I did try to add all codes in success codes 200..599, then even error is having 200 ok . This will cause more problem, because I have to add lot of choice routing as some flows are having more data conversion.
2) Ideal soln -> Raise exception as usual. This has to be caught in choice exception. Now I have to send the same status_code and the json response back to the caller.
Issue -? how can i find the payload returned by HTTP in exception object. Where is stored in exception object.
Here is the sample- one way of handling this kind of scenario , use validation Component to throw exception and capture in your mainflow either by exceptionHandling or by APIKIT ExceptionHandling
<flow name="routeexceptionFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<logger level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Configuration" path="/in" method="POST" doc:name="HTTP">
<http:success-status-code-validator values="200..599"/>
</http:request>
<validation:is-false config-ref="Validation_Configuration" message="#[payload]" exceptionClass="nz.co.exception.BadRequestException" expression="#[message.inboundProperties['http.status'] ==400]" doc:name="Validate Bad Request"/>
<validation:is-false config-ref="Validation_Configuration" message="#[payload]" expression="#[message.inboundProperties['http.status'] !=200]" doc:name="Capture all other Exceptions"/>
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy when="#[exception.causeMatches('nz.co.exception.BadRequestException')]" doc:name="Catch Exception Strategy">
<set-payload value="#[exception.message]" doc:name="Set Payload"/>
<logger level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="****log all other exception****" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
Add this class in your java folder
package nz.co.exception;
public class BadRequestException extends Exception {
private static final long serialVersionUID = 8546839078847602529L;
public BadRequestException() {
super();
}
public BadRequestException(String message) {
super(message);
}
public BadRequestException(Throwable t) {
super(t);
}
public BadRequestException(String message, Throwable t) {
super(message, t);
}
}
In your project if you are using APIKIT Router , then instead of using exceptionHandling as above, add directly nz.co.exception.BadRequestException in 400 ReturnCode apikitExceptionHandling.

Mule 3 to Mule 4 error handling queries for error types and http status

I am migrating an error handling file from Mule 3 to Mule 4 using Anypoint Studio 7.
My queries are:
How would I do I now do this check as I cannot see the same information in the exception message? #[exception.causedBy(org.mule.module.http.internal.request.ResponseValidatorException)]"
Where do I find the http.status property now? I can see it as a variable when it is 200 but when the error is thrown it seems to disappear and cannot locate it in the message
Where can I find a list of error handling types?
The error handling types I'm particularly interested in are below but no idea if that is the correct value for the error type:
HTTP:BAD_REQUEST
HTTP:UNAUTHORIZED
HTTP:FORBIDDEN
HTTP:RESOURCE_NOT_FOUND
HTTP:METHOD_NOT_ALLOWED
HTTP:NOT_ACCEPTABLE
HTTP:CONFLICT
HTTP:UNSUPPORTED_MEDIA_TYPE
HTTP:INTERNAL_SERVER_ERROR
HTTP:BAD_GATEWAY
Snippet of the Mule 3 code I am migrating is below and I think it was based on a template:
<choice-exception-strategy name="global-exception-strategy">
<catch-exception-strategy when="#[exception.causedBy(org.mule.module.http.internal.request.ResponseValidatorException)]" doc:name="Caused By (org.mule.module.http.internal.request.ResponseValidatorException)">
<choice doc:name="Choice">
<when expression="#[message.inboundProperties['http.status'] == 401]">
<set-variable variableName="errorMessage" value="Upstream service did not authorize the request." doc:name="Set Error Message"/>
<flow-ref name="global-bad-gateway-response-sub-flow" doc:name="Bad Gateway Response"/>
</when>
<otherwise>
<set-variable variableName="errorMessage" value="Upstream service internal error." doc:name="Set Error Message"/>
<flow-ref name="global-bad-gateway-response-sub-flow" doc:name="Bad Gateway Response"/>
</otherwise>
</choice>
</catch-exception-strategy>
</choice-exception-strategy>
<sub-flow name="global-bad-gateway-response-sub-flow">
<set-property propertyName="http.status" value="401" doc:name="Set Status"/>
<set-payload value="UNAUTHORIZED" doc:name="Set Error Code" mimeType="application/java"/>
<flow-ref name="global-prepare-error-response-sub-flow" doc:name="Prepare Error Response"/>
</sub-flow>
Thanks
Use these kind of check
#[contains(error.description,'internal server error (500).')]
in Mule 4 http status code for error response located here
#[error.errorMessage.attributes['statusCode']]

name attribute on exception strategy is only allowed on global exception strategies

I created a global exception strategy as below,
<choice-exception-strategy name="GlobalExceptionStrategy">
<catch-exception-strategy name="400:BadRequest" when="#[message.inboundProperties['http.status']=="400"]" doc:name="400:BadRequest">
<logger message="Caught error with code #[message.inboundProperties['http.status']] and reason #[message.inboundProperties['http.reason']] for query payload #[message.payloadAs(java.lang.String)]" level="ERROR" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
But why I am still getting the error like name attribute is required only on global exception strategy?
Error was in this line <catch-exception-strategy **name**="400:BadRequest" when="#[message.inboundProperties['http.status']=="400"]" doc:name="400:BadRequest">
Using doc:name in place of name works perfect!

mule mapping-exception-strategy only falls through to first 401 branch

asking this for some mulesoft expertise.
the following exception mapping strategy is supposed to branch on hhtp.status 401, 403, 429 but keeps on falling into the 401 branch for status codes 401 and 403 (at least, and determined by both debugging and log written to console):
<apikit:mapping-exception-strategy doc:name="waysact-adaptor-main-exception-strategy">
<apikit:mapping statusCode="401">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging 401 = #[payload]" level="INFO" doc:name="log-http-401"/>
</apikit:mapping>
<apikit:mapping statusCode="403">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging 403 = #[payload]" level="INFO" doc:name="log-http-403"/>
</apikit:mapping>
<apikit:mapping statusCode="429">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging 429 = #[payload]" level="INFO" doc:name="log-http-429"/>
</apikit:mapping>
<apikit:mapping statusCode="400">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging anything = #[payload]" level="INFO" doc:name="logging-anything"/>
</apikit:mapping>
</apikit:mapping-exception-strategy>
is this because it is branching only on exception type org.mule.module.http.internal.request.ResponseValidatorException? i thought it was meant to branch on the status code?
there is another strategy, choice-exception-strategy, that should branch on different exception object types.
Branching of exception based on http.status can be defined with choice exception strategy as below example,
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy when="#[message.inboundProperties.'http.status'=='404']" doc:name="Catch Exception Strategy" >
<logger message="Exceptions message is ... #[exception.message]" level="ERROR" doc:name="exceptionLogger"/>
<set-variable variableName="exceptionMessage" value="#[exception.message]" doc:name="Set exceptionMessage"/>
<set-payload value="{ errors: { errorCode: #[message.inboundProperties.'http.status'], errorMessage: #[flowVars.exceptionMessage] } }" doc:name="Set Exception Payload"/>
</catch-exception-strategy>
<catch-exception-strategy doc:name="Catch Exception Strategy" >
<logger message="Exception message is ... #[exception.message]" level="ERROR" category="com.project.stacktrace" doc:name="exceptionLogger"/>
<set-variable variableName="exceptionMessage" value="#[exception.message]" doc:name="Set exceptionMessage"/>
<set-payload value="{ errors: { errorCode: #[message.inboundProperties.'http.status'], errorMessage: #[flowVars.exceptionMessage] } }" doc:name="Set Exception Payload"/>
</catch-exception-strategy>
</choice-exception-strategy>
APIkit matches the exception based on the exception value defined and not by the statusCode defined. Use choice exception strategy and define multiple catch exception strategy in it. Make sure each catch exception strategy matches a unique exception to make the way for proper http.status code and desired exception payload.
For example, if you want to have 400 to be thrown, make sure a catch exception strategy matches BadrequestException. If the status codes are coming out of the HTTP requester, match the ResponseValidatorException and set the incoming http.status and exception payload

How to capture an exception using the regex-filter filter in Mule ESB

Currently I have a flow that exposes a REST service with a string as input parameter . I am using a regex -filter to ensure the format parameter as follows :
<http:inbound-endpoint doc:name="HTTP"
connector-ref="ciuServiceHTTPConnector" ref="ciuServiceHTTPEndpoint"
exchange-pattern="request-response" />
<logger level="INFO" doc:name="Logger" message="epale1 #[payload]"/>
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
<logger message="epale2 #[payload]" level="INFO" doc:name="Logger"/>
<jersey:resources doc:name="REST" >
<component class="...resource.CiudadanoResource"/>
</jersey:resources>
I need to send the customer a message "Invalid or missing parameter" . For this I use a choice-exception-strategy and catch-exception-strategy and then call a Subflow and perform http:response-builder.
How can I throw an exception(type) when the regex-filter do not match?. It is possible to incorporate this behavior or should I change my flow?
Thanks for your help;
Wrap it in a message-filter, like this:
<message-filter throwOnUnaccepted="true">
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
</message-filter>
See the official documentation for further details:
Check the Throw On Unaccepted box to throw an exception if a message
or event is not handled. The default when not checked is to not throw
an exception.