9 Temmuz 2012 Pazartesi

Groovy Development in JIRA

The task at hand was pretty simple - write a JIRA script to automatically handle e-mails that came in on a certain address, looking at the attachments, and then processing the e-mail as required.  However, with the minimal amount of documentation available on-line, it ended up taking a little bit longer than I had initially expected.  And so, I've decided to document my experiences here so that if anyone in the future needs to do something similar, they'll have at least one resource to look at.


Step 1. ScriptRunner
Due to the foresight of our QA Manager, (thanks man!) our JIRA environment had already been loaded with the Groovy ScriptRunner.  Consequently, I pretty much had the scripting language decided for me.  I set up a development instance of a JIRA server so that I wouldn't disrupt people's actual work while I was testing, and got to work.

Step 2. Working with JIRA Issues in Groovy
Our JIRA system was already set up to create issues based on e-mails delivered to the appropriate address, so now it was a matter of writing a script to process these issues once they came through the system. I knew that I was going to have to work with attachments, as well as add comments, and send e-mails, etc... I also wanted to be able to log information as I was working on the script to JIRA's default catalina.out file, so I went about finding the appropriate methods for accomplishing these things.

After some searching for the correct syntax I determined what I needed in order to manage logging, comments, and attachments:

import org.apache.log4j.Category;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.comments.CommentManager;
import com.atlassian.jira.issue.AttachmentManager;
import com.atlassian.jira.issue.attachment.Attachment;

// Logger

def Category log = Category.getInstance("com.onresolve.jira.groovy.PostFunction");

// Set the logging level to DEBUG

log.setLevel(org.apache.log4j.Level.DEBUG);

// Set up a comment manager and an attachment manager, as we will need to use these for working with the issues

CommentManager comment = ComponentManager.getInstance().getCommentManager();
AttachmentManager attachments = ComponentManager.getInstance().getAttachmentManager();

It turns out that the JIRA libraries have helper classes called CommentManager and AttachmentManager built in to make this process easier, so I set up instances of those objects for later use in the script.
I also wanted to log a debug message to catalina.out every time that I made a comment on the issue so that I could see the progress while I was tailing the file. To make this less of a headache, I created a method to manage this for me:
def doComment(commentManager, logger, issue, currentUser, text) {
  log.debug "Script Processing - ${issue.key} - Adding Comment - ${text}";
  comment.create(issue, currentUser, text, true);
}
Creating a comment requires an instance of the issue that we are working on (which the Groovy script is nice enough to give us with an 'issue' variable) as well as the username creating the comment, and the text of the comment.  I passed these into my method, along with the CommentManager and the Logger which I'd previouly instantiated, and used this method to create all of my comments.
Step 3. Working with Attachments This was probably the most non-intuitive part of the process and the main reason that I decided to write this entry. The first issue that had me scratching my head was this: Attachments in JIRA are not available when the issue is first created. We actually had to work around this process by activating this script when the issue was moved into In Progress as a result - so that I would be able to retrieve the attachments from the issue. Retrieving the list of attachments from the issue turned out to be fairly easy:
List attachments = attachmentManager.getAttachments(issue);

However, when it came to actually reading the contents of the attachment to the issue, the built-in Attachment Object in the JIRA library didn't seem to be of much help.

Methods were provided for finding the author, MIME Type, date created, etc... about the attachment, but nothing about the getting the actual text of the attachment itself.  This, however, was the entire reason that I needed the attachment object - I needed to be able to read the contents of a document attached to the original e-mail, and do the processing based on that.
 Luckily, I was able to find the file location on my development JIRA server where the attachments had been saved.  For example, it appeared that all of my attachments were saved in the following location on my server (this will be different based on which directory you have JIRA installed to, of course):
/usr/jira/data/attachments/

In that location were several directories, one for each of the different projects created on this JIRA instance.  Inside of those directories were more folders for each of the issues that had been created with attachments.  Using this information, I was able to determine the actual file path based on the issue that I was working with. From that point,it was a matter of reading the attachment file into a string and doing the appropriate parsing based on that data.
List attachments = attachmentManager.getAttachments(issue);

if (!attachments.isEmpty()) {
  for (Attachment a in attachments) {
    String filePath = "/usr/jira/data/attachments/PROJECT_ID/" + issue.getKey() + '/' + a.getId();
    def attachmentFile = new File(filePath);
    String attachmentContents = attachmentFile.text;

    // Do regex processing on the attachmentContents to determine what needs to be done
  }
}
Step 4. E-mails The last step of the process was to send an e-mail in cases where the attachment was unable to be parsed, or when some other issue didn't allow us to resolve this issue appropriately. I was able to write a simple method to handle this, using the documentation available on-line:
import com.atlassian.mail.Email;
import com.atlassian.mail.server.MailServerManager;
import com.atlassian.mail.server.SMTPMailServer;

def sendEmail(emailAddr, subject, body) {
  SMTPMailServer mailServer = ComponentManager.getInstance().getMailServerManager().getDefaultSMTPMailServer();

  if (mailServer) {
    Email email = new Email(emailAddr);
    email.setSubject(subject);
    email.setBody(body);
    mailServer.send(email);
  } else {
    // Problem getting the mail server from JIRA configuration, log this error
  }
}
Step 5. Finishing Up
These were the main issues I ran across while writing this script - and, as I mentioned earlier, tutorials on these nuances appear to be nearly non-existent on-line.  Hopefully, if anyone runs into these problems in the future this article will help them through the process.If you're working on JIRA/Groovy development and are looking for some guidance from someone's who has been there, or if you have questions about this tutorial, please feel free to connect with me on this site 
and send me a message, or comment on this blog.  I'm happy to answer anything that I can.

reference

1 yorum:

Adsız dedi ki...

Paylaşımlarınızı beğenerek takip etmekteyim . Dell dizüstü tamir olarak bu güzel paylaşımlarınızın devamını bekleriz .

Yorum Gönder