A java template: build, report and deploy
Template
Yes a template for a java repository to speed up the CI/CD part. Nothing exciting but while building my latest project there were some pieces of the puzzle that were missing and frustrating. If I had a template, it would have shaven a day off building the damn repo.
So I thought, why not make into a template and share the missing pieces of the puzzle.
The tools
To make it very brief, the template foresees solutions for the following technologies:
- Jenkins
- Kubernetes
- Maven / Takari
- Nexus
- Sonarqube
- Metrics & logstash
Takari
Takari is a tool that you can install if you need to use maven but it is not present on the target system. When you install the tool, it will install a wrapper with all the necessary functionality of maven inside the repository.
So how would you install it on your own repository ? It’s quite simple, make sure you are in the root folder of your project and execute the following command
mvn -N io.takari:maven:wrapper
After a couple of seconds the wrapper is installed and you can execute commands using the “./mvnw” executable.
Running a unit test will become
./mvnw test
Kubernetes
The repository foresees 2 templates for AKS. The first one is to create the namespace, the second one is to deploy the actual docker.
On the container part I did specify some resource limitations. Resource limitations can be specified with the following configuration
containers:
-
image: PROJECTCONTAINERREGISTRY/PROJECTNAME:__COMMIT_ID__
imagePullPolicy: Always
name: PROJECTNAME
resources:
limits:
cpu: 2000m
memory: 4096Mi
requests:
cpu: 500m
memory: 2096Mi
I would revise these values depending on the resources your project is consuming.
Jacoco and Sonarqube
As good developers we make sure we have 80% or more code coverage.
Or was it 50 😂 ?
Anyway, I used Jacoco to generate the reports and wanted to upload those reports to Sonarqube. It took me a while to get this configuration working properly.
So first let’s look at Jacoco. In the pom you will need to configure the Jacoco plugin both in the build and in the reporting section. Have a look in the repository for all configuration parameters.
On Jenkins we need to make sure that the Jacoco plugin has been installed. Next we can run the tests and create the reports.
stage ('Run unit test'){
steps {
sh './mvnw test'
step( [$class: 'JacocoPublisher',
exclusionPattern: '**/*Exception*,**/*Configuration*,**/ApiApplication*,**/*Test*'] )
}
}
If all is well Jenkins will now generate the reports. It will look something like this on the build page
Now let’s put everything in Sonarqube so we can have a full report on our code there. In the root directory of the project we need to configure “sonar-project.properties”. The file will look like this
sonar.language=java
sonar.projectKey=DummyKey
sonar.projectName=DummyProject
sonar.projectVersion=1.0.0
sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.binaries=target/
sonar.java.binaries=target/classes
sonar.jacoco.reportPath=target/coverage-reports/jacoco-unit.exec
sonar.java.coveragePlugin=jacoco
sonar.dynamicAnalysis=reuseReports
sonar.surefire.reportsPath=target/surefire-reports
In the Jenkins pipeline script we will trigger the build using the following commands
stage ('SonarQube analysis') {
steps {
script {
scannerHome = tool name: 'sonarqube', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
}
withSonarQubeEnv('sonarqube') {
sh "${scannerHome}/bin/sonar-scanner -X"
}
}
}
In my case we have configured the username and password inside of Jenkins so that we do not have to configure this for each build and expose it in the repositories.
If you then go to Sonarqube you will find a more in depth explanation of the coverage.
Nexus
Don’t do manual versioning of JARs. Ever ! Please rely on a tool. No it doesn’t need to be nexus (a good alternative might be Artifactory) but let’s do Nexus for now as it rather widely used.
Let’s configure the pom first. First you will need to configure the distribution management by providing the url and telling maven what the release and the snapshot endpoint is.
<distributionManagement>
<repository>
<id>nexus</id>
<name>Releases</name>
<url>https://xxxxx</url>
</repository>
<snapshotRepository>
<id>nexus</id>
<name>Snapshot</name>
<url>https://xxxx</url>
</snapshotRepository>
</distributionManagement>
Next we will need “settings.xml”. Important in this file is the authentication. This is done by configuring the servers sections. You need to provide a username and password as given by your nexus administrator.
<servers>
<server>
<id>nexus</id>
<username>USERNAME</username>
<password>{ENCPASSWORD}</password>
</server>
</servers>
Please make sure to encrypt the password. The master encryption password goes into the “settings-security.xml”
Metrics
Part of the repository is also the “ProjectMetrics” class. I think it is always prudent to show how well your code is performing. These metrics can also be exported and you can create some fancy reports on top.
So how does it work?
The following snippet will give an insight on the metrics package.
public class ProjectMetrics {
private static final Logger log = LoggerFactory.getLogger(ProjectMetrics.class);
...private final MetricRegistry metricRegistry;
private final Meter messageRate;
private ProjectMetrics() {
this.metricRegistry = new MetricRegistry();
messageRate = metricRegistry.meter("allMessages");
So basically we can create different types of metrics and couple them to the registry.
Next you can increase the message rate by calling the “mark” method for each message.
You can find the full usage description here.
Conclusion
Well I hope the repository gives you a good starting point or at least gives you some insights in the release part of java code. As always, the full repository can be found on my github page.