/** * Copyright Promptu Systems Corporation 2016. All rights reserved. */ package bugzilla.rest; import java.io.IOException; import java.io.InputStreamReader; import java.util.NoSuchElementException; import java.util.logging.Logger; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonParser; /** * Get the details of and update a bug using the REST API. * * https://wiki.mozilla.org/Bugzilla:REST_API * * @author Warwick Hunter * @since 2016-11-26 */ public class BugzillaBug { private static boolean VERBOSE = false; private final BugzillaSession m_session; private int m_bugNumber = -1; private BugData m_bugData; private final Gson m_gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); private final JsonParser m_jsonParser = new JsonParser(); private final Logger m_logger = Logger.getLogger("p4bugzilla"); public BugzillaBug(BugzillaSession session) { m_session = session; } /** * Get the details of a bug from a bugzilla instance. * * @see http://bugzilla.readthedocs.io/en/latest/api/core/v1/bug.html#get-bug * * @param bugNumber the number of the bug to get */ public void load(int bugNumber) throws HttpException, IOException { m_bugNumber = bugNumber; GetMethod method = new GetMethod(String.format("%s/bug/%d", m_session.getUrl(), bugNumber)); try { NameValuePair[] args = { new NameValuePair(BugzillaConst.TOKEN, m_session.getToken()) }; method.setQueryString(args); if (VERBOSE) { m_logger.info(String.format("request %s", method.getURI().toString())); } int statusCode = m_session.getHttpClient().executeMethod(method); switch (statusCode) { case HttpStatus.SC_OK: break; case HttpStatus.SC_NOT_FOUND: throw new NoSuchElementException("Bug not found: " + method.getStatusLine()); default: throw new HttpException("Get bug request failed: " + method.getStatusLine()); } JsonElement jelt = m_jsonParser.parse(new InputStreamReader(method.getResponseBodyAsStream())); if (VERBOSE) { m_logger.info("response " + m_gson.toJson(jelt).toString()); } if (jelt.isJsonObject() && jelt.getAsJsonObject().has(BugzillaConst.BUGS)) { BugData[] bugs = m_gson.fromJson(jelt.getAsJsonObject().get(BugzillaConst.BUGS), BugData[].class); if (bugs != null && bugs.length > 0) { m_bugData = bugs[0]; } if (VERBOSE) { m_logger.info(m_bugData.toString()); } } else { throw new HttpException("Get bug request failed, no bugs returned"); } } finally { method.releaseConnection(); } } /** * Add a comment to the bug. * * @see http://bugzilla.readthedocs.io/en/latest/api/core/v1/comment.html#create-comments * * @param comment the comment to add to the bug. * @throws IOException * @throws HttpException */ public void addComment(String comment) throws HttpException, IOException { PostMethod method = new PostMethod(String.format("%s/bug/%d/comment", m_session.getUrl(), m_bugNumber)); try { NameValuePair[] args = { new NameValuePair(BugzillaConst.TOKEN, m_session.getToken()) }; method.setQueryString(args); CommentData commentData = new CommentData(); commentData.comment = comment; commentData.is_markdown = false; commentData.is_private = false; StringRequestEntity entity = new StringRequestEntity(m_gson.toJson(commentData), "application/json", "UTF-8"); method.setRequestEntity(entity); if (VERBOSE) { m_logger.info(String.format("request %s%n%s", method.getURI().toString(), m_gson.toJson(commentData))); } int statusCode = m_session.getHttpClient().executeMethod(method); switch (statusCode) { case HttpStatus.SC_CREATED: break; case HttpStatus.SC_NOT_FOUND: throw new NoSuchElementException("Bug not found: " + method.getStatusLine()); default: throw new HttpException("Add comments to bug request failed: " + method.getStatusLine()); } if (VERBOSE) { JsonElement jelt = m_jsonParser.parse(method.getResponseBodyAsString()); m_logger.info("response " + m_gson.toJson(jelt).toString()); } } finally { method.releaseConnection(); } } /** * Mark a bug resolved/fixed a bugzilla instance and set the assignee to be * the QA contact. The bug must have been loaded first so that this class * can get the QA contact. * * @param comment the comment that is added to the bug when the status is changed. * @throws IOException * @throws HttpException */ public void markFixed(String comment) throws HttpException, IOException { if (m_bugData == null) { throw new IllegalStateException("This bug must be loaded before it can be marked as fixed."); } PutMethod method = new PutMethod(String.format("%s/bug/%d", m_session.getUrl(), m_bugNumber)); try { NameValuePair[] args = { new NameValuePair(BugzillaConst.TOKEN, m_session.getToken()) }; method.setQueryString(args); BugData bugData = new BugData(); bugData.resolution = BugzillaConst.FIXED; bugData.status = BugzillaConst.RESOLVED; bugData.assigned_to = m_bugData.qa_contact; bugData.comment = new CommentData(); bugData.comment.comment = comment; bugData.comment.is_markdown = false; bugData.comment.is_private = false; StringRequestEntity entity = new StringRequestEntity(m_gson.toJson(bugData), "application/json", "UTF-8"); method.setRequestEntity(entity); if (VERBOSE) { m_logger.info(String.format("request %s%n%s", method.getURI().toString(), m_gson.toJson(bugData))); } int statusCode = m_session.getHttpClient().executeMethod(method); switch (statusCode) { case HttpStatus.SC_OK: break; case HttpStatus.SC_NOT_FOUND: throw new NoSuchElementException("Bug not found: " + method.getStatusLine()); default: throw new HttpException("Update bug request failed: " + method.getStatusLine()); } if (VERBOSE) { JsonElement jelt = m_jsonParser.parse(method.getResponseBodyAsString()); m_logger.info("response " + m_gson.toJson(jelt).toString()); } } finally { method.releaseConnection(); } } public int getBugNumber() { return m_bugNumber; } public void setBugNumber(int bugNumber) { m_bugNumber = bugNumber; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("BugzillaBug [m_session=").append(m_session).append(", m_bugNumber=").append(m_bugNumber).append(", m_bugData=").append(m_bugData).append("]"); return builder.toString(); } private static final class BugData { Integer id; String priority; String assigned_to; String qa_contact; String resolution; String status; String summary; CommentData comment; @Override public String toString() { return String.format("BugData [priority=%s, assigned_to=%s, id=%s, qa_contact=%s, resolution=%s, status=%s, summary=%s]", priority, assigned_to, id, qa_contact, resolution, status, summary); } } private static final class CommentData { String comment; boolean is_private; boolean is_markdown; @Override public String toString() { return String.format("CommentData [comment=%s, is_private=%s, is_markdown=%s]", comment, is_private, is_markdown); } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 21161 | Warwick Hunter |
P4 Bugzilla v2.1 - Use the new Bugzilla REST API instead of the old XMLRPC API. - Use the latest P4 Java API. - Build with gradle and gradlew. - Integrate with the latest systemd Linux daemon startup environment found on Fedora 21+ systems. - Simplified the code to focus on just the job at hand. |