JIRA Plugins: Data model access

In previous entries of this blog, we have shown how to create Atlassian plugins for Atlassian JIRA by extending built-in search functionallity with JQL functions. This new post will provide you with some information regarding OfBiz in order to access JIRA’s data model directly. Our goal will be to create a JQL function that can use any records stored in JIRA (or Greenhopper) data model.

¿What is Ofbiz?

Apache Ofbiz (The Apache Open For Business Project) is a java framework by the Apache Foundation that provides corporate tools automation. It offers corporate tools such as: ERP, CRM, etc. So, what does this have to do with JIRA? Traditionally, JIRA has used OfBiz as a Database abstraction layer to access records as map of fields (as an instance of the class GenericValue). The main benefit of this approach is keeping forward compatibility even if the database schema changes.

The matching betweern logical model and database schema is performed by defining OfBiz Entities (tables) as a set of Fields (columns) with a strong data type. This model map is stored as a set of XML documents (for different DB servers) in a folder named entitydefs inside a JIRA installation directory. The file entitymodel.xml stores all entities available via Ofbiz. This is a little sample from this file:

Ofbiz is a complex tool and it’s API is out of the scope of this article so we will focus on an interface used by JIRA when accessing data: Delegator. This interface provides all required methods to search for different criteria.

Accesessing OfBiz from JIRA

JIRA public API contains interfaces to access OfBiz from plugins. com.atlassian.jira.ofbiz.OfBizDelegator is a wrapper interface to hide OfBiz Delegator. In the following snippet you can see how to retrieve an object of this interface:

This interface provides methods to explore entities and fileds from JIRA datamodel. Bear in mind that values for fileds are usually indexes from some other tables. For instance, in order to retireve all issues of type Bug (assuming the numerical value for Bug is 1) we can use this code:

Conditional queries

So far we have created simple queries using OfBizDelegator but there is no way to use complex logic using these methods. In order to combine different fields and logical conditions we will need some other classes:

JQL WAS operator

From version 4.3 on, JIRA provides a new operator to search in the past using JQL: WAS. It is identical as operator IS except it also checks in the issue‘s histoy. For example, the following JQL sentence would return all issues ever assigned to the current user:

assignee was currentUser()

In the next section we will try to replicate this functionallity using a JQL function based on OfBiz.

¿IS the user the actual assignee?

Operator IS works as a subset of WAS but schema-wise, queries affect completely different entities. This way, the current assignee for a particular issue is stored in the Issue entity (shown previously).

Now, let’s look into the past…

However, in order to know if a certain user has ever been assigned to a particular issue we need to use another entity that stores previous changes for all issues: ChangeGroupChangeItemView (see the example for Conditional queries). In this case, the helper class EasyMap comes in handy to create a map using constructor arguments.

Author: Eduardo Mayor

Eduardo Mayor is a software engineer with 20+ years of experience. He is also the founder of Novagenia Information Technologies, a company focused on introducing agile methods and tools to companies worldwide.