Java tutorial
/* * Copyright 2015 Hao Cheng Lee * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package hudson.plugins.jira; import com.atlassian.jira.rest.client.api.JiraRestClient; import com.atlassian.jira.rest.client.api.RestClientException; import com.atlassian.jira.rest.client.api.domain.*; import com.atlassian.jira.rest.client.api.domain.input.IssueInput; import com.atlassian.jira.rest.client.api.domain.input.IssueInputBuilder; import com.atlassian.jira.rest.client.api.domain.input.TransitionInput; import com.atlassian.jira.rest.client.api.domain.input.VersionInput; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.apache.http.client.fluent.Content; import org.apache.http.client.fluent.Request; import org.apache.http.client.utils.URIBuilder; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import static java.util.logging.Level.WARNING; public class JiraRestService { private static final Logger LOGGER = Logger.getLogger(JiraRestService.class.getName()); public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd"); /** * Base URI path for a REST API call. It must be relative to site's base * URI. */ public static final String BASE_API_PATH = "rest/api/2"; private final URI uri; private final JiraRestClient jiraRestClient; private final ObjectMapper objectMapper; private final String authHeader; private final String baseApiPath; private final int timeout; @Deprecated public JiraRestService(URI uri, JiraRestClient jiraRestClient, String username, String password) { this(uri, jiraRestClient, username, password, JiraSite.DEFAULT_TIMEOUT); } public JiraRestService(URI uri, JiraRestClient jiraRestClient, String username, String password, int timeout) { this.uri = uri; this.objectMapper = new ObjectMapper(); this.timeout = timeout; final String login = username + ":" + password; try { byte[] encodeBase64 = Base64.encodeBase64(login.getBytes("UTF-8")); this.authHeader = "Basic " + new String(encodeBase64, "UTF-8"); } catch (UnsupportedEncodingException e) { LOGGER.warning("jira rest encode username:password error. cause: " + e.getMessage()); throw new RuntimeException("failed to encode username:password using Base64"); } this.jiraRestClient = jiraRestClient; final StringBuilder builder = new StringBuilder(); if (uri.getPath() != null) { builder.append(uri.getPath()); if (!uri.getPath().endsWith("/")) { builder.append('/'); } } else { builder.append('/'); } builder.append(BASE_API_PATH); baseApiPath = builder.toString(); } public void addComment(String issueId, String commentBody, String groupVisibility, String roleVisibility) { final URIBuilder builder = new URIBuilder(uri) .setPath(String.format("%s/issue/%s/comment", baseApiPath, issueId)); final Comment comment; if (StringUtils.isNotBlank(groupVisibility)) { comment = Comment.createWithGroupLevel(commentBody, groupVisibility); } else if (StringUtils.isNotBlank(roleVisibility)) { comment = Comment.createWithRoleLevel(commentBody, roleVisibility); } else { comment = Comment.valueOf(commentBody); } try { jiraRestClient.getIssueClient().addComment(builder.build(), comment).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client add comment error. cause: " + e.getMessage(), e); } } public Issue getIssue(String issueKey) { try { return jiraRestClient.getIssueClient().getIssue(issueKey).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get issue error. cause: " + e.getMessage(), e); return null; } } public List<IssueType> getIssueTypes() { try { return Lists.newArrayList( jiraRestClient.getMetadataClient().getIssueTypes().get(timeout, TimeUnit.SECONDS)); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get issue types error. cause: " + e.getMessage(), e); return Collections.emptyList(); } } public List<String> getProjectsKeys() { Iterable<BasicProject> projects = Collections.emptyList(); try { projects = jiraRestClient.getProjectClient().getAllProjects().get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get project keys error. cause: " + e.getMessage(), e); } final List<String> keys = new ArrayList<String>(); for (BasicProject project : projects) { keys.add(project.getKey()); } return keys; } public List<Issue> getIssuesFromJqlSearch(String jqlSearch, Integer maxResults) { try { final SearchResult searchResult = jiraRestClient.getSearchClient() .searchJql(jqlSearch, maxResults, 0, null).get(timeout, TimeUnit.SECONDS); return Lists.newArrayList(searchResult.getIssues()); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get issue from jql search error. cause: " + e.getMessage(), e); return Collections.emptyList(); } } public List<Version> getVersions(String projectKey) { final URIBuilder builder = new URIBuilder(uri) .setPath(String.format("%s/project/%s/versions", baseApiPath, projectKey)); List<Map<String, Object>> decoded = Collections.emptyList(); try { URI uri = builder.build(); final Content content = buildGetRequest(uri).execute().returnContent(); decoded = objectMapper.readValue(content.asString(), new TypeReference<List<Map<String, Object>>>() { }); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get versions error. cause: " + e.getMessage(), e); } final List<Version> versions = new ArrayList<Version>(); for (Map<String, Object> decodedVersion : decoded) { final DateTime releaseDate = decodedVersion.containsKey("releaseDate") ? DATE_TIME_FORMATTER.parseDateTime((String) decodedVersion.get("releaseDate")) : null; final Version version = new Version(URI.create((String) decodedVersion.get("self")), Long.parseLong((String) decodedVersion.get("id")), (String) decodedVersion.get("name"), (String) decodedVersion.get("description"), (Boolean) decodedVersion.get("archived"), (Boolean) decodedVersion.get("released"), releaseDate); versions.add(version); } return versions; } public Version addVersion(String projectKey, String versionName) { final VersionInput versionInput = new VersionInput(projectKey, versionName, null, null, false, false); try { return jiraRestClient.getVersionRestClient().createVersion(versionInput).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client add version error. cause: " + e.getMessage(), e); return null; } } public void releaseVersion(String projectKey, Version version) { final URIBuilder builder = new URIBuilder(uri) .setPath(String.format("%s/version/%s", baseApiPath, version.getId())); final VersionInput versionInput = new VersionInput(projectKey, version.getName(), version.getDescription(), version.getReleaseDate(), version.isArchived(), version.isReleased()); try { jiraRestClient.getVersionRestClient().updateVersion(builder.build(), versionInput).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client release version error. cause: " + e.getMessage(), e); } } public BasicIssue createIssue(String projectKey, String description, String assignee, Iterable<String> components, String summary) { IssueInputBuilder builder = new IssueInputBuilder(); builder.setProjectKey(projectKey).setDescription(description).setIssueTypeId(1L) // BUG .setSummary(summary); if (!assignee.equals("")) builder.setAssigneeName(assignee); if (Iterators.size(components.iterator()) > 0) { builder.setComponentsNames(components); } final IssueInput issueInput = builder.build(); try { return jiraRestClient.getIssueClient().createIssue(issueInput).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "JIRA REST createIssue error: " + e.getMessage(), e); return null; } } public User getUser(String username) { try { return jiraRestClient.getUserClient().getUser(username).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get user error. cause: " + e.getMessage(), e); return null; } } public void updateIssue(String issueKey, List<Version> fixVersions) { final IssueInput issueInput = new IssueInputBuilder().setFixVersions(fixVersions).build(); try { jiraRestClient.getIssueClient().updateIssue(issueKey, issueInput).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client update issue error. cause: " + e.getMessage(), e); } } public void setIssueLabels(String issueKey, List<String> labels) { final IssueInput issueInput = new IssueInputBuilder().setFieldValue(IssueFieldId.LABELS_FIELD.id, labels) .build(); try { jiraRestClient.getIssueClient().updateIssue(issueKey, issueInput).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client update labels error for issue " + issueKey, e); } } public Issue progressWorkflowAction(String issueKey, Integer actionId) { final TransitionInput transitionInput = new TransitionInput(actionId); final Issue issue = getIssue(issueKey); try { jiraRestClient.getIssueClient().transition(issue, transitionInput).get(timeout, TimeUnit.SECONDS); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client process workflow action error. cause: " + e.getMessage(), e); } return issue; } public List<Transition> getAvailableActions(String issueKey) { final Issue issue = getIssue(issueKey); try { final Iterable<Transition> transitions = jiraRestClient.getIssueClient().getTransitions(issue) .get(timeout, TimeUnit.SECONDS); return Lists.newArrayList(transitions); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get available actions error. cause: " + e.getMessage(), e); return Collections.emptyList(); } } public List<Status> getStatuses() { try { final Iterable<Status> statuses = jiraRestClient.getMetadataClient().getStatuses().get(timeout, TimeUnit.SECONDS); return Lists.newArrayList(statuses); } catch (Exception e) { LOGGER.log(WARNING, "jira rest client get statuses error. cause: " + e.getMessage(), e); return Collections.emptyList(); } } public List<Component> getComponents(String projectKey) { final URIBuilder builder = new URIBuilder(uri) .setPath(String.format("%s/project/%s/components", baseApiPath, projectKey)); try { final Content content = buildGetRequest(builder.build()).execute().returnContent(); final List<Map<String, Object>> decoded = objectMapper.readValue(content.asString(), new TypeReference<List<Map<String, Object>>>() { }); final List<Component> components = new ArrayList<Component>(); for (final Map<String, Object> decodeComponent : decoded) { BasicUser lead = null; if (decodeComponent.containsKey("lead")) { final Map<String, Object> decodedLead = (Map<String, Object>) decodeComponent.get("lead"); lead = new BasicUser(URI.create((String) decodedLead.get("self")), (String) decodedLead.get("name"), (String) decodedLead.get("displayName")); } final Component component = new Component(URI.create((String) decodeComponent.get("self")), Long.parseLong((String) decodeComponent.get("id")), (String) decodeComponent.get("name"), (String) decodeComponent.get("description"), lead); components.add(component); } return components; } catch (Exception e) { LOGGER.log(WARNING, "jira rest client process workflow action error. cause: " + e.getMessage(), e); return Collections.emptyList(); } } private Request buildGetRequest(URI uri) { return Request.Get(uri).connectTimeout(timeoutInMiliseconds()).socketTimeout(timeoutInMiliseconds()) .addHeader("Authorization", authHeader).addHeader("Content-Type", "application/json"); } protected int timeoutInMiliseconds() { return (int) TimeUnit.SECONDS.toMillis(timeout); } public String getBaseApiPath() { return baseApiPath; } /** * Get User's permissions * */ public Permissions getMyPermissions() throws RestClientException { return jiraRestClient.getMyPermissionsRestClient().getMyPermissions(null).claim(); } }