Skip to content

Instantly share code, notes, and snippets.

@rgpower
Created March 4, 2021 15:00
Show Gist options
  • Select an option

  • Save rgpower/2241c2b25946191257f54581ff82101e to your computer and use it in GitHub Desktop.

Select an option

Save rgpower/2241c2b25946191257f54581ff82101e to your computer and use it in GitHub Desktop.
Create Jira tickets, attach images etc, via Java
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