Category Archives: Mule 4

Mule 4 Mulesoft Tutorial

Retry Mechanism – Until Success Vs Flow Reference

Published by:

Retry Mechanism – Until Success Vs Flow Reference

In mule 3 we have roll back exception strategy which enable’s the ability to retry the execution in case of error and define a separate flow to be executed once the retry count has exceeded.

In mule 4 you do have re-connection strategy which we can define on the connectors but that only retries in case of failure in connection. In Mule 4 we do not have roll back exception strategy, so in this tutorial we will be looking on how we can implement the same functionality in Mule 4.

To achieve this retry mechanism, we can use Until Successful, but the issue we will face are:

  1. We would not be able to specify any specific condition on which retry should happen . For Example: We will not be able to define retry only when HTTP status code is 202.
  2. We also cannot implement error flow, once an error has occurred. For Example: Every time an error is generated we need to send the error message on to a queue before retrying.

Scenario 1: We want to implement retry mechanism on Web service call, in case of error if HTTP status code is 502 then, API should retry its Web Service Call only 3 times.

To complete the above scenario, we will be using Flow Reference.

Flow Reference in Mule 3 was not able to call its own flow in which it was defined. But in Mule 4 you can call any flow even its own flow.

Flow Diagram:

All we need is to use is flow reference to call its own flow when an error is generated. We have moved HTTP Request to another flow “HTTPFlow” and is referred by flow reference in main flow “get:\users:test-config”.

Inside HTTPFlow we have HTTP Request call on which we have implement retry mechanism. In Error handling part, “On Error Continue” is checking for the retry count if it has reached to its max or not. Inside error flow of “On Error Continue” retry count value is getting incremented and after some seconds of sleep; flow reference will again call HTTPFlow. Once the retry count has reached to its max “On Error Continue” will no longer catch the error and the final error is throw back to its parent flow.

    <flow name="get:\users:test-config">
    <ee:transform xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd" doc:id="86de922d-7d4d-4d0a-b010-e1cf9e23a79d">
            <ee:message>
                <ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
  userID: [
    "1", 
    "2"
  ],
  userName: "Varun",
  subject: [
    "Maths", 
    "Mule", 
    "TIbco"
  ],
  class: {
    name: "Class 10"
  }
}]]></ee:set-payload>
            </ee:message>
        </ee:transform>
    <logger level="INFO" doc:name="Logger" doc:id="897eb15a-c379-4051-ae78-21ebbbf33cd1" />	
      <set-variable value="1" doc:name="SetRetryCount" doc:id="ae08693c-0c8e-4397-b5e2-235b8b288821" variableName="retryCount" />
    <flow-ref doc:name="HTTPFlow" doc:id="84ab16f4-0fa5-4ac4-a73e-80dd7ab20ea0" name="HTTPFlow"/>
    <logger level="INFO" doc:name="Logger" doc:id="92727a36-d8ed-4ea1-8616-3c0537598400" />
    </flow>
  <flow name="HTTPFlow" doc:id="610bee6d-59f2-4f77-a29e-d60b88aaea01" >
    <logger level="INFO" doc:name="Logger" doc:id="38537854-3f21-48a7-a6a6-31907d8bca90" message="Calling HTTP request count - #[(vars.retryCount default 0)]" />
    <http:request method="GET" doc:name="HTTPCall" doc:id="c766093c-c7ac-444f-914d-cd4d1b70676d" config-ref="HTTP_Request_configuration" path="/abc">
      <reconnect />
    </http:request>
    <error-handler >
      <on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" doc:id="8d23329f-b006-4a56-b6a7-6e33eb748957" when="#[(vars.retryCount as Number default 0) &lt; 3 and error.muleMessage.attributes.StatusCode == 503]">
        <logger level="INFO" doc:name="Logger" doc:id="1be75ffe-a4bf-4fe1-9802-ae1309d76341" message="#[error.description]"/>
        <set-variable value="#[(vars.retryCount default 0) +1]" doc:name="Increment retryCount" doc:id="a9877e1d-d1f5-4786-93e9-58126d08f3f4" variableName="retryCount"/>
        <scripting:execute doc:name="Sleep" doc:id="531bc61a-937d-4a0c-81ce-1ea0685ce64f" engine="groovy">
          <scripting:code >def duration = Long.valueOf('3000');
sleep(duration);
return message.payload;</scripting:code>
        </scripting:execute>
        <flow-ref doc:name="HTTPFlow" doc:id="3f37c302-ec9a-4751-ab4e-dcdefb2607f5" name="HTTPFlow"/>
      </on-error-continue>
    </error-handler>
  </flow>

 

Scenario 2: Here we want to implement retry mechanism on Web service call when a specific value is received. Example if a web service call returns a value 5 then retry should happen maximum 3 times else not.

Implementation:

We have moved HTTP Request to sub flow “testSub_Flow” and is referred by flow reference in its parent flow “post:\users:application\json:test-config”.

Inside testSub_Flow  we are using flow reference to call itself. Once we have received the response from web service call “Request“, Choice router we are routeing flow processing based on response received and number of retires number.

 

Mule 4 Mulesoft Tutorial

Error Handling In Mule 4

Published by:

In this tutorial we will be understand about various types of error handling in mule 4 and how we can implement it in our project with an example.

There are 3 types of error handling mechanism in Mule 4.

  1. On Error Continue
  2. On Error Propagate
  3. Try Catch Scope


On Error Continue


On-Error Continue catches the error, and do not report it as an error; thus the processing of the flow continues even after the error has occurred. This error handler can be used in flows where you don’t want to stop the flow processing even if an error has occurred.

For example in the below flow, the parent flow will execute till the end even if web consumer has returned an error.

SchedulerFlow is calling flow callWebService flow, in case of any error at point 9 (at web service consumer) the flow will process as follows: 1->2->3->7->8->9->12->13->4.
Here at point 13 the error is send to its parent flow (SchedulerFlow) as flow message, and parent flow executes its processing further.

On Error Propagate


On Error Propagate works exactly as Mule 3 Catch exception strategy. In case on any error, On Error Propagate processes the error message and re-throws the error to its parent flow. No further processing is done on that particular flow.

For example in the below Flow, when flow execution starts, point 1, 2, 3 will execute first, on error at point 3 the error is catch by on-error propagate and error processing begins with point 6, 7; once the error handling flow is completed the flow processing ends and an error is re-thrown to its parent flow.

In can of no error or happy scenario point 1,2,3,4,5 are executed, in case of error at point 3; point 1,2,3,6,7 are executed.

In the second example below, SchedulerFlow is calling flow callWebService flow, in case of any error at point 9 (at web service consumer) the flow will process as follows: 1->2->3->7->8->9->12->13->5->6.
Here at point 13 the error is thrown to its parent flow (SchedulerFlow), and parent flow error handler is invoked.

Try Catch Scope


Try catch scope can be used within a flow to do error handling of just inner components. Try catch scope can be very useful in cases where we want to add separate error processing strategy for various components in the flow.

For example: In case of error at point 3 (at web service consumer) the flow will process as follows: 1->2->3->7->8->10->11.
In case of error at point 5 (at saleforces connector) the flow will process as follows: 1->2->3->4->5->9->6.

 

Configuring On-Error Continue and On-Error Propagate


As in Mule 3 we had to specify which error is to be catch inside the catch exception strategy, same we can do in Mule 4 with even more control.

In Mule 4 we can specify Error Type and/or When Condition which when is evaluated true that particular error handler is executed. In case none error handler catches the error the error is re-thrown to its parent flow. 

Error Type: This matches with the type of error that is thrown. Error Type are auto populated based on connectors used in the flow. It contains the list of errors that the connectors can throw in the flow.

 

When Condition: The expression that will be evaluated to determine if the exception strategy could be executed. This should always be boolean expression. 

In below example when variable errorCount is greater than 3 then only that particular error handler is invoked.

Mule 4

Inbound Outbound Properties

Published by:

In this “Inbound Outbound Properties” tutorial of Mule 4 we will look on how we can set and modify Mule Inbound and Outbound Properties.

In Mule Inbound properties referees to the additional information that comes to an Mule API along with the message body/payload itself. It may consist of inbound Headers, Query Params, URI Params, HTTP method etc.
In Mule Inbound properties are preset by the sender of the message thus cannot be added or modified.

Mule Outbound Properties are headers and properties that Mule API set before ending its request to other external systems.

Inbound Properties
In Mule 3 we used to access inbound properties by #[message.inboundProperties]

Whereas in Mule 4 we access these properties by #[attributes]

Example
We have create a simple project using RAML.
The GET method of the RAML has URI Param – user_id, which can assess by #[attributes.uriParams['user_id']]

Similarly to access Query Param we do it by #[attributes.queryParams['code']]

To view all the Inbound Properties that are received by a Mule API:

#[attributes]


Output :

 

Outbound Properties
As in Mule 3 we used to set outbound properties via using Set Property Component.
In Mule 4, outbound properties no longer exist. Instead, the headers or properties (e.g. HTTP headers or JMS properties) that you wish to send as part of a request or message (e.g. HTTP request or JMS message) respectively are now configured explicitly as part of the connector operation configuration. 
Example:
To Set the outbound HTTP headers and HTTP status code for a Mule API we need to modify the HTTP Listener Configuration.

SoapUI Output –

Mule 4 Mulesoft Basics Mulesoft Tutorial

Variables in Mule 4

Published by:

Variable in Mule 4


In this Variable in Mule 4 tutorial we will look how we can create and use mule variable in Mule 4, and how it is different from Mule 3 and Mule 4.

In Mule 3 we had Flow variables, Session variables and record variable to store the data inside mule flow. But now in Mule 4 this has been changed; session variable and record variable has been removed and there is only Flow Variable.

As in Mule 3, Flow Variable in Mule 4 value is lost even when the flow crosses the transport barrier.
Session variable has been completely removed in Mule 4.

In Mule 4, flow variables have been enhanced to work efficiently during batch processing, just like the record variables. Flow variables created in batch steps are now automatically tied to the processing record and stays with it throughout the processing phase. No longer record variables are needed.
Continue reading

Mule 4 Mulesoft Basics Mulesoft Tutorial

Mule 4: JSON Schema Validation

Published by:

JSON Schema is a specification for JSON based format for defining the structure of JSON data. It validates input data at runtime and verifies that they match a referenced schema or not. We can match against defined schemas that exist in local file or in an external URI.

If the payload is incorrect with given JSON schema, then compiler throws below Exception:

org.mule.module.json.validation.JsonSchemaValidationException: Json content is not compliant with schema

Use Case:

Validating the input JSON payload against with JSON Schema.

JSON Payload:

{
  "firstName": "Murali",
  "lastName": "Krishna",
  "age" : 26
}	

JSON – Schema :

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "age": {
      "type": "integer"
    }
  },
  "required": [
    "firstName",
    "lastName",
    "age"
  ]
}

Mule Flow:

Step -1 :

Configure the HTTP Listener with by giving hostname, port number and path along with this specify allowed methods (Optional) at an Advanced tab of HTTP connector.

Step-2:

Drag and Drop the JSON Validate Schema from Mule Palette to validate the input payload. And provide the schema path. In my case it is like below:

schemas/Sample-Schema.json

From above line,

schemas –> It is directory

Sample-Schema.json —> It is JSON-Schema structure for validation.

Syntax of JSON Validator as below:

<json:validate-schema doc:name="Validate schema" doc:id="5a8b10e1-59e8-4f68-9aaa-303c9cb5c9d6" schema="schemas/Sample-Schema.json">

Step-3:

Drag & Drop the Logger component to log the resultant payload after validation.

Final Config.xml:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:validation="http://www.mulesoft.org/schema/mule/validation"
  xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
  xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/validation http://www.mulesoft.org/schema/mule/validation/current/mule-validation.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
  <http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="8a601d72-5913-4ed7-99d3-707601301ec9" >
    <http:listener-connection host="0.0.0.0" port="8080" />
  </http:listener-config>
  <flow name="abcFlow" doc:id="30917fd1-0429-4ec7-9d7d-aa8d4d19413e" >
    <http:listener doc:name="Listener" doc:id="2b89fed0-69ce-47eb-93bf-3bd0628fe188" config-ref="HTTP_Listener_config" path="abc" allowedMethods="POST">
      <ee:repeatable-file-store-stream />
    </http:listener>
    <json:validate-schema doc:name="Validate schema" doc:id="5a8b10e1-59e8-4f68-9aaa-303c9cb5c9d6" schema="schemas/Sample-Schema.json">
    </json:validate-schema>
    <logger level="INFO" doc:name="Logger" doc:id="26b62866-2f25-4374-9d95-9fe14c052366" message="Payload is Validated ----&gt; #[message.payload]" />
  </flow>
</mule>

Success Scenario:

Failed Scenario:

Thank you!

Please feel free to share your thoughts in the comments section.

Mule 4 Mulesoft Basics Mulesoft Tutorial

Mule – 4 DataWeave Functions – Part – 1

Published by:

In DataWeave 2.0 functions are categorized into different modules.

  1. Core (dw::Core)
  2. Arrays (dw::core::Arrays)
  3. Binaries (dw::core::Binaries)
  4. Encryption (dw::Crypto)
  5. Diff (dw::util::Diff)
  6. Objects (dw::core::Objects)
  7. Runtime (dw::Runtime)
  8. Strings (dw::core::Strings)
  9. System (dw::System)
  10. URL (dw::core::URL)

Functions defined in Core (dw::Core) module are imported automatically into your DataWeave scripts. To use other modules, we need to import them by adding the import directive to the head of DataWeave script, for example:

import dw::core::Strings

import dasherize, underscore from dw::core::Strings

import * from dw::core::Strings

Sample Payload:
{
"firstName" : "Murali",
"lastName" : "Krishna",
"age" : "26",
“age” : ”26”
}

1. Core (dw::Core)

Below are the DataWeave 2 core functions:

++ , –, abs, avg, ceil, contains, daysBetween, distinctBy, endsWith, filter, IsBlank, joinBy, min, max etc….

result : [0, 1, 2] ++ [“a”, “b”, “c”] will gives us “result” : “[0, 1, 2, “a”, “b”, “c”]”

result : [0, 1, 1, 2] — [1,2] will gives us “result” : “[0]”

result : abs(-20) will gives us “result” : 20

average : avg([1, 1000]) will gives us “average” : 500.5

value : ceil(1.5) will gives us “value” : 2

result : payload contains “Krish” will gives us “result” : true

days: daysBetween(“2016-10-01T23:57:59-03:00”, “2017-10-01T23:57:59-03:00”) will gives us “days”: 365

age : payload distinctBy $ will gives us  :

 {

“firstName” : “Murali”,

“lastName” : “Krishna”,

“age” : ”26”

}

a: “Murali” endsWith “li” will gives us “a” : true

a: [1, 2, 3, 4, 5] filter($ > 2) will gives us “a” : [3,4,5]

empty: isBlank(“”) will gives us “empty” : true

aa: [“a”,”b”,”c”] joinBy “-” will gives us “a” : “a-b-c”

a: min([1, 1000]) will gives us “a” : 1

a: max([1, 1000]) will gives us “a” : 1000

2.Arrays (dw::core::Arrays)

Arrays related functions in DataWeave are :

countBy, divideBy, every, some, sumBy

[1, 2, 3] countBy (($ mod 2) == 0) will gives us 1

[1,2,3,4,5] dw::core::Arrays::divideBy 2 will gives us :

[

[

1,

2

],

[

3,

4

],

[

5

]

]

 

[1,2,3,4] dw::core::Arrays::every ($ == 1) will gives us “false”

[1,2,3,4] dw::core::Arrays::some ($ == 1) will gives us “true”

[ { a: 1 }, { a: 2 }, { a: 3 } ] sumBy $.a will gives us “6”

3.Binaries (dw::core::Binaries)

Binary functions in DataWeave-2 are:

fromBase64, fromHex, toBase64, toHex

toBase64(fromBase64(12463730)) will gives us “12463730”

{ “binary”: fromHex(‘4D756C65’)} will gives us “binary” : “Mule”

{ “hex” : toHex(‘Mule’) } will gives us “hex” : “4D756C65”

4.Encryption (dw::Crypto)

Encryption functions in Dataweave – 2 are:

HMACBinary, HMACWith, MD5, SHA1, hashWith

{ “HMAC”: Crypto::HMACBinary((“aa” as Binary), (“aa” as Binary)) } will gives us :

“HMAC”: “\u0007£š±]\u00adÛ\u0006‰\u0006Ôsv:ý\u000b\u0016çÜð”

Crypto::MD5(“asd” as Binary) will gives us “7815696ecbf1c96e6894b779456d330e”

Crypto::SHA1(“dsasd” as Binary) will gives us “2fa183839c954e6366c206367c9be5864e4f4a65”

5.Diff (dw::util::Diff)

It calculates difference between two values and returns list of differences.

DataWeave Script:

%dw 2.0

import * from dw::util::Diff

output application/json

var a = { age: “Test” }

var b = { age: “Test2” }

a diff b

Output:

{

“matches”: false,

“diffs”: [

{

“expected”: “\”Test\””,

“actual”: “\”Test2\””,

“path”: “(root).age”

}

]

}

Note:

Rest of the things will proceed in Mule – 4 DataWeave Functions Part – 2 article

Mule 4 Mulesoft Basics Mulesoft Tutorial

DataWeave 1.0 to DataWeave 2.0 Migration – Part -1

Published by:

DataWeave is a new feature of Mule-3 that allows us to convert data to any kind of format, such as XML, CSV, JSON and POJO’s etc. In Mule 3, we use both MEL and Dataweave for writing the mule messages. Among these, MEL is default expression language in Mule 3 But this approach had some data inconsistencies and scattered approaches. To avoid the stress of converting data objects to Java objects in Mule 3 every time by the usage of expressions Mule 4 was launched. In Mule 4 DataWeave is the default expression language over Mule 3’s default MEL.

In Mule-4 DataWeave version has changed from 1.0 to 2.0.

Apart from syntax changes, there are many new features in DataWeave 2.0

Continue reading