JiraRestClient for Java does not support edits or updates

Continuing from my last post on using Jira’s REST client for Java, it seems the version I am using, 2.0.0-m2, does not actually support updates.  It is read only.

Because it’s not like you’d ever want to update JIRA through its API, obviously :O

However the basic REST api does support updates.  To use this you need to authenticate and do an HTTP PUT which contains a JSON message with the update details.  Here I am going to post the code to update a custom field referenced by name.  Took me all afternoon.  Atlassian suck.

public class JiraRestAPITest {
  private static final String JIRA_USERNAME = "admin";
  private static final String JIRA_PASSWORD = "password";
  private static final String JIRA_URL = "http://localhost:8091/";
  private static final String CUSTOM_FIELD_NAME = "AosCustom1";
  private static final String JIRA_FILTER_BY_STATUS = "Open";
  private static final String JIRA_PROJECT_NAME = "aosdemo";
  private static final String ISSUE_ID = "DEMO-3";

  @Test
  public void testSomething() throws URISyntaxException {

    JiraRestClient restClient = login(JIRA_USERNAME, JIRA_PASSWORD);
    String jsql = filterByProject(JIRA_PROJECT_NAME);

    SearchResult results = restClient.getSearchClient().searchJql(jsql).claim();
    for (BasicIssue i : results.getIssues()) {
       String key = i.getKey();

       Issue issue = restClient.getIssueClient().getIssue(key).claim();
       Field customField = issue.getFieldByName(CUSTOM_FIELD_NAME);

       if (ISSUE_ID.equals(key)){
          String newValue = "Edited by AdrianOS at " + new Date();
          update(issue, customField, newValue);
       }

    }

  }

  private static String filterByProject(String projectName) {
    return String.format("project = '%s' AND status = '%s' ORDER BY priority DESC", projectName, JIRA_FILTER_BY_STATUS);
  }

  private static void update(Issue issue, Field field, String value) {

     try {
       HttpURLConnection connection = urlConnection(forIssue(issue), withEncoding());

       connection.connect();

       writeData(connection, jsonEditIssue(field, value));
       checkResponse(connection);

    } catch (IOException e) {
       throw new RuntimeException(e);
    }

 }

 private static void writeData(HttpURLConnection connection, JSONObject fields) throws IOException {
    System.out.println(fields);
    OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
    out.write(fields.toString());
    out.flush();
    out.close();
 }

 private static String withEncoding() {
    String userPassword = JIRA_USERNAME + ":" + JIRA_PASSWORD;
    return encodeBase64String(userPassword.getBytes());
 }

 private static void checkResponse(HttpURLConnection connection)
 throws IOException {

    if (HttpURLConnection.HTTP_NO_CONTENT != connection.getResponseCode()) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
    StringBuilder stringBuilder = new StringBuilder();

    String line = null;
    while ((line = reader.readLine()) != null) {
       stringBuilder.append(line + "\n");
    }

    System.err.println(stringBuilder.toString());
    }
 }

 private static URL forIssue(Issue issue) throws MalformedURLException {
    return issue.getSelf().toURL();
 }

 private static HttpURLConnection urlConnection(URL url, String encoding) throws IOException {
    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
    connection.setDoOutput(true);
    connection.setRequestProperty("Content-Type", "application/json");
    connection.setRequestMethod("PUT");
    connection.setRequestProperty("Authorization", "Basic " + encoding);
    return connection;
 }

 private static JSONObject jsonEditIssue(Field field, String value) {
    JSONObject summary = new JSONObject()
      .accumulate(field.getId(), value);

    JSONObject fields = new JSONObject().accumulate("fields", summary);
      return fields;
 }

 private static JiraRestClient login(String admin, String password) throws URISyntaxException {
    final URI jiraServerUri = new URI(JIRA_URL);
    final JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
    return factory.createWithBasicHttpAuthentication(jiraServerUri, admin, password);
 }

}

Here are the dependencies:

 	<dependencies>
		<dependency>
			<groupId>com.atlassian.jira</groupId>
			<artifactId>jira-rest-java-client</artifactId>
			<version>2.0.0-m2</version>
		</dependency>

		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>

		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.6</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
	</dependencies>