How to implement an ITS plugin

Purpose

Kobee has a pluggable architecture regarding Issue Tracking Systems. Providers can write their own Issue Tracking System (ITS) Plugins and deploy them so that they will be integrated in Kobee. This document explains how to develop and deploy such a Plugin.

Setting up the Development Environment

The files that you need for writing an Kobee Issue Tracking System plugin are delivered in a .zip file named kobee60_its_plugin.zip.

That zip file has the following directory structure:

  • src/main/java/

    Contains the sources of the JiraITSPlugin, as a sample on how to create your own plugin

  • lib/

    Contains the jar files required to compile and run the JiraITSPlugin

  • tools/

    Contains an Ant and Bnd tool distribution

  • .settings/, .classpath, .project

    Contains Eclipse project settings

  • bnd.bnd

    Metadata file required for the BndTools Eclipse plugin (optional)

  • bnd_kobeeio_sampleits.bnd

    Sample Bnd metadata file describing the Sample ITS Plugin Bundle

  • build.cmd, build.xml

    Build scripts for building the ITS Plugin OSGi Bundles

Do the following to set up your development environment, for example in Eclipse:

  1. Unzip kobee60_its_plugin.zip to a directory with the name you want to use in your Eclipse project.

  2. Open Eclipse and select: New > Java Project.

  3. Select Create project from existing source and browse to the directory where you unzipped the file. If the project name is identical to the root directory of your sources, Eclipse automatically finds the source folders and puts the jar files of the “lib” directory in the project’s classpath.

  4. The Eclipse Project needs to have the following properties:

    • compiler compliance Level must be set to 11

    • Java JDK must be 11 or higher

  5. Optionally, you can install the BndTools Eclipse plugin, and add the BndTools Nature to the Project

Implementation

Basically, you create a class that extends the AbstractITSPlugin class and another class that implements the ITSPluginFactory interface. Next, you implement/override the required methods. As an implementation example you can look at the Jira plugin classes (in particular JiraITSPlugin and JiraITSPluginFactory). A skeleton implementation is provided in the SampleITSPlugin and SampleITSPluginFactory classes.

XyzITSPluginFactory class: Implement ITSPluginFactory

Create a class that implements the ITSPluginFactory interface. The class MUST have a no-argument constructor since this constructor will be called using reflection by Kobee code. Implement the method createITSPlugin() and let it return a fully configured instance of your implementing ITSPlugin class. The ITSPluginConfiguration argument is passed. It can be used to initialize your ITSPlugin object.

XyzITSPlugin: Extend AbstractITSPlugin

Create a class that extends the AbstractITSPlugin class. You could also directly implement the ITSPlugin interface, but this is not recommended. The following methods must be implemented:

List<Issue> getIssues(List<String> issueIds)

This is the most important method to implement: Kobee calls this method to get additional information on issues from the external Issue Tracking System. The method takes a single argument: a List of String Objects that represent the IDs of the Issues that need to be retrieved. The method should return the found issues, as a list of be.ikan.scm4all.plugin.issuetracking.Issue Objects.

All members of the Issue class are String objects and will be shown in Kobee as-is. Therefore, it might be interesting, for example, to look up the description of an issue status (e.g., “RESOLVED”) and put that in the Issue Object, instead of putting the status code (e.g., “3”) in the Issue Object.

List<PropertyInfo> getPropertyInfo()

In this method, you specify which custom properties can/need to be set on the Issue Tracking System plugin. For every property that can be set, you create a be.ikan.scm4all.plugin.issuetracking.util.PropertyInfo object in which you specify:

  • name: the name of the property

  • defaultValue: the default value of the property

  • description: a description of the property

  • required: whether the property is required or optional

  • secured: whether the value of the property is secure.

    If the property is secured, then its value is encrypted in the Kobee database, and when it is shown in the Kobee GUI, its value is masked by asterisks (*)

  • choices: a list of possible predefined values for the property. That list will be shown as a drop-down menu in the Kobee GUI

The method should return a List of PropertyInfo objects that represent the possible properties that can be set on the Issue Tracking System.

void testConnection()

This method should be implemented so that if a connection to the Issue Tracking System can be established using the properties specified, it should return normally, but should throw an IssueTrackingException when a connection cannot be made.

void validate()

This method should validate the values of all properties of the Issue Tracking System, and throw a ValidationException when some of them are invalid.

For example:

  • check whether a property that is set as required actually has a value,

  • check whether a property named “port” that is supposed to have a numeric value doesn’t contain alphanumerical characters,

  • check whether a property doesn’t contain spaces, …​

void addCommentToIssue(String issueId, String comment)

This method will be called by Kobee to add a comment to a property or to change a property of a certain Issue in the Issue Tracking System (so no impact on Kobee). The first argument represents the ID of the Issue, the second represents the comment that is to be added. The idea is to have some tracking in the Issue Tracking System of what is going on in Kobee, e.g., by setting a promotion level property of the Issue, or by adding a comment to the Issue, …​

List<Issue> parseIssues(List<String> vcrCommitMessages)

Probably, this method must not be overridden. This method is implemented in AbstractITSPlugin. It parses the list of Version Control Repository (VCR) commit messages and searches for references to issues by matching regular expression patterns. The patterns are set in the Kobee GUI and can be retrieved by calling the Getter methods: getIssuePattern() and getIssueIdPattern(). The method returns a list of Issue objects that represents the issues parsed from the commit messages.

Getter methods

Some getter methods are defined that can be used to retrieve the standard properties that can be set on any Issue Tracking System. Normally, they do not need to be overridden. Please refer to the chapter on Issue Tracking Systems in the Kobee User Guide for more information on those properties.

The getter methods are:

  • getURL() : returns the URL that should directly link to a detailed view of an Issue

  • getUser() : returns the User name that should be used to connect to the Issue Tracking System

  • getPassword() : returns the password that should be used to connect to the Issue Tracking System

  • getIssuePattern() : returns the Issue Pattern (Regular Expression) that is used to parse issue strings from VCR commit messages

  • getIssueIdPattern() : returns the Issue Id Pattern (Regular Expression) that is used to parse the issue ids from the parsed issue strings that were found in the VCR commit messages

  • getProperties() : returns a Map that contains the names and values of the custom properties that are set on the Issue Tracking System

Create a .bnd metadata file for your plugin

The Kobee Server runs as an OSGi bundle within Karaf, an OSGi container. As a consequence, all components that the Kobee Server uses, must also run as an OSGi bundle within Karaf, and thus also your custom ITS Plugin. This means your ITS Plugin classes must be packaged inside an OSGi bundle. A build script is provided that does just that, but it needs a .bnd file that contains the metadata information about your ITS Plugin OSGi bundle.

A sample .bnd metadata file is provided for the SampleITSPlugin : bnd_kobeeio_sampleits.bnd

Bundle-Version: 6.0.0
Bundle-Name: Kobee Sample ITS Plugin Bundle
Bundle-SymbolicName: io.kobee.its.sample

Private-Package: io.kobee.its.sample

Export-Package: io.kobee.its.sample

Bundle-ClassPath: .

So, suppose your plugin class is named com.example.xyz.XyzITSPlugin, then you can create a .bnd file named bnd_xyzits.bnd with contents :

Bundle-Version: 1.0.0
Bundle-Name: Xyz ITS Plugin Bundle
Bundle-SymbolicName: com.example.xyz

Private-Package: com.example.xyz

Export-Package: com.example.xyz

Bundle-ClassPath: .

If your plugin depends on additional jar files, then adding those jars to the lib/ folder will cause the build script to use these jars when building the OSGi bundle. However, you must make sure these jars are valid OSGi bundles, since they will also need to be deployed to the Karaf runtime of the Kobee Server. Normally, the Bnd tool that is used to generate the OSGi bundle will detect the packages that your ITS Bundle classes depend on and generate the proper OSGi metadata for it. In case this doesn’t work properly, or if you need more control over the generated "Import-Package" directives, you can add an "Import-Package" directive to the .bnd file. Please consult the documentation of the Bnd tool for detailed information : https://bnd.bndtools.org/

Building the Plugin

Before you can launch the build scripts that will generate the OSGi bundles for your ITS Plugin, you must edit the build.cmd file and set the JAVA_HOME that will be used to run the build.xml Ant script. The version of this Java runtime must be 11. For example :

@SET JAVA_HOME=D:\java\jdk-11.0.19+7

Launch the build.cmd script in a Command Prompt, or as an External Tool in Eclipse. This will generate for each .bnd file in the root directory of the Project an OSGi bundle in the dist/ directory.

Deploying the Plugin to Kobee

In the following section, we assume that you installed Kobee in the folder KOBEE_HOME, and that Tomcat is installed in the folder TOMCAT_HOME.

To use your plugin in Kobee, you need to do the following:

  1. Shut down Tomcat. Leave the Kobee Server running.

  2. Copy all 3rd party jars that your plugin needs to TOMCAT_HOME/webapps/alm/WEB-INF/lib

  3. Copy the generated OSGi plugin bundle jar from dist/ to TOMCAT_HOME/webapps/alm/WEB-INF/lib

  4. Copy all 3rd party jars that your plugin needs to KOBEE_HOME/daemons/server/karaf/deploy

    All 3rd party jars that your plugin needs must be valid OSGi bundles

  5. Copy the generated OSGi plugin bundle jar from dist/ to KOBEE_HOME/daemons/server/karaf/deploy

  6. Start Tomcat. Make sure the Kobee Server is still running.

  7. In Kobee, create a new Issue Tracking System and set the Plugin Factory Class to the fully qualified class name of your implementation of the ITSPluginFactory interface. In the JIRA example, this would be be.ikan.scm4all.plugin.issuetracking.jira.JiraITSPluginFactory.

  8. Link the created Issue Tracking System to a Project and add the Issue Phase to existing Levels (if needed).

For further information on how to use Issue Tracking in Kobee, please refer to the Kobee User Guide.