Tests: Remove HttpClient to only use one Http client

The HTTP client implementation used by the Elasticsearch REST tests is
backed by apache http client instead of a self written helper class,
that uses HttpUrlConnection. This commit removes the old simple HttpClient
class and uses the more powerful and reliable one for all tests.

It also fixes a minor bug, that when sending a 301 redirect, a Location
header needs to be added as well, which was uncovered by the switching
to the new client.

Closes #7003
This commit is contained in:
Alexander Reelsen 2014-07-25 10:26:52 +02:00
parent 51fd2f513c
commit 35e562343f
10 changed files with 138 additions and 280 deletions

View File

@ -154,7 +154,10 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> {
pluginName = path;
sitePath = null;
// If a trailing / is missing, we redirect to the right page #2654
channel.sendResponse(new BytesRestResponse(RestStatus.MOVED_PERMANENTLY, "text/html", "<head><meta http-equiv=\"refresh\" content=\"0; URL=" + request.rawPath() + "/\"></head>"));
String redirectUrl = request.rawPath() + "/";
BytesRestResponse restResponse = new BytesRestResponse(RestStatus.MOVED_PERMANENTLY, "text/html", "<head><meta http-equiv=\"refresh\" content=\"0; URL=" + redirectUrl + "></head>");
restResponse.addHeader("Location", redirectUrl);
channel.sendResponse(restResponse);
return;
} else {
pluginName = path.substring(0, i1);

View File

@ -19,15 +19,16 @@
package org.elasticsearch.options.jsonp;
import org.apache.http.impl.client.HttpClients;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.helper.HttpClient;
import org.elasticsearch.rest.helper.HttpClientResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
import org.elasticsearch.test.rest.client.http.HttpResponse;
import org.junit.Test;
import static org.hamcrest.Matchers.containsString;
@ -55,11 +56,12 @@ public class JsonpOptionDisabledTest extends ElasticsearchIntegrationTest {
@Test
public void testThatJSONPisDisabled() throws Exception {
// Make the HTTP request
HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
HttpClient httpClient = new HttpClient(httpServerTransport.boundAddress().publishAddress());
HttpClientResponse response = httpClient.request("/?callback=DisabledJSONPCallback");
assertThat(response.getHeader("Content-Type"), is("application/javascript"));
assertThat(response.response(), containsString("DisabledJSONPCallback("));
assertThat(response.response(), containsString("JSONP is disabled"));
HttpResponse response = new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class))
.path("/")
.addParam("callback", "DisabledJSONPCallback").execute();
assertThat(response.getHeaders().get("Content-Type"), is("application/javascript"));
assertThat(response.getBody(), containsString("DisabledJSONPCallback("));
assertThat(response.getBody(), containsString("JSONP is disabled"));
}
}

View File

@ -19,15 +19,16 @@
package org.elasticsearch.options.jsonp;
import org.apache.http.impl.client.HttpClients;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.helper.HttpClient;
import org.elasticsearch.rest.helper.HttpClientResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
import org.elasticsearch.test.rest.client.http.HttpResponse;
import org.junit.Test;
import static org.hamcrest.Matchers.containsString;
@ -50,11 +51,9 @@ public class JsonpOptionEnabledTest extends ElasticsearchIntegrationTest {
@Test
public void testThatJSONPisEnabled() throws Exception {
// Make the HTTP request
HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
HttpClient httpClient = new HttpClient(httpServerTransport.boundAddress().publishAddress());
HttpClientResponse response = httpClient.request("/?callback=EnabledJSONPCallback");
assertThat(response.getHeader("Content-Type"), is("application/javascript"));
assertThat(response.response(), containsString("EnabledJSONPCallback("));
assertThat(response.response(), containsString("You Know, for Search"));
HttpResponse response = new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class)).path("/").addParam("callback", "EnabledJSONPCallback").execute();
assertThat(response.getHeaders().get("Content-Type"), is("application/javascript"));
assertThat(response.getBody(), containsString("EnabledJSONPCallback("));
assertThat(response.getBody(), containsString("You Know, for Search"));
}
}

View File

@ -19,6 +19,8 @@
package org.elasticsearch.plugin;
import com.google.common.base.Predicate;
import org.apache.http.impl.client.HttpClients;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
@ -33,11 +35,11 @@ import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.node.internal.InternalSettingsPreparer;
import org.elasticsearch.plugins.PluginManager;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.helper.HttpClient;
import org.elasticsearch.rest.helper.HttpClientResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.elasticsearch.test.junit.annotations.Network;
import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
import org.elasticsearch.test.rest.client.http.HttpResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -205,31 +207,37 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
assertThat(pluginFound, is(true));
}
private void assertPluginAvailable(String pluginName) throws InterruptedException {
HttpServerTransport httpServerTransport = internalCluster().getInstance(HttpServerTransport.class);
final HttpClient httpClient = new HttpClient(httpServerTransport.boundAddress().publishAddress());
logger.info("--> tested http address [{}]", httpServerTransport.info().getAddress());
private void assertPluginAvailable(String pluginName) throws InterruptedException, IOException {
final HttpRequestBuilder httpRequestBuilder = getHttpRequestBuilder();
//checking that the http connector is working properly
// We will try it for some seconds as it could happen that the REST interface is not yet fully started
assertThat(awaitBusy(new Predicate<Object>() {
public boolean apply(Object obj) {
HttpClientResponse response = httpClient.request("");
if (response.errorCode() != RestStatus.OK.getStatus()) {
// We want to trace what's going on here before failing the test
logger.info("--> error caught [{}], headers [{}]", response.errorCode(), response.getHeaders());
logger.info("--> cluster state [{}]", internalCluster().clusterService().state());
return false;
try {
HttpResponse response = httpRequestBuilder.method("GET").path("/").execute();
if (response.getStatusCode() != RestStatus.OK.getStatus()) {
// We want to trace what's going on here before failing the test
logger.info("--> error caught [{}], headers [{}]", response.getStatusCode(), response.getHeaders());
logger.info("--> cluster state [{}]", internalCluster().clusterService().state());
return false;
}
return true;
} catch (IOException e) {
throw new ElasticsearchException("HTTP problem", e);
}
return true;
}
}, 5, TimeUnit.SECONDS), equalTo(true));
//checking now that the plugin is available
HttpClientResponse response = httpClient.request("_plugin/" + pluginName + "/");
HttpResponse response = getHttpRequestBuilder().method("GET").path("/_plugin/" + pluginName + "/").execute();
assertThat(response, notNullValue());
assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
}
private HttpRequestBuilder getHttpRequestBuilder() {
return new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class));
}
@Test
@ -300,7 +308,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
@Test
@Network
public void testInstallPluginWithElasticsearchDownloadService() throws IOException {
assumeTrue(isDownloadServiceWorking("http://download.elasticsearch.org/", "elasticsearch/ci-test.txt"));
assumeTrue(isDownloadServiceWorking("download.elasticsearch.org", 80, "/elasticsearch/ci-test.txt"));
singlePluginInstallAndRemove("elasticsearch/elasticsearch-transport-thrift/1.5.0", null);
}
@ -313,7 +321,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
@Test
@Network
public void testInstallPluginWithMavenCentral() throws IOException {
assumeTrue(isDownloadServiceWorking("http://search.maven.org/", "/"));
assumeTrue(isDownloadServiceWorking("search.maven.org", 80, "/"));
singlePluginInstallAndRemove("org.elasticsearch/elasticsearch-transport-thrift/1.5.0", null);
}
@ -326,20 +334,21 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
@Test
@Network
public void testInstallPluginWithGithub() throws IOException {
assumeTrue(isDownloadServiceWorking("https://github.com/", "/"));
assumeTrue(isDownloadServiceWorking("github.com", 443, "/"));
singlePluginInstallAndRemove("elasticsearch/kibana", null);
}
private boolean isDownloadServiceWorking(String url, String resource) {
HttpClient client = new HttpClient(url);
private boolean isDownloadServiceWorking(String host, int port, String resource) {
try {
if (client.request(resource).errorCode() != 200) {
logger.warn("[{}{}] download service is not working. Disabling current test.", url, resource);
String protocol = port == 443 ? "https" : "http";
HttpResponse response = new HttpRequestBuilder(HttpClients.createDefault()).protocol(protocol).host(host).port(port).path(resource).execute();
if (response.getStatusCode() != 200) {
logger.warn("[{}{}] download service is not working. Disabling current test.", host, resource);
return false;
}
return true;
} catch (Throwable t) {
logger.warn("[{}{}] download service is not working. Disabling current test.", url, resource);
logger.warn("[{}{}] download service is not working. Disabling current test.", host, resource);
}
return false;
}

View File

@ -18,21 +18,19 @@
*/
package org.elasticsearch.plugin;
import com.google.common.collect.Maps;
import org.apache.http.impl.client.HttpClients;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.plugin.responseheader.TestResponseHeaderPlugin;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.helper.HttpClient;
import org.elasticsearch.rest.helper.HttpClientResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
import org.elasticsearch.test.rest.client.http.HttpResponse;
import org.junit.Test;
import java.util.Map;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import static org.hamcrest.Matchers.equalTo;
/**
@ -53,19 +51,16 @@ public class ResponseHeaderPluginTests extends ElasticsearchIntegrationTest {
@Test
public void testThatSettingHeadersWorks() throws Exception {
ensureGreen();
HttpClientResponse response = httpClient().request("/_protected");
assertThat(response.errorCode(), equalTo(RestStatus.UNAUTHORIZED.getStatus()));
assertThat(response.getHeader("Secret"), equalTo("required"));
HttpResponse response = httpClient().method("GET").path("/_protected").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.UNAUTHORIZED.getStatus()));
assertThat(response.getHeaders().get("Secret"), equalTo("required"));
Map<String, String> headers = Maps.newHashMap();
headers.put("Secret", "password");
HttpClientResponse authResponse = httpClient().request("GET", "_protected", headers);
assertThat(authResponse.errorCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(authResponse.getHeader("Secret"), equalTo("granted"));
HttpResponse authResponse = httpClient().method("GET").path("/_protected").addHeader("Secret", "password").execute();
assertThat(authResponse.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(authResponse.getHeaders().get("Secret"), equalTo("granted"));
}
private HttpClient httpClient() {
HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
return new HttpClient(httpServerTransport.boundAddress().publishAddress());
private HttpRequestBuilder httpClient() {
return new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class));
}
}

View File

@ -18,20 +18,23 @@
*/
package org.elasticsearch.plugin;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.helper.HttpClient;
import org.elasticsearch.rest.helper.HttpClientResponse;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
import org.elasticsearch.test.rest.client.http.HttpResponse;
import org.junit.Test;
import java.io.File;
import java.net.URISyntaxException;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
@ -56,22 +59,23 @@ public class SitePluginTests extends ElasticsearchIntegrationTest {
}
}
public HttpClient httpClient() {
HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
return new HttpClient(httpServerTransport.boundAddress().publishAddress());
public HttpRequestBuilder httpClient() {
RequestConfig.Builder builder = RequestConfig.custom().setRedirectsEnabled(false);
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(builder.build()).build();
return new HttpRequestBuilder(httpClient).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class));
}
@Test
public void testRedirectSitePlugin() throws Exception {
// We use an HTTP Client to test redirection
HttpClientResponse response = httpClient().request("/_plugin/dummy");
assertThat(response.errorCode(), equalTo(RestStatus.MOVED_PERMANENTLY.getStatus()));
assertThat(response.response(), containsString("/_plugin/dummy/"));
HttpResponse response = httpClient().method("GET").path("/_plugin/dummy").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.MOVED_PERMANENTLY.getStatus()));
assertThat(response.getBody(), containsString("/_plugin/dummy/"));
// We test the real URL
response = httpClient().request("/_plugin/dummy/");
assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.response(), containsString("<title>Dummy Site Plugin</title>"));
response = httpClient().method("GET").path("/_plugin/dummy/").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>"));
}
/**
@ -79,9 +83,9 @@ public class SitePluginTests extends ElasticsearchIntegrationTest {
*/
@Test
public void testAnyPage() throws Exception {
HttpClientResponse response = httpClient().request("/_plugin/dummy/index.html");
assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.response(), containsString("<title>Dummy Site Plugin</title>"));
HttpResponse response = httpClient().path("/_plugin/dummy/index.html").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>"));
}
/**
@ -90,15 +94,15 @@ public class SitePluginTests extends ElasticsearchIntegrationTest {
*/
@Test
public void testWelcomePageInSubDirs() throws Exception {
HttpClientResponse response = httpClient().request("/_plugin/subdir/dir/");
assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.response(), containsString("<title>Dummy Site Plugin (subdir)</title>"));
HttpResponse response = httpClient().path("/_plugin/subdir/dir/").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.getBody(), containsString("<title>Dummy Site Plugin (subdir)</title>"));
response = httpClient().request("/_plugin/subdir/dir_without_index/");
assertThat(response.errorCode(), equalTo(RestStatus.FORBIDDEN.getStatus()));
response = httpClient().path("/_plugin/subdir/dir_without_index/").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.FORBIDDEN.getStatus()));
response = httpClient().request("/_plugin/subdir/dir_without_index/page.html");
assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.response(), containsString("<title>Dummy Site Plugin (page)</title>"));
response = httpClient().path("/_plugin/subdir/dir_without_index/page.html").execute();
assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
assertThat(response.getBody(), containsString("<title>Dummy Site Plugin (page)</title>"));
}
}

View File

@ -1,120 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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 org.elasticsearch.rest.helper;
import com.google.common.base.Charsets;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class HttpClient {
private final URL baseUrl;
public HttpClient(TransportAddress transportAddress) {
InetSocketAddress address = ((InetSocketTransportAddress) transportAddress).address();
try {
baseUrl = new URL("http", address.getAddress().getHostAddress(), address.getPort(), "/");
} catch (MalformedURLException e) {
throw new ElasticsearchException("", e);
}
}
public HttpClient(String url) {
try {
baseUrl = new URL(url);
} catch (MalformedURLException e) {
throw new ElasticsearchException("", e);
}
}
public HttpClient(URL url) {
baseUrl = url;
}
public HttpClientResponse request(String path) {
return request("GET", path);
}
public HttpClientResponse request(String method, String path) {
return request(method, path, null);
}
public HttpClientResponse request(String method, String path, Map<String, String> headers) {
URL url;
try {
url = new URL(baseUrl, path);
} catch (MalformedURLException e) {
throw new ElasticsearchException("Cannot parse " + path, e);
}
HttpURLConnection urlConnection;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(method);
if (headers != null) {
for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
urlConnection.setRequestProperty(headerEntry.getKey(), headerEntry.getValue());
}
}
urlConnection.connect();
} catch (IOException e) {
throw new ElasticsearchException("", e);
}
int errorCode = -1;
Map<String, List<String>> respHeaders = null;
try {
errorCode = urlConnection.getResponseCode();
respHeaders = urlConnection.getHeaderFields();
InputStream inputStream = urlConnection.getInputStream();
String body = null;
try {
body = Streams.copyToString(new InputStreamReader(inputStream, Charsets.UTF_8));
} catch (IOException e1) {
throw new ElasticsearchException("problem reading error stream", e1);
}
return new HttpClientResponse(body, errorCode, respHeaders, null);
} catch (IOException e) {
InputStream errStream = urlConnection.getErrorStream();
String body = null;
if (errStream != null) {
try {
body = Streams.copyToString(new InputStreamReader(errStream, Charsets.UTF_8));
} catch (IOException e1) {
throw new ElasticsearchException("problem reading error stream", e1);
}
}
return new HttpClientResponse(body, errorCode, respHeaders, e);
} finally {
urlConnection.disconnect();
}
}
}

View File

@ -1,63 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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 org.elasticsearch.rest.helper;
import java.util.List;
import java.util.Map;
public class HttpClientResponse {
private final String response;
private final int errorCode;
private Map<String, List<String>> headers;
private final Throwable e;
public HttpClientResponse(String response, int errorCode, Map<String, List<String>> headers, Throwable e) {
this.response = response;
this.errorCode = errorCode;
this.headers = headers;
this.e = e;
}
public String response() {
return response;
}
public int errorCode() {
return errorCode;
}
public Throwable cause() {
return e;
}
public Map<String, List<String>> getHeaders() {
return headers;
}
public String getHeader(String name) {
if (headers == null) {
return null;
}
List<String> vals = headers.get(name);
if (vals == null || vals.size() == 0) {
return null;
}
return vals.iterator().next();
}
}

View File

@ -20,6 +20,7 @@ package org.elasticsearch.test.rest.client.http;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
@ -27,6 +28,9 @@ import org.apache.lucene.util.IOUtils;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.http.HttpServerTransport;
import java.io.IOException;
import java.net.URI;
@ -46,6 +50,8 @@ public class HttpRequestBuilder {
private final CloseableHttpClient httpClient;
private String protocol = "http";
private String host;
private int port;
@ -54,6 +60,8 @@ public class HttpRequestBuilder {
private final Map<String, String> params = Maps.newHashMap();
private final Map<String, String> headers = Maps.newHashMap();
private String method = HttpGetWithEntity.METHOD_NAME;
private String body;
@ -67,6 +75,11 @@ public class HttpRequestBuilder {
return this;
}
public HttpRequestBuilder httpTransport(HttpServerTransport httpServerTransport) {
InetSocketTransportAddress transportAddress = (InetSocketTransportAddress) httpServerTransport.boundAddress().publishAddress();
return host(transportAddress.address().getHostName()).port(transportAddress.address().getPort());
}
public HttpRequestBuilder port(int port) {
this.port = port;
return this;
@ -82,6 +95,16 @@ public class HttpRequestBuilder {
return this;
}
public HttpRequestBuilder addHeader(String name, String value) {
this.headers.put(name, value);
return this;
}
public HttpRequestBuilder protocol(String protocol) {
this.protocol = protocol;
return this;
}
public HttpRequestBuilder method(String method) {
this.method = method;
return this;
@ -95,26 +118,21 @@ public class HttpRequestBuilder {
}
public HttpResponse execute() throws IOException {
CloseableHttpResponse closeableHttpResponse = null;
try {
HttpUriRequest httpUriRequest = buildRequest();
if (logger.isTraceEnabled()) {
StringBuilder stringBuilder = new StringBuilder(httpUriRequest.getMethod()).append(" ").append(httpUriRequest.getURI());
if (Strings.hasLength(body)) {
stringBuilder.append("\n").append(body);
}
logger.trace("sending request \n{}", stringBuilder.toString());
HttpUriRequest httpUriRequest = buildRequest();
if (logger.isTraceEnabled()) {
StringBuilder stringBuilder = new StringBuilder(httpUriRequest.getMethod()).append(" ").append(httpUriRequest.getURI());
if (Strings.hasLength(body)) {
stringBuilder.append("\n").append(body);
}
closeableHttpResponse = httpClient.execute(httpUriRequest);
logger.trace("sending request \n{}", stringBuilder.toString());
}
for (Map.Entry<String, String> entry : this.headers.entrySet()) {
httpUriRequest.addHeader(entry.getKey(), entry.getValue());
}
try (CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpUriRequest)) {
HttpResponse httpResponse = new HttpResponse(httpUriRequest, closeableHttpResponse);
logger.trace("got response \n{}\n{}", closeableHttpResponse, httpResponse.hasBody() ? httpResponse.getBody() : "");
return httpResponse;
} finally {
try {
IOUtils.close(closeableHttpResponse);
} catch (IOException e) {
logger.error("error closing http response", e);
}
}
}
@ -152,7 +170,7 @@ public class HttpRequestBuilder {
query = Joiner.on('&').withKeyValueSeparator("=").join(params);
}
try {
return new URI("http", null, host, port, path, query, null);
return new URI(protocol, null, host, port, path, query, null);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}

View File

@ -18,6 +18,7 @@
*/
package org.elasticsearch.test.rest.client.http;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpUriRequest;
@ -26,6 +27,8 @@ import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Response obtained from an http request
@ -39,11 +42,15 @@ public class HttpResponse {
private final int statusCode;
private final String reasonPhrase;
private final String body;
private final Map<String, String> headers = new HashMap<>();
HttpResponse(HttpUriRequest httpRequest, CloseableHttpResponse httpResponse) {
this.httpRequest = httpRequest;
this.statusCode = httpResponse.getStatusLine().getStatusCode();
this.reasonPhrase = httpResponse.getStatusLine().getReasonPhrase();
for (Header header : httpResponse.getAllHeaders()) {
this.headers.put(header.getName(), header.getValue());
}
if (httpResponse.getEntity() != null) {
try {
this.body = EntityUtils.toString(httpResponse.getEntity(), HttpRequestBuilder.DEFAULT_CHARSET);
@ -86,6 +93,10 @@ public class HttpResponse {
return !HttpHead.METHOD_NAME.equals(httpRequest.getMethod());
}
public Map<String, String> getHeaders() {
return headers;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder(statusCode).append(" ").append(reasonPhrase);