Wednesday, July 14, 2010

Perl SOAP Interface to Jira (part II)

A while ago, we wrote a bit of Perl code that uses Jira's SOAP interface to log bugs, add comments, update tickets, and do other fun stuff. I recently extended this to get the current status of an issue out of Jira. We use this to look for bugs that are closed that we're still updating (whoops!).

Here's the code:
######################################################################
# Issue a request to the Jira server and get a response.
#
# @param cmd The name of the command being sent
# @param checkResult Whether or not to check the result of the command
# @param params The parameters of that command
#
# @return The result of the command
##
sub _request {
my ($self, $cmd, $checkResult, $params) = assertMinArgs(3, @_);
my $soap = SOAP::Lite->proxy(
"https://jira.permabit.com/rpc/soap/jirasoapservice-v2?wsdl");
my $auth = $soap->login($self->{jiraUser}, $self->{jiraPwd});
my $s = SOAP::Serializer->new;
my $doThis;
if ($cmd eq "addComment") {
$doThis = $soap->$cmd($auth->result(), $params->{'issue'},
$params->{'comment_obj'});
} elsif ($cmd eq "getComponents") {
$doThis = $soap->$cmd($auth->result(), $params->{'project'});
} elsif ($cmd eq "getStatuses") {
$doThis = $soap->$cmd($auth->result());
} elsif ($cmd eq "createIssue") {
$doThis = $soap->$cmd($auth->result(), $params->{'issueDef'});
} elsif ($cmd eq "updateIssue") {
$doThis = $soap->$cmd($auth->result(), $params->{'issue'},
[$params->{'rfv'}]);
} elsif ($cmd eq "getIssueById") {
$doThis = $soap->$cmd($auth->result(), $params->{'issueId'});
} elsif ($cmd eq "getIssue") {
$doThis = $soap->$cmd($auth->result(), $params->{'issueKey'});
} elsif ($cmd eq "getStatuses") {
$doThis = $soap->$cmd($auth->result(), $params->{'issueKey'});
} elsif ($cmd eq "getVersions") {
$doThis = $soap->$cmd($auth->result(), $params->{'project'});
} elsif ($cmd eq "getIssuesFromFilter") {
$doThis = $soap->$cmd($auth->result(), $params->{'filterId'});
} else {
croak("Unexpected command: $cmd");
}
if ($checkResult && defined $doThis->faultcode) { # whoops something went wrong
croak("Error running command: $cmd\nGot: " . $doThis->faultstring);
}
return $doThis;
}


#####################################################################
# Get issue Status by key
#
# @param params{issueKey}
#
# @return The jira issue number
##
sub getIssueStatus {
my ($self, %params) = assertMinArgs(1, @_);
$params{issueKey} ||= '';
my %issue;
$issue{issueKey} = SOAP::Data->type(string => $params{issueKey});
my $jStatuses = $self->_request('getStatuses',1);
my $jIssue = $self->_request('getIssue', 1, \%issue);
my $jIssueStatusId = $jIssue->result()->{'status'};
my $jIssueCurrStatus;
foreach my $status (@{$jStatuses->result()}) {
if ($status->{'id'} eq $jIssueStatusId) {
$jIssueCurrStatus = $status->{'name'};
}
}
return $jIssueCurrStatus;
}


The first method is what actually submits the SOAP-encoded request to Jira. There are different request types with different parameters, but the ones were interested in are:
getStatuses: takes in the authentication token only, and returns all statuses defined in Jira (regardless of project)
getIssue: given the authentication token and an issue key (the thing you see in the UI: e.g., "QA-1"), this returns the status. Jira returns the ID of the status - for example, "1" - and we use the statuses we grabbed to translate that to a human-readable status name - for example, "open".

Once we have the status we can do things like automatically reopen issues if we're getting logs for an occurrence (hey, it must have happened again, so why not reopen the issue?).

You may choose to do this differently, but hopefully it will give you some pointers on how to handle the Jira interface.

No comments:

Post a Comment