Introducing - Mule Flow Diagrams
Manik Magar
Posted on July 26, 2020
Mule applications are written in xml language with predefined XML schemas. Flows and sub-flows, along with other components are the base constructs of a Mule application. An application is usually a collection of multiple flows and sub-flows, spread across multiple configuration files. All of these can reference each other for processing messages. Often times, data can also be exchanged synchronously or asynchronously using connectors. When analyzing mule application, it can get difficult to see the complete data processing flow and their dependencies. In studio, you can keep jumping between flows to understand the processing flow but it is time consuming.
Have you ever wished to visualize your flow dependencies in a diagram? How does message flows through your application? Which sub-flows are called and in which order?
If yes, then this is for you!
Introducing Mule flow diagrams , a tool that can scan your mule projects and generate diagrams such as Graph of your mule application code.
What it does?
Consider following mule 4 configuration file that has some flows, sub-flow, and connectivity over VM and HTTP connector. Reading this XML or even seeing it in studio design mode may not easily tell how message flows through this application.
Click here to see an example test-hello-app.xml configuration.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:db="http://www.mulesoft.org/schema/mule/db" 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/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd">
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="4b9901d3-7256-4899-ba42-e48244bb84fd" >
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<db:config name="Database_Config" doc:name="Database Config" doc:id="6d07f955-b6c6-4bb6-8dde-8461669e29f2" >
<db:my-sql-connection port="${db.port}" host="${db.hostname}" user="${db.user}" password="${db.password}" database="${db.database}"/>
</db:config>
<configuration-properties doc:name="Configuration properties" doc:id="f535d8b1-e94a-47d3-8280-192dfc7f53b4" file="application.properties" />
<flow name="test-hello-appFlow1" doc:id="e8a2c60f-ec54-49af-85c7-6a4338658412" >
<vm:listener doc:name="Listener" doc:id="cedb163e-e702-4c04-9695-712e59e2a0b4" config-ref="Messages_VM" queueName="messagesToProcess"/>
<db:select doc:name="Select" doc:id="439a447d-3d96-4526-9b94-24e34bb9c938" config-ref="Database_Config">
<db:sql >select * from books;</db:sql>
</db:select>
<flow-ref doc:name="Flow Reference" doc:id="d606631b-f1f5-41d5-9ec8-9eec117bcc5b" name="sub-flow-level-1-1"/>
</flow>
<sub-flow name="sub-flow-level-1-1" doc:id="a33ad865-b9d8-4fbf-8d09-69d0b0300c99" >
<logger level="INFO" doc:name="Logger" doc:id="dd241f4f-b7b7-4152-a532-999384753969" />
<flow-ref doc:name="Flow Reference" doc:id="ae8ed341-07c1-4730-a728-8a5aa98b5e8d" name="sub-flow-level-2-1-1"/>
</sub-flow>
<sub-flow name="sub-flow-level-2-2-0" doc:id="a33ad865-b9d8-4fbf-8d09-69d0b0300c99" >
<logger level="INFO" doc:name="Logger" doc:id="dd241f4f-b7b7-4152-a532-999384753969" />
</sub-flow>
<sub-flow name="sub-flow-unused" doc:id="a33ad865-b9d8-4fbf-8d09-69d0b0300c99" >
<logger level="INFO" doc:name="Logger" doc:id="dd241f4f-b7b7-4152-a532-999384753969" />
</sub-flow>
<sub-flow name="sub-flow-loop" doc:id="a33ad865-b9d8-4fbf-8d09-69d0b0300c99" >
<logger level="INFO" doc:name="Logger" doc:id="dd241f4f-b7b7-4152-a532-999384753969" />
<flow-ref doc:name="Flow Reference" doc:id="ae8ed341-07c1-4730-a728-8a5aa98b5e8d" name="sub-flow-loop"/>
</sub-flow>
<sub-flow name="sub-flow-level-1-2" doc:id="5dced7e5-9fbc-4138-951f-586e0c1a766f" >
<logger level="INFO" doc:name="Logger" doc:id="d451a2c2-a520-489a-8660-fb226a246f2a" />
<flow-ref doc:name="Flow Reference" doc:id="1fb51667-42c9-4af6-9c7b-a3811e0e509a" name="sub-flow-level-2-2-0"/>
<async>
<flow-ref doc:name="Flow Reference" doc:id="1fb51667-42c9-4af6-9c7b-a3811e0e509a" name="sub-flow-level-2-1-1"/>
</async>
<flow-ref doc:name="Flow Reference" doc:id="1fb51667-42c9-4af6-9c7b-a3811e0e509a" name="sub-flow-level-2-2-1"/>
</sub-flow>
<sub-flow name="sub-flow-level-2-1-1" doc:id="1d7a1a3a-777d-4d4b-8461-f11185247ae3" >
<logger level="INFO" doc:name="Logger" doc:id="9e7481ed-b803-40a3-a720-3d9edf1b5500" />
</sub-flow>
<sub-flow name="sub-flow-level-2-2-1" doc:id="da46a247-0355-4ace-a255-c28a19e628b9" >
<logger level="INFO" doc:name="Logger" doc:id="2fabf827-7695-4830-ae9e-ec79eb38ba96" />
<flow-ref doc:name="Flow Reference" doc:id="1fb51667-42c9-4af6-9c7b-a3811e0e509a" name="sub-flow-level-2-2-2"/>
</sub-flow>
<sub-flow name="sub-flow-level-2-2-2" doc:id="da46a247-0355-4ace-a255-c28a19e628b9" >
<logger level="INFO" doc:name="Logger" doc:id="2fabf827-7695-4830-ae9e-ec79eb38ba96" />
</sub-flow>
<flow name="test-hello-appFlow" doc:id="c13c3670-cd7a-4181-bd9b-8d87f3f114d6" >
<http:listener doc:name="Listener" doc:id="b0b19843-27ad-45c9-8761-2910af952655" config-ref="HTTP_Listener_config" path="/sayhello"/>
<set-payload value="#['Hello from container']" doc:name="Set Payload" doc:id="2cfc464b-950a-4645-b7e3-355c5aeb7304" mimeType="text/plain"/>
<flow-ref doc:name="Flow Reference" doc:id="f8c61d95-28e4-4c4a-8a51-27dc059b89b1" name="sub-flow-level-1-2"/>
<flow-ref doc:name="Flow Reference" doc:id="f8c61d95-28e4-4c4a-8a51-27dc059b89b1" name="test-hello-appFlow1"/>
</flow>
<flow name="test-hello-appFlow-3" doc:id="c13c3670-cd7a-4181-bd9b-8d87f3f114d6" >
<http:listener doc:name="Listener" doc:id="b0b19843-27ad-45c9-8761-2910af952655" config-ref="HTTP_Listener_config" path="/sayhello2"/>
<vm:publish doc:id="7fdcd659-283b-40c7-9550-8b965fd8441f" sendCorrelationId="ALWAYS" correlationId="#[vars.formatType ++ '_' ++ vars.queueBody.properties.documentIdentifier ++ '_' ++ vars.queueBody.properties.serviceInstanceIdentifier]" queueName="messagesToProcess" doc:name="vm Publish" config-ref="VM_Config" transactionalAction="NOT_SUPPORTED" >
<error-mapping targetType="APP:TRANSMISSION_QUEUE_FAILED" />
</vm:publish>
<choice>
<when>
<flow-ref doc:name="Flow Reference" doc:id="f8c61d95-28e4-4c4a-8a51-27dc059b89b1" name="sub-flow-level-1-2"/>
</when>
<otherwise>
<logger level="INFO" doc:name="Logger" doc:id="2fabf827-7695-4830-ae9e-ec79eb38ba96" />
</otherwise>
</choice>
</flow>
</mule>
Let’s generate a graph for this configuration file by running following command.
$ muleflowdiagrams ~/Downloads/test-hello-app.xml -d GRAPH
What do we get from this diagram?
Now, this diagram tells us many things about our application code such as -
How are those flows and sub-flows linked to each other?
There is a sub-flow named sub-flow-unused
which is potentially an unused sub-flow.
There is an asynchronous communication happening over VM.
Sub flow named sub-flow-loop
is marked for a recursion condition.
Isn’t this more easier to understand the application?
How to get this tool?
If you are on Mac OS, then you can get it via homebrew
.
brew install manikmagar/tap/muleflowdiagrams
Alternatively, you can download the latest release from git repository and install it manually. See installation section on the repository.
| | You can make it out from the project repository path that this is by me and has no relation with MuleSoft. |
How to use this tool?
It is a CLI tool and supports various arguments. Once you have it installed, you can run it from your terminal.
CLI Options
$ muleflowdiagrams
Missing required parameter: <sourcePath>
Usage: muleflowdiagrams [-hV] [-d=<diagramType>] [-o=<outputFilename>]
[-t=<targetPath>] <sourcePath>
Create Flow diagrams from mule configuration files.
<sourcePath> Source directory path containing mule configuration files
-d, --diagram=<diagramType>
Type of diagram to generate. Valid values: GRAPH, SEQUENCE
Default: GRAPH
-h, --help Show this help message and exit.
-o, --out=<outputFilename>
Name of the output file
Default: mule-diagram
-t, --target=<targetPath>
Output directory path to generate diagram
-V, --version Print version information and exit.
Copyright: 2020 Manik Magar, License: MIT
Website: https://github.com/manikmagar/mule-flow-diagrams
See Readme on project repository for more details on the usage.
For example, run the against a mule 4 project:
muleflowdiagrams ~/devlife/AnypointStudio/studio-workspace/test-hello-app
Next?
It is evolving and more will come, so keep watching the repository for new releases. In meantime, please feel free to get the current release and try it out.
If you run into any issues or have suggestions, please open a new issue on project repository.
Still got a question, comment on this article or find me on Twitter. I am looking forward to hear your thoughts on this.
Posted on July 26, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.