diff --git a/docs/en/watcher/actions/jira.asciidoc b/docs/en/watcher/actions/jira.asciidoc index 68097e6ace6..38c95fe71cb 100644 --- a/docs/en/watcher/actions/jira.asciidoc +++ b/docs/en/watcher/actions/jira.asciidoc @@ -123,6 +123,10 @@ reject `url` settings like `http://internal-jira.elastic.co` that are based on plain text HTTP protocol. This default behavior can be disabled with the explicit `allow_http setting`: +NOTE: The `url` field can also contain a path, that is used to create an issue. By +default this is `/rest/api/2/issue`. If you set this as well, make sure that this +path is the full path to the endpoint to create an issue. + [source,yaml] -------------------------------------------------- xpack.notification.jira: diff --git a/plugin/src/main/java/org/elasticsearch/xpack/notification/jira/JiraAccount.java b/plugin/src/main/java/org/elasticsearch/xpack/notification/jira/JiraAccount.java index e6eab2a87ec..a95be5f291a 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/notification/jira/JiraAccount.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/notification/jira/JiraAccount.java @@ -96,7 +96,7 @@ public class JiraAccount { HttpRequest request = HttpRequest.builder(url.getHost(), url.getPort()) .scheme(Scheme.parse(url.getScheme())) .method(HttpMethod.POST) - .path(DEFAULT_PATH) + .path(url.getPath().isEmpty() || url.getPath().equals("/") ? DEFAULT_PATH : url.getPath()) .jsonBody((builder, params) -> builder.field("fields", fields)) .auth(new BasicAuth(user, password.toCharArray())) .proxy(proxy) diff --git a/plugin/src/test/java/org/elasticsearch/xpack/notification/jira/JiraAccountTests.java b/plugin/src/test/java/org/elasticsearch/xpack/notification/jira/JiraAccountTests.java index 3c98660037f..067b9e6ac8f 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/notification/jira/JiraAccountTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/notification/jira/JiraAccountTests.java @@ -13,12 +13,14 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.common.http.HttpClient; +import org.elasticsearch.xpack.common.http.HttpProxy; import org.elasticsearch.xpack.common.http.HttpRequest; import org.elasticsearch.xpack.common.http.HttpResponse; import org.elasticsearch.xpack.common.http.Scheme; import org.junit.Before; import org.mockito.ArgumentCaptor; +import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -28,11 +30,14 @@ import static java.util.Collections.singletonMap; import static org.elasticsearch.common.collect.Tuple.tuple; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isOneOf; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class JiraAccountTests extends ESTestCase { @@ -207,6 +212,31 @@ public class JiraAccountTests extends ESTestCase { assertThat(sentRequest.body(), notNullValue()); } + public void testCustomUrls() throws Exception { + assertCustomUrl(Settings.builder().put("url", "https://localhost/foo").build(), "/foo"); + assertCustomUrl(Settings.builder().put("url", "https://localhost/foo/").build(), "/foo/"); + // this ensures we retain backwards compatibility + assertCustomUrl(Settings.builder().put("url", "https://localhost/").build(), JiraAccount.DEFAULT_PATH); + assertCustomUrl(Settings.builder().put("url", "https://localhost").build(), JiraAccount.DEFAULT_PATH); + } + + private void assertCustomUrl(Settings urlSettings, String expectedPath) throws IOException { + Settings settings = Settings.builder().put(urlSettings).put("user", "foo").put("password", "bar").build(); + HttpClient client = mock(HttpClient.class); + + HttpResponse response = new HttpResponse(200); + when(client.execute(any())).thenReturn(response); + + JiraAccount jiraAccount = new JiraAccount("test", settings, client); + jiraAccount.createIssue(Collections.emptyMap(), HttpProxy.NO_PROXY); + + ArgumentCaptor captor = ArgumentCaptor.forClass(HttpRequest.class); + verify(client, times(1)).execute(captor.capture()); + assertThat(captor.getAllValues(), hasSize(1)); + HttpRequest request = captor.getValue(); + assertThat(request.path(), is(expectedPath)); + } + private void addAccountSettings(String name, Settings.Builder builder) { builder.put("xpack.notification.jira.account." + name + "." + JiraAccount.URL_SETTING, "https://internal-jira.elastic.co:443"); builder.put("xpack.notification.jira.account." + name + "." + JiraAccount.USER_SETTING, randomAlphaOfLength(10));