/** *# Copyright 2016 Infobip # # 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 com.infobip.jira; import com.atlassian.applinks.api.*; import com.atlassian.applinks.api.application.jira.JiraApplicationType; import com.atlassian.sal.api.net.ResponseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.infobip.infrastructure.ObjectMapperFactory; import java.io.IOException; import java.time.LocalDate; import java.util.*; import static com.atlassian.sal.api.net.Request.MethodType; /** * @see <a href="https://docs.atlassian.com/jira/REST/6.4/">JIRA 6.4 REST API documentation</a> */ public class JiraService { private final ApplicationLinkService applicationLinkService; private final ObjectMapper objectMapper; public JiraService(ApplicationLinkService applicationLinkService) { this.applicationLinkService = applicationLinkService; this.objectMapper = ObjectMapperFactory.getInstance(); this.objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); } Optional<SerializedVersion> findVersion(ProjectKey projectKey, String name) { return getVersions(projectKey).stream() .filter(version -> Objects.equals(name, version.getName())) .findFirst(); } SerializedVersion createJiraVersion(SerializedVersion version) { String responseJson = executeJsonHttpRequest(MethodType.POST, "/rest/api/2/version", version); return toObject(responseJson, SerializedVersion.class); } void addVersionToIssues(String versionName, ProjectKey projectKey, List<IssueKey> issueKeys) { for (IssueKey issueKey : issueKeys) { String body = String.format( "{\"update\":{\"fixVersions\":[{\"add\":{\"name\":\"%s\",\"project\":\"%s\"}}]}}", versionName, projectKey.getValue()); executeJsonHttpRequest(MethodType.PUT, "/rest/api/2/issue/" + issueKey, body); } } void releaseVersion(SerializedVersion version, LocalDate releaseDate) { String body = String.format( "{\"released\":true,\"releaseDate\":\"%s\"}", releaseDate); executeJsonHttpRequest(MethodType.PUT, "/rest/api/2/version/" + version.getId(), body); } private List<SerializedVersion> getVersions(ProjectKey projectKey) { String url = String.format("/rest/api/2/project/%s/versions", projectKey.getValue()); String versionsJson = executeJsonHttpRequest(MethodType.GET, url); try { return objectMapper.readValue(versionsJson, new TypeReference<List<SerializedVersion>>() {}); } catch (IOException e) { throw new JiraServiceException("Failed ", e); } } private ApplicationLinkRequestFactory getJiraApplicationLinkRequestFactory() { ApplicationLink applicationLink = applicationLinkService.getPrimaryApplicationLink(JiraApplicationType.class); if (applicationLink == null) { throw new IllegalStateException("Primary JIRA application link does not exist!"); } return applicationLink.createAuthenticatedRequestFactory(); } private String executeJsonHttpRequest(MethodType methodType, String url, Object body) { return executeJsonHttpRequest(methodType, url, toJson(body)); } private String executeJsonHttpRequest(MethodType methodType, String url, String body) { try { return getJiraApplicationLinkRequestFactory().createRequest(methodType, url) .setHeader("Content-Type", "application/json") .setRequestBody(body).execute(); } catch (CredentialsRequiredException | ResponseException e) { throw new JiraServiceException("Failed to create request " + methodType + " " + url + " " + body, e); } } private String executeJsonHttpRequest(MethodType methodType, String url) { try { return getJiraApplicationLinkRequestFactory().createRequest(methodType, url) .setHeader("Content-Type", "application/json").execute(); } catch (CredentialsRequiredException | ResponseException e) { throw new JiraServiceException("Failed to create request " + methodType + " " + url, e); } } private String toJson(Object value) { try { return objectMapper.writeValueAsString(value); } catch (JsonProcessingException e) { throw new JiraServiceException("Failed to write to json " + value, e); } } private <T> T toObject(String json, Class<T> objectClass) { try { return objectMapper.readValue(json, objectClass); } catch (IOException e) { throw new JiraServiceException("Failed to deserialize " + json + " to " + objectClass, e); } } }