Created
March 4, 2021 15:00
-
-
Save rgpower/2241c2b25946191257f54581ff82101e to your computer and use it in GitHub Desktop.
Create Jira tickets, attach images etc, via Java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package utils.jira; | |
| import com.google.gson.GsonBuilder; | |
| import org.asynchttpclient.*; | |
| import org.asynchttpclient.request.body.multipart.FilePart; | |
| import org.asynchttpclient.uri.Uri; | |
| import java.io.*; | |
| import java.nio.charset.StandardCharsets; | |
| import java.util.Collections; | |
| import java.util.List; | |
| import java.util.concurrent.CompletableFuture; | |
| import java.util.logging.Logger; | |
| public class Jira { | |
| private final static Logger logger = Logger.getLogger(Jira.class.getName()); | |
| private final static String JIRA_API_ENDPOINT = System.getenv("CXS_TEST_JIRA_API_ENDPOINT"); | |
| private final static String JIRA_API_TOKEN = System.getenv("CXS_TEST_JIRA_API_TOKEN"); | |
| private final static String JIRA_API_PROJECT = System.getenv("CXS_TEST_JIRA_API_PROJECT"); | |
| static { | |
| assert null != JIRA_API_ENDPOINT; | |
| assert !"".equals(JIRA_API_ENDPOINT); | |
| assert null != JIRA_API_TOKEN; | |
| assert !"".equals(JIRA_API_TOKEN); | |
| } | |
| private final static GsonBuilder gsonBuilder = new GsonBuilder(); | |
| public CompletableFuture<CreateIssueResponse> createJiraIssue(String title, String description) { | |
| return createJiraIssue(title, description, null); | |
| } | |
| public CompletableFuture<CreateIssueResponse> createJiraIssue(String title, String description, String parent) { | |
| CompletableFuture<CreateIssueResponse> cf = new CompletableFuture<>(); | |
| AsyncHttpClient client = new DefaultAsyncHttpClient(); | |
| CreateIssueRequest createIssueRequest = createIssueRequest(title, description, parent); | |
| Request request = new RequestBuilder() | |
| .setMethod("POST") | |
| .setUri(Uri.create(String.format("%s/rest/api/3/issue", JIRA_API_ENDPOINT))) | |
| .setHeader("Authorization", String.format("Basic %s", JIRA_API_TOKEN)) | |
| .setHeader("Content-Type", "application/json") | |
| .setHeader("Accept", "application/json") | |
| .setBody(gsonBuilder.create().toJson(createIssueRequest)) | |
| .build(); | |
| client.executeRequest(request).toCompletableFuture().whenCompleteAsync((response, err) -> { | |
| if (null != err) { | |
| cf.completeExceptionally(err); | |
| close(client); | |
| return; | |
| } | |
| InputStreamReader isr = new InputStreamReader(response.getResponseBodyAsStream()); | |
| CreateIssueResponse createIssueResponse = gsonBuilder.create().fromJson(isr, CreateIssueResponse.class); | |
| cf.complete(createIssueResponse); | |
| close(client); | |
| }); | |
| return cf; | |
| } | |
| public CompletableFuture<AddAttachmentResponseItem> addAttachment(String issue, File file) { | |
| CompletableFuture<AddAttachmentResponseItem> cf = new CompletableFuture<>(); | |
| AsyncHttpClient client = new DefaultAsyncHttpClient(); | |
| Request request = new RequestBuilder() | |
| .setMethod("POST") | |
| .setUri(Uri.create(String.format("%s/rest/api/3/issue/%s/attachments", JIRA_API_ENDPOINT, issue))) | |
| .setHeader("Authorization", String.format("Basic %s", JIRA_API_TOKEN)) | |
| .setHeader("X-Atlassian-Token", "no-check") | |
| .setHeader("Content-Type", "multipart/form-data") | |
| .setHeader("Accept", "application/json") | |
| .addBodyPart(new FilePart("file", file,"image/png", null, file.getName())) | |
| .build(); | |
| client.executeRequest(request).toCompletableFuture().whenCompleteAsync((response, err) -> { | |
| if (null != err) { | |
| cf.completeExceptionally(err); | |
| close(client); | |
| return; | |
| } | |
| AddAttachmentResponseItem[] createIssueResponse = gsonBuilder.create() | |
| .fromJson(response.getResponseBody(StandardCharsets.UTF_8), AddAttachmentResponseItem[].class); | |
| cf.complete(createIssueResponse[0]); | |
| close(client); | |
| }); | |
| return cf; | |
| } | |
| private void close(AsyncHttpClient client) { | |
| try { | |
| client.close(); | |
| } catch (IOException e) { | |
| logger.severe(e.getMessage()); | |
| } | |
| } | |
| private CreateIssueRequest createIssueRequest(String title, String description, String parent) { | |
| CreateIssueRequest createIssueRequest = new CreateIssueRequest(); | |
| createIssueRequest.fields = new IssueRequestFields(); | |
| if (null == parent) { | |
| createIssueRequest.fields.issuetype = new IssueType(); | |
| createIssueRequest.fields.issuetype.id = JiraIssueType.EPIC.getId(); | |
| } else { | |
| createIssueRequest.fields.parent = new IssueParent(); | |
| createIssueRequest.fields.parent.key = parent; | |
| createIssueRequest.fields.issuetype = new IssueType(); | |
| createIssueRequest.fields.issuetype.id = JiraIssueType.BUG.getId(); | |
| } | |
| createIssueRequest.fields.summary = title; | |
| createIssueRequest.fields.project = new JiraProject(); | |
| createIssueRequest.fields.project.key = JIRA_API_PROJECT; | |
| createIssueRequest.fields.description = new IssueDescription(); | |
| createIssueRequest.fields.description.type = "doc"; | |
| createIssueRequest.fields.description.version = 1; | |
| createIssueRequest.fields.description.content = Collections.singletonList(new DescriptionContent()); | |
| createIssueRequest.fields.description.content.get(0).type = "paragraph"; | |
| createIssueRequest.fields.description.content.get(0).content = Collections.singletonList(new DescriptionContentItem()); | |
| createIssueRequest.fields.description.content.get(0).content.get(0).text = description; | |
| createIssueRequest.fields.description.content.get(0).content.get(0).type = "text"; | |
| return createIssueRequest; | |
| } | |
| /** | |
| * These ids are generated when the project is created, or when new issue types | |
| * are added. | |
| */ | |
| public enum JiraIssueType { | |
| TASK("10071"), | |
| EPIC("10072"), | |
| SUB_TASK("10073"), | |
| BUG("10074"), | |
| STORY("10075"); | |
| private String id; | |
| JiraIssueType(String id) { | |
| this.id = id; | |
| } | |
| public String getId() { | |
| return this.id; | |
| } | |
| } | |
| static class JiraProject { | |
| String key; | |
| } | |
| static class IssueParent { | |
| String key; | |
| } | |
| static class DescriptionContentItem { | |
| String type; | |
| String text; | |
| } | |
| static class DescriptionContent { | |
| String type; | |
| List<DescriptionContentItem> content; | |
| } | |
| static class IssueDescription { | |
| String type; | |
| Integer version; | |
| List<DescriptionContent> content; | |
| } | |
| public static class CreateIssueResponse { | |
| public String id; | |
| public String key; | |
| public String self; | |
| } | |
| static class IssueType { | |
| String id; | |
| } | |
| static class IssueRequestFields { | |
| String summary; | |
| IssueType issuetype; | |
| IssueParent parent; | |
| JiraProject project; | |
| IssueDescription description; | |
| } | |
| static class CreateIssueRequest { | |
| IssueRequestFields fields; | |
| } | |
| public static class AddAttachmentResponseItem { | |
| public String id; | |
| public String self; | |
| public String filename; | |
| public String mimeType; | |
| public String content; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment