Resolve URL syntax at init/config time
Remove all the noise in the code about managing and adjusting the
Jira URL and centralise validation in two points:
- init
- configuration
Once the JiraConfig is resolved, all the rest of the code can assume
that the URL is valid and can be used as-is.
Change-Id: I0ff634216c8df5b60a897e67ff84aad980b56791
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 0f9e19a..77d2b1b 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
@@ -25,6 +25,8 @@
import com.googlesource.gerrit.plugins.its.base.its.InitIts;
import com.googlesource.gerrit.plugins.its.base.validation.ItsAssociationPolicy;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Arrays;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -35,7 +37,7 @@
private final Section.Factory sections;
private final InitFlags flags;
private Section jira;
- private String jiraUrl;
+ private URL jiraUrl;
private String jiraUsername;
private String jiraPassword;
@@ -89,13 +91,14 @@
}
}
- private void init() {
+ private void init() throws MalformedURLException {
this.jira = sections.get(pluginName, null);
Section jiraComment = sections.get(COMMENT_LINK_SECTION, pluginName);
do {
enterJiraConnectivity();
- } while (jiraUrl != null && (isConnectivityRequested(jiraUrl) && !isJiraConnectSuccessful()));
+ } while (jiraUrl != null
+ && (isConnectivityRequested(jiraUrl.toString()) && !isJiraConnectSuccessful()));
if (jiraUrl == null) {
return;
@@ -111,9 +114,10 @@
"Issue-id enforced in commit message", "association", ItsAssociationPolicy.SUGGESTED);
}
- public void enterJiraConnectivity() {
- jiraUrl = jira.string("Jira URL (empty to skip)", "url", null);
- if (jiraUrl != null) {
+ public void enterJiraConnectivity() throws MalformedURLException {
+ String jiraUrlString = jira.string("Jira URL (empty to skip)", "url", null);
+ if (jiraUrlString != null) {
+ jiraUrl = new URL(jiraUrlString);
jiraUsername = jira.string("Jira username", "username", "");
jiraPassword = jira.password("username", "password");
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraClient.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraClient.java
index ae2a864..7311a9b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/JiraClient.java
@@ -31,7 +31,7 @@
import com.googlesource.gerrit.plugins.its.jira.restapi.JiraServerInfo;
import com.googlesource.gerrit.plugins.its.jira.restapi.JiraTransition;
import java.io.IOException;
-import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
@@ -44,7 +44,7 @@
private final Gson gson;
@Inject
- public JiraClient(JiraConfig jiraConfig) throws MalformedURLException {
+ public JiraClient(JiraConfig jiraConfig) {
this(jiraConfig.getJiraUrl(), jiraConfig.getUsername(), jiraConfig.getPassword());
}
@@ -55,7 +55,7 @@
* @param user username of the jira user
* @param pass password of the jira user
*/
- JiraClient(String url, String user, String pass) throws MalformedURLException {
+ JiraClient(URL url, String user, String pass) {
this.apiBuilder = new JiraRestApiProvider(url, user, pass);
this.gson = new Gson();
}
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 b757b65..9ec5d9b 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,23 +14,26 @@
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 java.net.MalformedURLException;
+import java.net.URL;
import org.eclipse.jgit.lib.Config;
/** The JIRA plugin configuration as read from Gerrit config. */
@Singleton
public class JiraConfig {
- static final String ERROR_MSG = "Unable to load plugin %s. Cause: Wrong configuration ";
+ static final String ERROR_MSG = "Unable to load plugin %s because of invalid configuration: %s";
static final String GERRIT_CONFIG_URL = "url";
static final String GERRIT_CONFIG_USERNAME = "username";
static final String GERRIT_CONFIG_PASSWORD = "password";
- private final String jiraUrl;
+ private final URL jiraUrl;
private final String jiraUsername;
private final String jiraPassword;
@@ -42,11 +45,16 @@
*/
@Inject
JiraConfig(@GerritServerConfig Config config, @PluginName String pluginName) {
- jiraUrl = config.getString(pluginName, null, GERRIT_CONFIG_URL);
+ try {
+ jiraUrl = adjustUrlPath(new URL(config.getString(pluginName, null, GERRIT_CONFIG_URL)));
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(format(ERROR_MSG, pluginName, e.getLocalizedMessage()));
+ }
+
jiraUsername = config.getString(pluginName, null, GERRIT_CONFIG_USERNAME);
jiraPassword = config.getString(pluginName, null, GERRIT_CONFIG_PASSWORD);
if (jiraUrl == null || jiraUsername == null || jiraPassword == null) {
- throw new RuntimeException(format(ERROR_MSG, pluginName));
+ throw new RuntimeException(format(ERROR_MSG, pluginName, "missing username/password"));
}
}
@@ -55,7 +63,7 @@
*
* @return the jira url
*/
- public String getJiraUrl() {
+ public URL 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
new file mode 100644
index 0000000..a6b89ef
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/UrlHelper.java
@@ -0,0 +1,37 @@
+
+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 aff8428..35f70ce 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,12 +14,13 @@
package com.googlesource.gerrit.plugins.its.jira.restapi;
+import static com.googlesource.gerrit.plugins.its.jira.UrlHelper.*;
+
import com.google.gson.Gson;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URL;
@@ -45,10 +46,9 @@
* @param user username of the jira user
* @param pass password of the jira user
*/
- JiraRestApi(URL url, String user, String pass, Class<T> classOfT, String classPrefix)
- throws MalformedURLException {
+ JiraRestApi(URL url, String user, String pass, Class<T> classOfT, String classPrefix) {
this.auth = Base64.getEncoder().encodeToString((user + ":" + pass).getBytes());
- this.baseUrl = new URL(url, BASE_PREFIX + classPrefix + "/");
+ this.baseUrl = resolveUrl(url, BASE_PREFIX, classPrefix, "/");
this.gson = new Gson();
this.classOfT = classOfT;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiProvider.java b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiProvider.java
index 3277f7f..37534a5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiProvider.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/jira/restapi/JiraRestApiProvider.java
@@ -14,7 +14,6 @@
package com.googlesource.gerrit.plugins.its.jira.restapi;
-import java.net.MalformedURLException;
import java.net.URL;
public class JiraRestApiProvider {
@@ -22,26 +21,25 @@
private final String user;
private final String pass;
- public JiraRestApiProvider(String url, String user, String pass) throws MalformedURLException {
- this.url = new URL(url + (url.endsWith("/") ? "" : "/"));
+ public JiraRestApiProvider(URL url, String user, String pass) {
+ this.url = url;
this.user = user;
this.pass = pass;
}
- public <T> JiraRestApi<T> get(Class<T> classOfT, String classPrefix)
- throws MalformedURLException {
+ public <T> JiraRestApi<T> get(Class<T> classOfT, String classPrefix) {
return new JiraRestApi<>(url, user, pass, classOfT, classPrefix);
}
- public JiraRestApi<JiraIssue> getIssue() throws MalformedURLException {
+ public JiraRestApi<JiraIssue> getIssue() {
return get(JiraIssue.class, "/issue");
}
- public JiraRestApi<JiraServerInfo> getServerInfo() throws MalformedURLException {
+ public JiraRestApi<JiraServerInfo> getServerInfo() {
return get(JiraServerInfo.class, "/serverInfo");
}
- public JiraRestApi<JiraProject[]> getProjects() throws MalformedURLException {
+ public JiraRestApi<JiraProject[]> getProjects() {
return get(JiraProject[].class, "/project");
}
}
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 f7f5a40..fba7db7 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
@@ -15,13 +15,13 @@
package com.googlesource.gerrit.plugins.its.jira;
import static com.google.common.truth.Truth.assertThat;
-import static com.googlesource.gerrit.plugins.its.jira.JiraConfig.ERROR_MSG;
import static com.googlesource.gerrit.plugins.its.jira.JiraConfig.GERRIT_CONFIG_PASSWORD;
import static com.googlesource.gerrit.plugins.its.jira.JiraConfig.GERRIT_CONFIG_URL;
import static com.googlesource.gerrit.plugins.its.jira.JiraConfig.GERRIT_CONFIG_USERNAME;
-import static java.lang.String.format;
import static org.mockito.Mockito.when;
+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 String URL = "http://jira_example.com";
+ private static final URL TEST_URL = newUrl("http://jira_example.com/");
private static final String USER = "user";
private static final String PLUGIN_NAME = "its-jira";
@@ -45,19 +45,26 @@
@Test
public void gerritConfigContainsSaneValues() throws Exception {
- when(cfg.getString(PLUGIN_NAME, null, GERRIT_CONFIG_URL)).thenReturn(URL);
+ when(cfg.getString(PLUGIN_NAME, null, GERRIT_CONFIG_URL)).thenReturn(TEST_URL.toString());
when(cfg.getString(PLUGIN_NAME, null, GERRIT_CONFIG_USERNAME)).thenReturn(USER);
when(cfg.getString(PLUGIN_NAME, null, GERRIT_CONFIG_PASSWORD)).thenReturn(PASS);
jiraConfig = new JiraConfig(cfg, PLUGIN_NAME);
assertThat(jiraConfig.getUsername()).isEqualTo(USER);
assertThat(jiraConfig.getPassword()).isEqualTo(PASS);
- assertThat(jiraConfig.getJiraUrl()).isEqualTo(URL);
+ assertThat(jiraConfig.getJiraUrl()).isEqualTo(TEST_URL);
}
@Test
public void gerritConfigContainsNullValues() throws Exception {
thrown.expect(RuntimeException.class);
- thrown.expectMessage(format(ERROR_MSG, PLUGIN_NAME));
jiraConfig = new JiraConfig(cfg, PLUGIN_NAME);
}
+
+ private static URL newUrl(String url) {
+ try {
+ return new URL(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 24512b5..b87b591 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
@@ -16,37 +16,38 @@
import static com.google.common.truth.Truth.assertThat;
+import java.net.URL;
import org.junit.Test;
public class JiraRestApiTest {
@Test
public void testJiraServerInfoForNonRootJiraUrl() throws Exception {
- String nonRootJiraUrl = "http://jira.mycompany.com/myroot/";
+ URL nonRootJiraUrl = new URL("http://jira.mycompany.com/myroot/");
JiraRestApi<JiraServerInfo> serverInfo =
new JiraRestApiProvider(nonRootJiraUrl, "", "").getServerInfo();
String jiraApiUrl = serverInfo.getBaseUrl().toString();
- assertThat(jiraApiUrl).startsWith(nonRootJiraUrl);
+ assertThat(jiraApiUrl).startsWith(nonRootJiraUrl.toString());
}
@Test
public void testJiraServerInfoForNonRootJiraUrlNotEndingWithSlash() throws Exception {
- String nonRootJiraUrl = "http://jira.mycompany.com/myroot";
+ URL nonRootJiraUrl = new URL("http://jira.mycompany.com/myroot/");
JiraRestApi<JiraServerInfo> serverInfo =
new JiraRestApiProvider(nonRootJiraUrl, "", "").getServerInfo();
String jiraApiUrl = serverInfo.getBaseUrl().toString();
- assertThat(jiraApiUrl).startsWith(nonRootJiraUrl);
+ assertThat(jiraApiUrl).startsWith(nonRootJiraUrl.toString());
}
@Test
public void testJiraServerInfoForRootJiraUrl() throws Exception {
- String rootJiraUrl = "http://jira.mycompany.com";
+ URL rootJiraUrl = new URL("http://jira.mycompany.com");
JiraRestApi<JiraServerInfo> serverInfo =
new JiraRestApiProvider(rootJiraUrl, "", "").getServerInfo();
String jiraApiUrl = serverInfo.getBaseUrl().toString();
- assertThat(jiraApiUrl).startsWith(rootJiraUrl);
+ assertThat(jiraApiUrl).startsWith(rootJiraUrl.toString());
}
}