net.thucydides.plugins.jira.service.JiraIssueTracker Maven / Gradle / Ivy
package net.thucydides.plugins.jira.service;
import ch.lambdaj.function.convert.Converter;
import com.google.inject.Inject;
import net.thucydides.plugins.jira.model.IssueComment;
import net.thucydides.plugins.jira.model.IssueTracker;
import net.thucydides.plugins.jira.model.IssueTrackerUpdateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import thucydides.plugins.jira.soap.RemoteComment;
import thucydides.plugins.jira.soap.RemoteIssue;
import thucydides.plugins.jira.soap.RemoteNamedObject;
import thucydides.plugins.jira.soap.RemoteStatus;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static ch.lambdaj.Lambda.convert;
/**
* Update comments in JIRA issues with links to Thucydides reports.
* This plugin will use the JIRA username and password provided in the jira.username
* and jira.password system properties. The URL of the JIRA instance should be provided
* using the jira.url system property.
*/
public class JiraIssueTracker implements IssueTracker {
private final Logger logger;
private final JIRAConnection jiraConnection;
private final Marker warn = MarkerFactory.getMarker("WARN");
@Inject
public JiraIssueTracker(JIRAConfiguration jiraConfiguration) {
this(LoggerFactory.getLogger(JiraIssueTracker.class), jiraConfiguration);
}
public JiraIssueTracker(Logger logger, JIRAConfiguration jiraConfiguration) {
this.logger = logger;
this.jiraConnection = new JIRAConnection(jiraConfiguration);
}
@Override
public String toString() {
return "Connection to JIRA instance at " + jiraConnection.getJiraWebserviceUrl()
+ " with user " + jiraConnection.getJiraUser();
}
/**
* Add a comment to the specified issue.
* The author is the JIRA user specified in the *jira.user* system property.
*
* @param issueKey the unique key identifying the issue to be commented.
* @param commentText text of the comment.
* @throws IssueTrackerUpdateException
*/
public void addComment(final String issueKey, final String commentText) throws IssueTrackerUpdateException {
try {
String token = jiraConnection.getAuthenticationToken();
RemoteComment comment = newCommentWithText(commentText);
jiraConnection.getJiraSoapService().addComment(token, issueKey, comment);
} catch (IOException exception) {
processJiraException(issueKey, exception);
}
}
private void processJiraException(String issueKey, IOException exception) {
if (noSuchIssue(exception)) {
logger.error("No JIRA issue found with key {}", issueKey);
} else {
throw new IssueTrackerUpdateException("Could not update JIRA using URL ("
+ jiraConnection.getJiraWebserviceUrl() + ")", exception);
}
}
private boolean noSuchIssue(Exception exception) {
return (exception.toString().contains("This issue does not exist"));
}
/**
* Return the comments associated with the specified issue.
*
* @param issueKey Identifies the specified issue.
* @return the list of comments.
* @throws IssueTrackerUpdateException
*/
public List getCommentsFor(String issueKey) throws IssueTrackerUpdateException {
List results = Collections.emptyList();
try {
String token = jiraConnection.getAuthenticationToken();
RemoteComment[] comments = jiraConnection.getJiraSoapService().getComments(token, issueKey);
results = convert(comments, new CommentConverter());
} catch (IOException e) {
processJiraException(issueKey, e);
}
return results;
}
public void updateComment(IssueComment issueComment) {
try {
String token = jiraConnection.getAuthenticationToken();
RemoteComment updatedComment = jiraConnection.getJiraSoapService().getComment(token, issueComment.getId());
updatedComment.setBody(issueComment.getText());
jiraConnection.getJiraSoapService().editComment(token, updatedComment);
} catch (IOException e) {
throw new IssueTrackerUpdateException("Could not update JIRA using URL ("
+ jiraConnection.getJiraWebserviceUrl() + ")", e);
}
}
/**
* Return the current status for a given JIRA issue.
* Note that the status value depends on the issue workflow, so can be very variable.
* @param issueKey
* @return
* @throws IssueTrackerUpdateException
*/
public String getStatusFor(final String issueKey) throws IssueTrackerUpdateException {
String status = null;
try {
String token = jiraConnection.getAuthenticationToken();
RemoteIssue issue = jiraConnection.getJiraSoapService().getIssue(token, issueKey);
checkThatIssueExists(issue, issueKey);
status = getStatusLabel(issue);
} catch (IOException e) {
processJiraException(issueKey, e);
}
return status;
}
public void doTransition(final String issueKey, final String workflowAction) throws IssueTrackerUpdateException {
try {
String token = jiraConnection.getAuthenticationToken();
RemoteIssue issue = jiraConnection.getJiraSoapService().getIssue(token, issueKey);
checkThatIssueExists(issue, issueKey);
String actionId = getAvailableActions(issueKey).get(workflowAction);
if (actionId != null) {
jiraConnection.getJiraSoapService().progressWorkflowAction(token, issueKey, actionId, null);
}
} catch (IOException e) {
processJiraException(issueKey, e);
}
}
private String getStatusLabel(final RemoteIssue issue) {
return getStatusCodeMap().get(issue.getStatus());
}
private Map getAvailableActions(final String issueKey) {
Map availableActionMap = null;
if (availableActionMap == null) {
availableActionMap = new HashMap();
try {
String token = jiraConnection.getAuthenticationToken();
RemoteNamedObject[] actions = jiraConnection.getJiraSoapService().getAvailableActions(token, issueKey);
for(RemoteNamedObject action : actions) {
availableActionMap.put(action.getName(), action.getId());
}
} catch (IOException e) {
processJiraException(issueKey, e);
}
}
return availableActionMap;
}
private Map statusCodeMap = null;
private Map getStatusCodeMap() {
if (statusCodeMap == null) {
statusCodeMap = new HashMap();
try {
String token = jiraConnection.getAuthenticationToken();
RemoteStatus[] statuses = jiraConnection.getJiraSoapService().getStatuses(token);
for(RemoteStatus status : statuses) {
statusCodeMap.put(status.getId(), status.getName());
}
} catch (IOException e) {
throw new IssueTrackerUpdateException("Could not read JIRA using URL ("
+ jiraConnection.getJiraWebserviceUrl() + ")", e);
}
}
return statusCodeMap;
}
private Map statusLabelMap = null;
private String getStatusId(final String statusLabel) {
return getStatusLabelMap().get(statusLabel);
}
private Map getStatusLabelMap() {
if (statusLabelMap == null) {
statusLabelMap = new HashMap();
try {
String token = jiraConnection.getAuthenticationToken();
RemoteStatus[] statuses = jiraConnection.getJiraSoapService().getStatuses(token);
for(RemoteStatus status : statuses) {
statusLabelMap.put(status.getName(), status.getId());
}
} catch (IOException e) {
throw new IssueTrackerUpdateException("Could not read JIRA using URL ("
+ jiraConnection.getJiraWebserviceUrl() + ")", e);
}
}
return statusLabelMap;
}
private void checkThatIssueExists(final RemoteIssue issue, final String issueKey) {
if (issue == null) {
logger.error(warn, "JIRA issue not found for {}",issueKey);
throw new NoSuchIssueException("No issue found for " + issueKey);
}
}
private RemoteComment newCommentWithText(final String commentText) {
RemoteComment comment = new RemoteComment();
comment.setAuthor(jiraConnection.getJiraUser());
comment.setBody(commentText);
return comment;
}
private class CommentConverter implements Converter {
public IssueComment convert(RemoteComment from) {
return new IssueComment(Long.valueOf(from.getId()), from.getBody(), from.getAuthor());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy