Using SonarQube and the XML Plugin to do code quality checks on SOA Suite components has several benefits compared to other options described at the end of this post.
- It is very flexible and relatively technology independent. It allows you to scan any XML file such as BPEL, BPMN, OSB, Mediator, Spring, composite.xml files
- It requires only configuration of SonarQube, the SonarQube XML Plugin and the CI solution (Jenkins in this example)
- It has few dependencies. It does not require an Oracle Home or custom JAR files on your SonarQube server.
- The XML Plugin has support (by SonarSource) so high probability it will still work in future versions of SonarQube.
- Writing rules is simple; XPath expressions. it does not require you to write Java code to create checks.
Jenkins / SonarQube setup
Setting up the environment
In this setup I've used Git, Jenkins, Maven, SonarQube. I've used an Ubuntu Server 16.04 install. The installation of the tools is pretty straightforward. Git and Maven are easiest: sudo apt-get install git maven. Jenkins is also pretty easy since there is a Debian package available. See here. For SonarQube I've installed a MySQL server (sudo apt-get install mysql-server). Next I've used the following manual. After the installation I've set the default admin password to admin (see here). I have also got Sonatype Nexus 3 installed on the server. This required a bit more effort. Nexus 2.x and Nexus 3.x use different API locations. Maven needed to be able to find Nexus (settings.xml file used for Nexus 2 cannot be used OOTB for Nexus 3). The init.d script had some different installation steps. See here.
Of course most people will know how to use Git. I prefer a setup in which the server has a single Git user who owns the repository and grant other users access with SSH keys to that repository. You can see how this is done here.
I've used the XML Plugin in SonarQube to define XPath rules. This first needs to be installed. Administration, System, Update Center and install the plugin:
You have to define a project in SonarQube. Administration, Projects, Management, Create Project.
The SonarQube Scanner (called from the CI tool) requires some configuration in order to know where in SonarQube to store the results of the analysis and what to analyse. This configuration can be stored in your source code project in a sonar.properties. In my case this file contained the following (match the settings from when you created the project in SonarQube):
I put this sonar.properties in the project directory (SampleApplication/HelloWorldProject). The sources location is relative to the checkout directory. I checked out the entire application so that is the root of my SonarQube analysis. For a composite compilation you might want to make the build more specific in that you only checkout a specific project and not the entire application. In that case the source path will also be different.
In order to create rules in SonarQube, you can go to Rules, Language XML, Xpath rule. Here you can create custom XPath rules.
In this case I'm checking .bpel files. The rule will be violated if the value of the name attribute of the process tag does not end with Process. Thus my BPEL process should have a name ending in Process. You should mind that XPath 1.0 is used (see here) in this plugin and not XPath 2.0. Thus you cannot use the ends-with function (which is why I needed to use the substring/string-length XPath expression).
There are two options for defining XPath rules which become apparent from browsing the source code of the XPath check here. You can use a boolean expression (false = violation) and XPath queries selecting violating nodes. First the boolean expression:
not(count(/process[substring(@name, string-length(@name) - string-length('Process') +1) = 'Process'])=1)
If this is true, then a rule violation is displayed on top of the page showing the source code (it cannot determine the specific node):
If however you want to have the rule violation displayed at the node which is violating the rule, you should restructure your rule to only select violating nodes, such as:
/process[not(substring(@name, string-length(@name) - string-length('Process') +1) = 'Process')]
Now the rule violation can be pinpointed to the violating node.
SonarQube Quality Gate
SonarQube uses the concept of quality gates. You can define rules which define when the quality gate will be passed. In my case I have defined the rule as Critical in the Quality profile Sonar Way.
I have also defined a rule in the Quality Gate that Critical Issues are not allowed.
You can make the SonarQube analysis part of your CI solution. In this example I'm using Jenkins. First install the following plugins:
You also have to do this for the Quality Gates plugin.
Under Global Tool Configuration, you have to add SonarQube Scanner configuration. See below:
Below you can see part of the job configuration indicating the SonarQube Scanner will be used. If a SonarQube Quality Gate is not passed, the build will fail.
A failed build indicates the reason why it has failed:
After the issue is fixed, the Quality Gate has been passed.
Inside the Maven build or as a separate step?
You can make the SonarQube code quality checks part of the Maven pom.xml file (application or project level). This requires you to make the SonarQube configuration available to the pom file which is used to do the build. This has the risk a developer will send measures to SonarQube of code which has not yet been committed, polluting the measures in SonarQube. Also there is a loss of separation of concerns. The CI tool usually has the configuration of different tools (such as VCS, build tools, JVM, code quality tools, automated testing tools, etc) defined and the order in which they are executed (usually in jobs, stages). These tools such as Jenkins, Bamboo, Hudson are good at keeping this configuration and visualizing the progress during a build. This task for the code quality checks will (if you define the sonar properties in a pom.xml file) now be delegated to the Maven build. Having a separate CI tool to do this, allows you to implement a loose coupling between the tools used to execute the build and the source code.
Code Compliance Inspector
You can use the AIA Code Compliance Inspector (CCI). Using the Code Compliance Inspector allows you to define XPath expressions to do checks. You can only check a single file at a time and JDeveloper 184.108.40.206 or later is required (see here). You can call the Code Compliance Inspector from within JDeveloper. Read more here
You can use the following SonarQube plugin to put the Code Compliance Inspector output in SonarQube.
Oracle JDeveloper comes with its own audit framework called OJAudit. There is a plug-in available to put the ojaudit output in SonarQube. In order to use OJAudit, you should define your own rules using Java code. For ADF there is already a set of rules available. You can see how this works here. In the below picture you can see an example on how you can give suggestions to fix issues as part of the rules.
In order to get this working, as you can see from the (4 part) tutorial, you have to do several things such as (but not limited to): create a JDeveloper extension project, write your audit rules in Java, packaging the audit rules, making the audit rules available on your SonarQube server which requires an Oracle home since it is ojaudit you will be using. Of course as described in this post, you also need to do the described configuration of your CI tool and SonarQube.
You can create something similar for SOA/BPM/OSB and other components. This has the benefit that it can also be used within JDeveloper and not only in SonarQube. Also you can check references to files and consistency between files since the rules will be applied on application level.