As promised in my first post this starts a small series of tutorials using SonarQube to verify some properties on BPMN process files. In this post I briefly sketch the purpose of SonarQube, describe the basic installation process and how the different parts of SonarQube can be used to perform some first analysis. Finally, I introduce my use case of analysing BPMN process models.
What is SonarQube?
First of all some words to SonarQube: SonarQube (formerly known as Sonar) is an open source tool suite to measure and analyse to quality of source code. It is written in Java but is able to analyse code in about 20 different programming languages. Code analysis may be started manually by executing a so-called sonar runner but SonarQube’s full is potential is especially revealed when used in combination with continuous integration such as a Jenkins server. The results of an analysis are shown in a fancy web frontend with ‘green’ and ‘red lights’, nice charts, issue lists and an ability to drill down from project level to a single class. A public live demo showing the results for various open source projects is available here.
Getting Started: Download, Installation, First Results
Following the official documentation it is rather simple to get a local SonarQube instance up and running:
- Prerequisite: You need a Java installation on your machine.
- Download the recent version of the SonarQube Server, unzip it to your favored folder and run the OS-specific startup script. On my ubuntu 64bit machine this looks like this:
On Windows machines the `StartSonar.bat` file has to be executed which is located in the `$sonarqubeBase\bin\windows-x86-xx\` folder – where xx stands for 32/64 depending whether your machine has a 32bit or 64bit architecture.
- Using the default setting, the server is now accessible on http://localhost:9000. However, there are no results to see as no project has been analyzed by now:
The getting started Tutorial now proposes to analyze a sample project from GitHub – I think it is more exiting to analyze on of your own existing projects. In order to add a project to your SonarQube server 1) you have to write/adjust a
sonar-project.properties file and 2) run the analysis using the Sonar Runner.
- So let’s first have a look at an example `sonar-project.properties` file: Each project to be added to SonarQube needs a unique key, a name and a version identifier. Moreover, at least one folder pointing to the sources to be analyzed has to be defined. In my case the sample project is written in Java and encoded in UTF-8.
# Required metadata sonar.projectKey=hello-sonar-example sonar.projectName=My first Project to be analyzed sonar.projectVersion=1.0 # Comma-separated paths to directories with sources (required) sonar.sources=src # Language sonar.language=java # Encoding of the source files sonar.sourceEncoding=UTF-8
- Put this file in the root directory of your project.
- To perform the analysis download the SonarQube Runner and unzip it.
- Open a terminal/console in the root directory of your project to check and run the `sonar-runner`/`sonar-runnter.bat` script:
The scripts will produce loads of output but at the end the execution should be successful:
After successful execution of the SonarQube Runner you can find the results in the already mentioned web frontend on http://localhost:9000
The following gallery shows some screenshots with the results for my simple “Hello World” project1:
My Use Case: Analysing BPMN Process Models
Instead of measuring the quality of Java-Projects I am interested in revealing issues in BPMN process models. Process models are often ‘drawn’ using modelers such as Signavio Process Editor, the Yaoqiang Editor or the eclipse BPMN2 modeler. A simple example of a BPMN process is shown in the following figure:
This simple process begins with a StartEvent (circle with a thin line), connected by a SequenceFlow (arc) to a single Task (rectangle with rounded corners) which is again connected to an EndEvent (circle with a thicker line).
It is rather easy to determine for humans that this process is well-formed according to the syntactical constraints defined in the BPMN specification. However, for complexer processes (such as this one) this is not always obvious. Performing an automated analysis on the graphical layer of BPMN is hard – but fortunately since Version 2.0 BPMN has its own XML-based serialization format. The XML serialization of the example process above is shown here:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1392799441952" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" exporter="" exporterVersion="2.2.18 (GPLv3, Non-Commercial)" expressionLanguage="http://www.w3.org/1999/XPath" id="_1392799441952" name="" targetNamespace="http://sourceforge.net/bpmn/definitions/_1392799441952" typeLanguage="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd"> <process id="PROCESS_1" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" isInterrupting="true" name="Start Event" parallelMultiple="false"> <outgoing>_5</outgoing> </startEvent> <task completionQuantity="1" id="_3" isForCompensation="false" name="Perform a Task" startQuantity="1"> <incoming>_5</incoming> <outgoing>_6</outgoing> </task> <endEvent id="_4" name="End Event"> <incoming>_6</incoming> </endEvent> <sequenceFlow id="_5" sourceRef="_2" targetRef="_3"/> <sequenceFlow id="_6" sourceRef="_3" targetRef="_4"/> </process> <bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=597.6;height=842.4;imageableWidth=587.6;imageableHeight=832.4;imageableX=5.0;imageableY=5.0" id="Yaoqiang_Diagram-_1" name="New Diagram" resolution="96.0"> <bpmndi:BPMNPlane bpmnElement="PROCESS_1"> <bpmndi:BPMNShape bpmnElement="_2" id="Yaoqiang-_2"> <dc:Bounds height="32.0" width="32.0" x="122.76086956521738" y="282.4565217391304"/> <bpmndi:BPMNLabel> <dc:Bounds height="18.8046875" width="69.0" x="104.26086956521738" y="323.0541779891304"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_3" id="Yaoqiang-_3"> <dc:Bounds height="55.0" width="100.0" x="238.0" y="271.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="32.8046875" width="63.0" x="256.5" y="284.09765625"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_4" id="Yaoqiang-_4"> <dc:Bounds height="32.0" width="32.0" x="410.5869565217391" y="282.9347826086956"/> <bpmndi:BPMNLabel> <dc:Bounds height="18.8046875" width="62.0" x="395.5869565217391" y="323.5324388586956"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="_6" id="Yaoqiang-_6" sourceElement="_3" targetElement="_4"> <di:waypoint x="337.7608695652174" y="298.5"/> <di:waypoint x="410.804347826087" y="298.9347826086956"/> <bpmndi:BPMNLabel> <dc:Bounds height="18.8046875" width="6.0" x="371.29347826086956" y="289.37234961210294"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_5" id="Yaoqiang-_5" sourceElement="_2" targetElement="_3"> <di:waypoint x="155.15211184904825" y="298.4565217391303"/> <di:waypoint x="237.76086956521738" y="298.5"/> <bpmndi:BPMNLabel> <dc:Bounds height="18.8046875" width="6.0" x="193.36953568047477" y="289.0541779891304"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>
WTF… 59 LoC for 5 graphical elements?!?
Yes… XML produces bloated code. However, the major part of the listing above (line 23-58) exists due to the fact, that also the Diagram Interchange information is generated by the used modeling tool. This information is needed – as the name implies – for interchange between different modeling tools. I.e., the same model should look the same in all tools. This not only covers the model structure but especially graphical information such as positioning and size of all elements. The model structure (Which BPMN elements are used? And how are they connected?) is defined in the <process>-tag (line 9-22). For further analysis I focus on this structural information.
The OMG provides a set of normative XML Schema Definitions (XSDs) which allow for some a “schema validation” whether a concrete model is “correct” BPMN.
And at this point SonarQube comes into play: There exists an SonarQube XML Plugin which provides support for checking XML files. On feature covers the schema validation of arbitray XML files. So it should be possible to use SonarQube to check whether given BPMN process model are schema valid, or not.
How SonarQube has to be configured to perform such a schema validation on arbitrary XML and especially BPMN projects is the topic of the next post.