Add PUT to JiraRestApi
Change-Id: I03245612dbca9cc935a60ef972f39d7fe91a9474
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/InitJira.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/InitJira.java
index 59cb1bd..91cf5b8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/InitJira.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/InitJira.java
@@ -27,9 +27,9 @@
import com.googlesource.gerrit.plugins.its.base.validation.ItsAssociationPolicy;
import com.googlesource.gerrit.plugins.its.jira.restapi.JiraServerInfo;
import com.googlesource.gerrit.plugins.its.jira.restapi.JiraServerInfoRestApi;
+import com.googlesource.gerrit.plugins.its.jira.restapi.JiraURL;
import java.io.IOException;
import java.net.MalformedURLException;
-import java.net.URL;
import java.util.Arrays;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -40,7 +40,7 @@
private final Section.Factory sections;
private final InitFlags flags;
private Section jira;
- private URL jiraUrl;
+ private JiraURL jiraUrl;
private String jiraUsername;
private String jiraPassword;
@@ -120,7 +120,7 @@
public void enterJiraConnectivity() throws MalformedURLException {
String jiraUrlString = jira.string("Jira URL (empty to skip)", "url", null);
if (jiraUrlString != null) {
- jiraUrl = new URL(jiraUrlString);
+ jiraUrl = new JiraURL(jiraUrlString);
jiraUsername = jira.string("Jira username", "username", "");
jiraPassword = jira.password("username", "password");
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraConfig.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraConfig.java
index 9ec5d9b..a39e059 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraConfig.java
@@ -14,15 +14,14 @@
package com.googlesource.gerrit.plugins.its.jira;
-import static com.googlesource.gerrit.plugins.its.jira.UrlHelper.*;
import static java.lang.String.format;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.its.jira.restapi.JiraURL;
import java.net.MalformedURLException;
-import java.net.URL;
import org.eclipse.jgit.lib.Config;
/** The JIRA plugin configuration as read from Gerrit config. */
@@ -33,7 +32,7 @@
static final String GERRIT_CONFIG_USERNAME = "username";
static final String GERRIT_CONFIG_PASSWORD = "password";
- private final URL jiraUrl;
+ private final JiraURL jiraUrl;
private final String jiraUsername;
private final String jiraPassword;
@@ -46,7 +45,7 @@
@Inject
JiraConfig(@GerritServerConfig Config config, @PluginName String pluginName) {
try {
- jiraUrl = adjustUrlPath(new URL(config.getString(pluginName, null, GERRIT_CONFIG_URL)));
+ jiraUrl = new JiraURL(config.getString(pluginName, null, GERRIT_CONFIG_URL)).adjustUrlPath();
} catch (MalformedURLException e) {
throw new RuntimeException(format(ERROR_MSG, pluginName, e.getLocalizedMessage()));
}
@@ -63,7 +62,7 @@
*
* @return the jira url
*/
- public URL getJiraUrl() {
+ public JiraURL getJiraUrl() {
return jiraUrl;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/UrlHelper.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/UrlHelper.java
deleted file mode 100644
index a6b89ef..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/UrlHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-
-package com.googlesource.gerrit.plugins.its.jira;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class UrlHelper {
- private static final Logger log = LoggerFactory.getLogger(UrlHelper.class);
-
- public static URL resolveUrl(URL url, String... paths) {
- if (url == null) {
- return url;
- }
-
- String relativePath = String.join("", Arrays.asList(paths));
- try {
- return new URL(url, relativePath);
- } catch (MalformedURLException e) {
- log.error("Unexpected exception while composing URL {} with path {}", url, relativePath, e);
- throw new IllegalArgumentException(e);
- }
- }
-
- public static URL adjustUrlPath(URL url) {
- if (url == null) {
- return url;
- }
- try {
- return url.getPath().endsWith("/") ? url : new URL(url, "/");
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApi.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApi.java
index 450ac47..ceec13d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApi.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApi.java
@@ -14,27 +14,22 @@
package com.googlesource.gerrit.plugins.its.jira.restapi;
-import static com.googlesource.gerrit.plugins.its.jira.UrlHelper.*;
-
import com.google.gson.Gson;
import com.google.inject.Inject;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
-import java.net.Proxy;
import java.net.ProxySelector;
-import java.net.URL;
import java.util.Base64;
import org.apache.commons.lang.ArrayUtils;
-import org.eclipse.jgit.util.HttpSupport;
/** Jira Rest Client. */
public class JiraRestApi<T> {
private static final String BASE_PREFIX = "rest/api/2";
- private final URL baseUrl;
+ private final JiraURL baseUrl;
private final String auth;
private final Gson gson;
@@ -52,9 +47,9 @@
* @param classPrefix prefix for the rest api request
*/
@Inject
- public JiraRestApi(URL url, String user, String pass, Class<T> classOfT, String classPrefix) {
+ public JiraRestApi(JiraURL url, String user, String pass, Class<T> classOfT, String classPrefix) {
this.auth = encode(user, pass);
- this.baseUrl = resolveUrl(url, BASE_PREFIX, classPrefix, "/");
+ this.baseUrl = url == null ? url : url.resolveUrl(BASE_PREFIX, classPrefix, "/");
this.gson = new Gson();
this.classOfT = classOfT;
}
@@ -75,7 +70,7 @@
* @throws IOException generated if unexpected failCode is returned
*/
public T doGet(String spec, int passCode, int[] failCodes) throws IOException {
- HttpURLConnection conn = prepHttpConnection(spec, false);
+ HttpURLConnection conn = prepHttpConnection(spec, "GET", false);
try {
if (validateResponse(conn, passCode, failCodes)) {
readIncomingData(conn);
@@ -90,43 +85,51 @@
return doGet(spec, passCode, null);
}
- URL getBaseUrl() {
+ JiraURL getBaseUrl() {
return baseUrl;
}
/** Do a simple POST request. */
public boolean doPost(String spec, String jsonInput, int passCode) throws IOException {
- HttpURLConnection conn = prepHttpConnection(spec, true);
+ return sendPayload("POST", spec, jsonInput, passCode);
+ }
+
+ /** Do a simple PUT request. */
+ public boolean doPut(String spec, String jsonInput, int passCode) throws IOException {
+ return sendPayload("PUT", spec, jsonInput, passCode);
+ }
+
+ private boolean sendPayload(String method, String spec, String jsonInput, int passCode)
+ throws IOException {
+ HttpURLConnection conn = prepHttpConnection(spec, method, true);
try {
- writePostData(jsonInput, conn);
+ writeBodyData(jsonInput, conn);
return validateResponse(conn, passCode, null);
} finally {
conn.disconnect();
}
}
- private HttpURLConnection prepHttpConnection(String spec, boolean isPostRequest)
+ private HttpURLConnection prepHttpConnection(String spec, String method, boolean withPayload)
throws IOException {
- URL url = new URL(baseUrl, spec);
+ JiraURL url = baseUrl.withSpec(spec);
ProxySelector proxySelector = ProxySelector.getDefault();
- Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
+ HttpURLConnection conn = url.openConnection(proxySelector);
conn.setRequestProperty("Authorization", "Basic " + auth);
conn.setRequestProperty("Content-Type", "application/json");
- if (isPostRequest) {
- conn.setRequestMethod("POST");
+
+ conn.setRequestMethod(method.toUpperCase());
+ if (withPayload) {
conn.setDoOutput(true);
- } else {
- conn.setRequestMethod("GET");
}
return conn;
}
- /** Write the Read the returned data from the HTTP connection. */
- private void writePostData(String postData, HttpURLConnection conn) throws IOException {
- if (postData != null) {
+ /** Write the data to the HTTP connection. */
+ private void writeBodyData(String data, HttpURLConnection conn) throws IOException {
+ if (data != null) {
try (OutputStream os = conn.getOutputStream()) {
- os.write(postData.getBytes());
+ os.write(data.getBytes());
os.flush();
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraServerInfoRestApi.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraServerInfoRestApi.java
index 10a4c91..0a64de0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraServerInfoRestApi.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraServerInfoRestApi.java
@@ -17,11 +17,10 @@
import static java.net.HttpURLConnection.HTTP_OK;
import java.io.IOException;
-import java.net.URL;
public class JiraServerInfoRestApi extends JiraRestApi<JiraServerInfo> {
- public JiraServerInfoRestApi(URL url, String user, String pass) {
+ public JiraServerInfoRestApi(JiraURL url, String user, String pass) {
super(url, user, pass, JiraServerInfo.class, "/serverInfo/");
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraURL.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraURL.java
new file mode 100644
index 0000000..03935a5
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraURL.java
@@ -0,0 +1,93 @@
+// Copyright (C) 2018 Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License"),
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.its.jira.restapi;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Objects;
+import org.eclipse.jgit.util.HttpSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JiraURL {
+
+ private static final Logger log = LoggerFactory.getLogger(JiraURL.class);
+
+ private final URL url;
+
+ public JiraURL(String spec) throws MalformedURLException {
+ this.url = new URL(spec);
+ }
+
+ private JiraURL(URL url) {
+ this.url = requireNonNull(url);
+ }
+
+ public JiraURL resolveUrl(String... paths) {
+ String relativePath = String.join("", Arrays.asList(paths));
+ try {
+ return new JiraURL(new URL(url, relativePath));
+ } catch (MalformedURLException e) {
+ log.error("Unexpected exception while composing URL {} with path {}", url, relativePath, e);
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public JiraURL adjustUrlPath() {
+ try {
+ return url.getPath().endsWith("/") ? this : this.withSpec("/");
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public JiraURL withSpec(String spec) throws MalformedURLException {
+ return new JiraURL(new URL(url, spec));
+ }
+
+ public HttpURLConnection openConnection(ProxySelector proxySelector) throws IOException {
+ Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
+ return (HttpURLConnection) url.openConnection(proxy);
+ }
+
+ public String getPath() {
+ return url.getPath();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ JiraURL jiraURL = (JiraURL) o;
+ return Objects.equals(url, jiraURL.url);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(url);
+ }
+
+ @Override
+ public String toString() {
+ return url.toString();
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/jira/JiraConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/jira/JiraConfigTest.java
index fba7db7..e25d1ef 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/jira/JiraConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/jira/JiraConfigTest.java
@@ -20,8 +20,8 @@
import static com.googlesource.gerrit.plugins.its.jira.JiraConfig.GERRIT_CONFIG_USERNAME;
import static org.mockito.Mockito.when;
+import com.googlesource.gerrit.plugins.its.jira.restapi.JiraURL;
import java.net.MalformedURLException;
-import java.net.URL;
import org.eclipse.jgit.lib.Config;
import org.junit.Rule;
import org.junit.Test;
@@ -34,7 +34,7 @@
public class JiraConfigTest {
private static final String PASS = "pass";
- private static final URL TEST_URL = newUrl("http://jira_example.com/");
+ private static final JiraURL TEST_URL = newUrl("http://jira_example.com/");
private static final String USER = "user";
private static final String PLUGIN_NAME = "its-jira";
@@ -60,9 +60,9 @@
jiraConfig = new JiraConfig(cfg, PLUGIN_NAME);
}
- private static URL newUrl(String url) {
+ private static JiraURL newUrl(String url) {
try {
- return new URL(url);
+ return new JiraURL(url);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiTest.java
index 073a03c..1ee2ab2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiTest.java
@@ -15,10 +15,14 @@
package com.googlesource.gerrit.plugins.its.jira.restapi;
import static com.google.common.truth.Truth.assertThat;
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
import com.google.common.base.CharMatcher;
+import java.io.ByteArrayOutputStream;
+import java.net.HttpURLConnection;
import java.net.MalformedURLException;
-import java.net.URL;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
@@ -27,14 +31,15 @@
@SuppressWarnings({"unchecked", "rawtypes"})
public class JiraRestApiTest {
private static final String ISSUE_CLASS_PREFIX = "/issue/";
+ private static final String JSON_PAYLOAD = "{}";
- private URL url;
+ private JiraURL url;
private String user = "user";
private String password = "pass";
private JiraRestApi restApi;
private void setURL(String jiraUrl) throws MalformedURLException {
- url = new URL(CharMatcher.is('/').trimFrom(jiraUrl) + "/");
+ url = new JiraURL(CharMatcher.is('/').trimFrom(jiraUrl) + "/");
}
@Test
@@ -60,4 +65,25 @@
String jiraApiUrl = restApi.getBaseUrl().toString();
assertThat(jiraApiUrl).startsWith(url.toString());
}
+
+ @Test
+ public void testDoPut() throws Exception {
+ JiraURL url = mock(JiraURL.class);
+ when(url.resolveUrl(any())).thenReturn(url);
+ when(url.withSpec(ISSUE_CLASS_PREFIX)).thenReturn(url);
+
+ HttpURLConnection connection = mock(HttpURLConnection.class);
+ when(url.openConnection(any())).thenReturn(connection);
+ ByteArrayOutputStream connectionOutputStream = new ByteArrayOutputStream();
+ when(connection.getOutputStream()).thenReturn(connectionOutputStream);
+ when(connection.getResponseCode()).thenReturn(HTTP_NO_CONTENT);
+
+ restApi = new JiraRestApi(url, user, password, JiraIssue.class, ISSUE_CLASS_PREFIX);
+ boolean pass = restApi.doPut(ISSUE_CLASS_PREFIX, JSON_PAYLOAD, HTTP_NO_CONTENT);
+
+ verify(connection).setRequestMethod("PUT");
+ verify(connection).setDoOutput(true);
+ assertThat(pass).isTrue();
+ assertThat(new String(connectionOutputStream.toByteArray(), "UTF-8")).isEqualTo(JSON_PAYLOAD);
+ }
}