package de.hftstuttgart.unifiedticketing.systems.github; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import de.hftstuttgart.unifiedticketing.core.Logging; import de.hftstuttgart.unifiedticketing.core.TicketBuilder; import de.hftstuttgart.unifiedticketing.core.TicketSystem; import de.hftstuttgart.unifiedticketing.exceptions.*; import okhttp3.*; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class GithubTicketBuilder extends TicketBuilder { private final static Logger logger = Logging.getLogger(GithubTicketBuilder.class.getName()); protected GithubTicketBuilder(GithubTicketSystem parent) { super(parent); } protected OkHttpClient getHttpClient() { return new OkHttpClient(); } @Override public GithubTicket create() { logger.log(Level.FINEST, "starting Ticket creation from builder data"); ObjectMapper mapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); ObjectNode body = mapper.createObjectNode(); // title is mandatory field if (this.title == null) { String msg = "mandatory field title not set before building ticket"; logger.log(Level.SEVERE, msg); if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null; else throw new AssertionException(msg); } if (this.description != null) { body.put("body", this.description); logger.log(Level.FINEST, "description set"); } body.put("title", this.title); logger.log(Level.FINEST, "title set"); if (this.assignees != null) { ArrayNode arrayNode = body.putArray("assignees"); assignees.forEach(arrayNode::add); logger.log(Level.FINEST, "assignees set"); } if (this.labels != null) { ArrayNode arrayNode = body.putArray("labels"); this.labels.forEach(arrayNode::add); logger.log(Level.FINEST, "labels set"); } String jsonBody; try { jsonBody = mapper.writeValueAsString(body); } catch (JsonProcessingException e) { String msg = "json serialization FAILED"; logger.log(Level.SEVERE, msg); if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null; else throw new SerializationException(e); } OkHttpClient client = getHttpClient(); Request.Builder builder = new Request.Builder() .url(parent.baseUrl) .addHeader("accept", parent.acceptHeader) .post(RequestBody.create(jsonBody, MediaType.get("application/json"))); if (this.parent.username != null && this.parent.apiKey != null) { builder.addHeader("Authorization", Credentials.basic(this.parent.username, this.parent.apiKey)); logger.log(Level.FINEST, "added basic auth header with api token"); } Response response; try { Request request = builder.build(); logger.log(Level.FINEST, String.format( "created request:\n%s", (this.parent.apiKey != null) ? request.toString().replace(this.parent.apiKey, "SECRET") : request.toString() )); response = client.newCall(request).execute(); } catch (IOException e) { logger.log(Level.SEVERE, "create request FAILED"); if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null; else throw new HttpReqeustException(e); } if (response.code() >= 400) { logger.log(Level.SEVERE, String.format( "create request failed with response code %d", response.code() )); if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null; else throw new HttpResponseException( String.format("ticket creation failed, error response code %d", response.code()), response.code()); } logger.log(Level.FINEST, "response received\n"); ResponseBody responseBody; responseBody = response.body(); if (responseBody == null) { logger.log(Level.SEVERE, "create request didn't deliver a body in response"); if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null; else throw new HttpResponseException("ticket creation failed, no response body", response.code()); } GithubTicketResponse ticketResponse; try { ticketResponse = mapper.readValue(responseBody.bytes(), GithubTicketResponse.class); logger.log(Level.FINEST, "parsed response to ticketResponse instance"); } catch (IOException e) { logger.severe(String.format("parsing create response FAILED with: %s", e.getMessage())); if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null; else throw new DeserializationException(e); } return GithubTicket.fromTicketResponse(parent, ticketResponse); } }