This year I got the chance to gain some experiences with Atlassian Connect and also Mule/the Anypoint Platform. These two things have nothing to do with each other at the first sight. But when looking deeper, a Connect add-on needs to provide an API and calls the API of the Atlassian product. The MuleSoft products offer API Management and integration and they also support a microservice approach – which fits very well for a Connect add-on. So I tried to build a Connect add-on with Mule.
That’s not what Mule is explicitly made for and my add-on should not only provide an API, but also deliver webpages with HTML content. So this was an experiment with unknown result to learn from.
This article is more focused on Mule, but for a better understanding I start with a short description of Connect and the app being developed.
A general introduction to Connect can already be found here on this blog. For our use case we want to have an add-on with a workflow post-function, that copies the value of a specific field from the parent issue to the issue being changed. These post-functions can be applied to any transition in a JIRA workflow. For a post-function there are three visual parts:
- create: form to configure the post-function, in our case select the field to copy
- edit: form to edit the post-function configuration
- view: short description in the list of active post-functions
The add-on needs to provide endpoints where JIRA can fetch the HTML for each case to embed it in the page. Then there are some endpoints that execute the logic or provide data:
- triggered: executes the post-function
- descriptor: delivers the descriptor of the add-on (needed for installation)
- add-on-installed-callback: a lifecycle hook, that is executed after add-on installation
The goal is to implement all this in Mule. There is already a spring boot implementation, so I had a working solution and the general knowledge what actions are required.
Developing the App
Setup hint: For development I used a JIRA cloud instance and a local add-on, tunneled with ngrok.
I started to design the API of the add-on using RAML (RESTful API Modeling Language), describing the six endpoints mentioned above. From this RAML specification, we can generate Mule flows using APIkit. To test early and get fast feedback, the first thing needed is the descriptor to install the add-on in the JIRA instance. So we need to serve a static json file from our add-on.
Learning #1: Delivering static content
Of course we could just try to use Set Payload and paste the json there. But a separated file is much better to handle (editing, formatting and so on). There are multiple ways of how a file can be read and provided to a mule flow. Most of the proposed solutions are rather strange or complicated, like creating a spring bean with IOUtils, providing the file name as constructor argument and accessing this bean through the app registry. Another proposed solution was to use the underlying Thread to get the resource as a stream.
An easier solution is to use the Static Resource Handler provided by Mule. The critical point in understanding for me was to leave behind the APIkit flows – the HTTP Static Resource Handler will be placed directly behind a HTTP Connector in its own flow. This took some time to realize.
Now we are ready to install the add-on – but it does not do anything. So the next thing we need is a way to create the desired post-function.