Watcher: Remove mock web server from square (elastic/elasticsearch#4221)

The latest release of the mock web server requires more security permissions, and
we dont need all the functionality anyway.

This introduces a small MockWebServer using the JDK internal HttpServer, yet fullfilling
all our needs and supporting SSL as well for testing.

The MockWebServer allows to enqueue responses and also requires you to enqueue as many responses
as you requests will be executed - there is no fallback at the moment.

SSL is also supported by passing an SSL context - for which the TestsSSLService is needed, which
makes the required methods public.

Original commit: elastic/x-pack-elasticsearch@55f4a172a2
This commit is contained in:
Alexander Reelsen 2016-12-09 09:07:09 +01:00 committed by GitHub
parent b1846190af
commit 37b0d52882
16 changed files with 731 additions and 396 deletions

View File

@ -16,10 +16,6 @@ esplugin {
}
archivesBaseName = 'x-pack' // for api jar
ext.versions = [
okhttp: '2.7.5'
]
// TODO: fix this! https://github.com/elastic/x-plugins/issues/1066
ext.compactProfile = 'full'
@ -58,12 +54,6 @@ dependencies {
testCompile 'org.elasticsearch:securemock:1.2'
testCompile 'org.slf4j:slf4j-log4j12:1.6.2'
testCompile 'org.slf4j:slf4j-api:1.6.2'
// mock web server
testCompile "com.squareup.okhttp:mockwebserver:${versions.okhttp}"
testCompile "com.squareup.okhttp:okhttp:${versions.okhttp}"
testCompile "com.squareup.okhttp:okhttp-ws:${versions.okhttp}"
testCompile 'com.squareup.okio:okio:1.6.0'
}
// make LicenseSigner available for testing signed licenses

View File

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.test.http;
import org.elasticsearch.common.SuppressForbidden;
import java.util.Collections;
import java.util.List;
/**
* A helper class to not leak the internal headers class into our tests
* Currently setting multiple values for a single header is not supported, as it was not needed yet
*/
@SuppressForbidden(reason = "use http server")
public class Headers {
final com.sun.net.httpserver.Headers headers;
/**
* Creates a class with empty headers
*/
Headers() {
this.headers = new com.sun.net.httpserver.Headers();
}
/**
* Creates a class headers from http
* @param headers The internal sun webserver headers object
*/
Headers(com.sun.net.httpserver.Headers headers) {
this.headers = headers;
}
/**
* @param name The name of header
* @return A list of values for this header
*/
public List<String> get(String name) {
return headers.get(name);
}
/**
* Adds a new header to this headers object
* @param name Name of the header
* @param value Value of the header
*/
void add(String name, String value) {
this.headers.put(name, Collections.singletonList(value));
}
/**
* @param name Name of the header
* @return Returns the first header value or null if none exists
*/
String getFirst(String name) {
return headers.getFirst(name);
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.test.http;
import org.elasticsearch.common.SuppressForbidden;
import java.net.URI;
import java.util.Locale;
/**
* A request parsed by the MockWebServer
*/
public class MockRequest {
private final String method;
private final URI uri;
private final Headers headers;
private String body = null;
@SuppressForbidden(reason = "use http server header class")
MockRequest(String method, URI uri, com.sun.net.httpserver.Headers headers) {
this.method = method;
this.uri = uri;
this.headers = new Headers(headers);
}
/**
* @return The HTTP method of the incoming request
*/
public String getMethod() {
return method;
}
/**
* @return The URI of the incoming request
*/
public URI getUri() {
return uri;
}
/**
* @return The specific value of a request header, null if it does not exist
*/
public String getHeader(String name) {
return headers.getFirst(name);
}
/**
* @return All headers associated with this request
*/
public Headers getHeaders() {
return headers;
}
/**
* @return The body the incoming request had, null if no body was found
*/
public String getBody() {
return body;
}
@Override
public String toString() {
return String.format(Locale.ROOT, "%s %s", method, uri);
}
/**
* @param body Sets the body of the incoming request
*/
void setBody(String body) {
this.body = body;
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.test.http;
import org.elasticsearch.common.unit.TimeValue;
/**
* A response to be sent via the mock webserver. Parts of the response can be configured
*/
public class MockResponse {
private String body = null;
private int statusCode = 200;
private TimeValue bodyDelay = null;
private Headers headers = new Headers();
private TimeValue beforeReplyDelay = null;
/**
* @param body The body to be returned if the response is sent by the webserver
* @return The updated mock response
*/
public MockResponse setBody(String body) {
this.body = body;
return this;
}
/**
* @param statusCode The status code to be returned if the response is sent by the webserver, defaults to 200
* @return The updated mock response
*/
public MockResponse setResponseCode(int statusCode) {
this.statusCode = statusCode;
return this;
}
/**
* @param timeValue Allows to specify a delay between sending of headers and the body to inject artificial latency
* @return The updated mock response
*/
public MockResponse setBodyDelay(TimeValue timeValue) {
this.bodyDelay = timeValue;
return this;
}
/**
* @param timeValue Allows to specify a delay before anything is sent back to the client
* @return The updated mock response
*/
public MockResponse setBeforeReplyDelay(TimeValue timeValue) {
this.beforeReplyDelay = timeValue;
return this;
}
/**
* Adds a new header to a response
* @param name Header name
* @param value header value
* @return The updated mock response
*/
public MockResponse addHeader(String name, String value) {
headers.add(name, value);
return this;
}
/**
* @return the body of the request
*/
String getBody() {
return body;
}
/**
* @return The HTTP status code
*/
int getStatusCode() {
return statusCode;
}
/**
* @return The time to delay the between sending the headers and the body
*/
TimeValue getBodyDelay() {
return bodyDelay;
}
/**
* @return All configured headers for this request
*/
Headers getHeaders() {
return headers;
}
/**
* @return The time to delay before the first byte is being returned
*/
TimeValue getBeforeReplyDelay() {
return beforeReplyDelay;
}
}

View File

@ -0,0 +1,234 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.test.http;
import com.google.common.base.Charsets;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.util.Supplier;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import javax.net.ssl.SSLContext;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.elasticsearch.test.ESTestCase.terminate;
/**
* A MockWebServer to test against. Holds a list of responses, which can be enqueed.
* The webserver has to enqueue at least the amount of responses with the number of requests that happen, otherwise errors
* will be returned.
* <p>
* Each response that was executed also contains the request, so you can check if requests happened in the correct order.
*/
@SuppressForbidden(reason = "use http server")
public class MockWebServer implements Closeable {
private HttpServer server;
private final AtomicInteger index = new AtomicInteger(0);
private final List<MockResponse> responses = new ArrayList<>();
private final List<MockRequest> requests = new ArrayList<>();
private final Logger logger;
private final SSLContext sslContext;
private boolean needClientAuth;
private Set<CountDownLatch> latches = ConcurrentCollections.newConcurrentSet();
/**
* Instantiates a webserver without https
*/
public MockWebServer() {
this(null, false);
}
/**
* Instantiates a webserver with https
* @param sslContext The SSL context to be used for encryption
* @param needClientAuth Should clientAuth be used, which requires a client side certificate
*/
public MockWebServer(SSLContext sslContext, boolean needClientAuth) {
this.needClientAuth = needClientAuth;
this.logger = ESLoggerFactory.getLogger(this.getClass());
this.sslContext = sslContext;
}
/**
* Starts the webserver and binds it to an arbitrary ephemeral port
* The webserver will be able to serve requests once this method returns
*
* @throws IOException in case of a binding or other I/O errors
*/
public void start() throws IOException {
InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress().getHostAddress(), 0);
if (sslContext != null) {
HttpsServer httpsServer = HttpsServer.create(address, 0);
httpsServer.setHttpsConfigurator(new CustomHttpsConfigurator(sslContext, needClientAuth));
server = httpsServer;
} else {
server = HttpServer.create(address, 0);
}
server.start();
server.createContext("/", s -> {
logger.debug("incoming HTTP request [{} {}]", s.getRequestMethod(), s.getRequestURI());
try {
MockResponse response = responses.get(index.getAndAdd(1));
MockRequest request = createRequest(s);
requests.add(request);
sleepIfNeeded(response.getBeforeReplyDelay());
s.getResponseHeaders().putAll(response.getHeaders().headers);
if (Strings.isEmpty(response.getBody())) {
s.sendResponseHeaders(response.getStatusCode(), 0);
} else {
byte[] responseAsBytes = response.getBody().getBytes(Charsets.UTF_8);
s.sendResponseHeaders(response.getStatusCode(), responseAsBytes.length);
sleepIfNeeded(response.getBodyDelay());
try (OutputStream responseBody = s.getResponseBody()) {
responseBody.write(responseAsBytes);
}
}
} catch (Exception e) {
logger.error((Supplier<?>) () -> new ParameterizedMessage("failed to respond to request [{} {}]",
s.getRequestMethod(), s.getRequestURI()), e);
} finally {
s.close();
}
});
logger.info("bound HTTP mock server to [{}:{}]", getHostName(), getPort());
}
/**
* A custom HttpsConfigurator that takes the SSL context and the required client authentication into account
* Also configured the protocols and cipher suites to match the security default ones
*/
@SuppressForbidden(reason = "use http server")
private static final class CustomHttpsConfigurator extends HttpsConfigurator {
private final boolean needClientAuth;
public CustomHttpsConfigurator(SSLContext sslContext, boolean needClientAuth) {
super(sslContext);
this.needClientAuth = needClientAuth;
}
@Override
public void configure(HttpsParameters params) {
params.setNeedClientAuth(needClientAuth);
}
}
/**
* Sleep the specified amount of time, if the time value is not null
*/
private void sleepIfNeeded(TimeValue timeValue) throws InterruptedException {
if (timeValue == null) {
return;
}
CountDownLatch latch = new CountDownLatch(1);
latches.add(latch);
try {
latch.await(timeValue.millis(), TimeUnit.MILLISECONDS);
} finally {
latches.remove(latch);
}
}
/**
* Creates a MockRequest from an incoming HTTP request, that can later be checked in your test assertions
*/
private MockRequest createRequest(HttpExchange exchange) throws IOException {
MockRequest request = new MockRequest(exchange.getRequestMethod(), exchange.getRequestURI(), exchange.getRequestHeaders());
if (exchange.getRequestBody() != null) {
String body = Streams.copyToString(new InputStreamReader(exchange.getRequestBody()));
if (Strings.isEmpty(body) == false) {
request.setBody(body);
}
}
return request;
}
/**
* @return The hostname the server is bound to. Uses #InetSocketAddress.getHostString() to prevent reverse dns lookups
*/
public String getHostName() {
return server.getAddress().getHostString();
}
/**
* @return The tcp port that the server is bound to
*/
public int getPort() {
return server.getAddress().getPort();
}
/**
* Adds a response to the response queue that is used when a request comes in
* Note: Every response is only processed once
* @param response The created mock response
*/
public void enqueue(MockResponse response) {
responses.add(response);
}
/**
* @return The requests that have been made to this mock web server
*/
public List<MockRequest> requests() {
return requests;
}
/**
* Removes the first request in the list of requests and returns it to the caller.
* This can be used as a queue if you know the order of your requests deone.
*/
public MockRequest takeRequest() {
return requests.remove(0);
}
/**
* Closes down the webserver. Also tries to stop all the currently sleeping requests first by counting down their respective
* latches.
*/
@Override
public void close() {
logger.debug("Counting down all latches before terminating executor");
latches.forEach(CountDownLatch::countDown);
if (server.getExecutor() instanceof ExecutorService) {
try {
terminate((ExecutorService) server.getExecutor());
} catch (InterruptedException e) {
}
}
server.stop(0);
}
}

View File

@ -6,33 +6,32 @@
package org.elasticsearch.xpack.common.http;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.util.Supplier;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.env.Environment;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.test.junit.annotations.Network;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.ssl.SSLService;
import org.elasticsearch.xpack.ssl.TestsSSLService;
import org.elasticsearch.xpack.ssl.VerificationMode;
import org.junit.After;
import org.junit.Before;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.concurrent.ExecutorService;
@ -42,6 +41,7 @@ import java.util.concurrent.atomic.AtomicReference;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
@ -49,7 +49,7 @@ import static org.hamcrest.core.Is.is;
public class HttpClientTests extends ESTestCase {
private MockWebServer webServer;
private MockWebServer webServer = new MockWebServer();
private HttpClient httpClient;
private HttpAuthRegistry authRegistry;
private Environment environment = new Environment(Settings.builder().put("path.home", createTempDir()).build());
@ -57,13 +57,13 @@ public class HttpClientTests extends ESTestCase {
@Before
public void init() throws Exception {
authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(null)));
webServer = startWebServer();
webServer.start();
httpClient = new HttpClient(Settings.EMPTY, authRegistry, new SSLService(environment.settings(), environment));
}
@After
public void shutdown() throws Exception {
webServer.shutdown();
webServer.close();
}
public void testBasics() throws Exception {
@ -71,7 +71,6 @@ public class HttpClientTests extends ESTestCase {
String body = randomAsciiOfLengthBetween(2, 8096);
webServer.enqueue(new MockResponse().setResponseCode(responseCode).setBody(body));
HttpRequest.Builder requestBuilder = HttpRequest.builder("localhost", webServer.getPort())
.method(HttpMethod.POST)
.path("/" + randomAsciiOfLength(5));
@ -90,18 +89,16 @@ public class HttpClientTests extends ESTestCase {
HttpRequest request = requestBuilder.build();
HttpResponse response = httpClient.execute(request);
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(response.status(), equalTo(responseCode));
assertThat(response.body().utf8ToString(), equalTo(body));
assertThat(webServer.getRequestCount(), equalTo(1));
assertThat(recordedRequest.getBody().readString(StandardCharsets.UTF_8), equalTo(request.body()));
assertThat(recordedRequest.getPath().split("\\?")[0], equalTo(request.path()));
assertThat(recordedRequest.getPath().split("\\?")[1], equalTo(paramKey + "=" + paramValue));
assertThat(recordedRequest.getHeader(headerKey), equalTo(headerValue));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), equalTo(request.path()));
assertThat(webServer.requests().get(0).getUri().getQuery(), equalTo(paramKey + "=" + paramValue));
assertThat(webServer.requests().get(0).getHeader(headerKey), equalTo(headerValue));
}
@TestLogging("org.elasticsearch.http.test:TRACE")
public void testNoQueryString() throws Exception {
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
HttpRequest.Builder requestBuilder = HttpRequest.builder("localhost", webServer.getPort())
@ -112,9 +109,9 @@ public class HttpClientTests extends ESTestCase {
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test"));
assertThat(recordedRequest.getBody().readUtf8Line(), nullValue());
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), is("/test"));
assertThat(webServer.requests().get(0).getBody(), is(nullValue()));
}
public void testUrlEncodingWithQueryStrings() throws Exception{
@ -128,9 +125,10 @@ public class HttpClientTests extends ESTestCase {
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test?key=value+123%3A123"));
assertThat(recordedRequest.getBody().readUtf8Line(), nullValue());
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), is("/test"));
assertThat(webServer.requests().get(0).getUri().getRawQuery(), is("key=value+123%3A123"));
assertThat(webServer.requests().get(0).getBody(), is(nullValue()));
}
public void testBasicAuth() throws Exception {
@ -143,17 +141,19 @@ public class HttpClientTests extends ESTestCase {
HttpResponse response = httpClient.execute(request.build());
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test"));
assertThat(recordedRequest.getHeader("Authorization"), equalTo("Basic dXNlcjpwYXNz"));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), is("/test"));
assertThat(webServer.requests().get(0).getHeader("Authorization"), is("Basic dXNlcjpwYXNz"));
}
public void testNoPathSpecified() throws Exception {
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("doesntmatter"));
HttpRequest.Builder request = HttpRequest.builder("localhost", webServer.getPort()).method(HttpMethod.GET);
httpClient.execute(request.build());
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/"));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), is("/"));
}
public void testHttps() throws Exception {
@ -171,26 +171,16 @@ public class HttpClientTests extends ESTestCase {
.put("xpack.ssl.truststore.password", "truststore-testnode-only")
.build();
}
HttpClient httpClient = new HttpClient(settings, authRegistry, new SSLService(settings, environment));
httpClient = new HttpClient(settings, authRegistry, new SSLService(settings, environment));
// We can't use the client created above for the server since it is only a truststore
Settings settings2 = Settings.builder()
.put("xpack.ssl.keystore.path", getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks"))
.put("xpack.ssl.keystore.password", "testnode")
.build();
webServer.useHttps(new SSLService(settings2, environment).sslSocketFactory(Settings.EMPTY), false);
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
HttpRequest.Builder request = HttpRequest.builder("localhost", webServer.getPort())
.scheme(Scheme.HTTPS)
.path("/test")
.body("body");
HttpResponse response = httpClient.execute(request.build());
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test"));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("body"));
TestsSSLService sslService = new TestsSSLService(settings2, environment);
testSslMockWebserver(sslService.sslContext(), false);
}
public void testHttpsDisableHostnameVerification() throws Exception {
@ -210,7 +200,7 @@ public class HttpClientTests extends ESTestCase {
.put("xpack.ssl.verification_mode", randomFrom(VerificationMode.NONE, VerificationMode.CERTIFICATE))
.build();
}
HttpClient httpClient = new HttpClient(settings, authRegistry, new SSLService(settings, environment));
httpClient = new HttpClient(settings, authRegistry, new SSLService(settings, environment));
// We can't use the client created above for the server since it only defines a truststore
Settings settings2 = Settings.builder()
@ -218,52 +208,38 @@ public class HttpClientTests extends ESTestCase {
getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode-no-subjaltname.jks"))
.put("xpack.ssl.keystore.password", "testnode-no-subjaltname")
.build();
webServer.useHttps(new SSLService(settings2, environment).sslSocketFactory(Settings.EMPTY), false);
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
HttpRequest.Builder request = HttpRequest.builder("localhost", webServer.getPort())
.scheme(Scheme.HTTPS)
.path("/test")
.body("body");
HttpResponse response = httpClient.execute(request.build());
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test"));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("body"));
TestsSSLService sslService = new TestsSSLService(settings2, environment);
testSslMockWebserver(sslService.sslContext(), false);
}
public void testHttpsClientAuth() throws Exception {
Path resource = getDataPath("/org/elasticsearch/xpack/security/keystore/testnode.jks");
Settings settings;
if (randomBoolean()) {
settings = Settings.builder()
.put("xpack.http.ssl.keystore.path", resource.toString())
.put("xpack.http.ssl.keystore.password", "testnode")
.build();
} else {
settings = Settings.builder()
Settings settings = Settings.builder()
.put("xpack.ssl.keystore.path", resource.toString())
.put("xpack.ssl.keystore.password", "testnode")
.build();
TestsSSLService sslService = new TestsSSLService(settings, environment);
httpClient = new HttpClient(settings, authRegistry, sslService);
testSslMockWebserver(sslService.sslContext(), true);
}
private void testSslMockWebserver(SSLContext sslContext, boolean needClientAuth) throws IOException {
try (MockWebServer mockWebServer = new MockWebServer(sslContext, needClientAuth)) {
mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
mockWebServer.start();
HttpRequest.Builder request = HttpRequest.builder("localhost", mockWebServer.getPort())
.scheme(Scheme.HTTPS)
.path("/test");
HttpResponse response = httpClient.execute(request.build());
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
assertThat(mockWebServer.requests(), hasSize(1));
assertThat(mockWebServer.requests().get(0).getUri().getPath(), is("/test"));
}
final SSLService sslService = new SSLService(settings, environment);
HttpClient httpClient = new HttpClient(settings, authRegistry, sslService);
webServer.useHttps(
new ClientAuthRequiringSSLSocketFactory(sslService.sslSocketFactory(settings.getByPrefix("xpack.http.ssl."))), false);
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
HttpRequest.Builder request = HttpRequest.builder("localhost", webServer.getPort())
.scheme(Scheme.HTTPS)
.path("/test")
.body("body");
HttpResponse response = httpClient.execute(request.build());
assertThat(response.status(), equalTo(200));
assertThat(response.body().utf8ToString(), equalTo("body"));
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test"));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("body"));
}
public void testHttpResponseWithAnyStatusCodeCanReturnBody() throws Exception {
@ -304,10 +280,9 @@ public class HttpClientTests extends ESTestCase {
public void testThatProxyCanBeConfigured() throws Exception {
// this test fakes a proxy server that sends a response instead of forwarding it to the mock web server
MockWebServer proxyServer = startWebServer();
proxyServer.enqueue(new MockResponse().setResponseCode(200).setBody("fullProxiedContent"));
try {
try (MockWebServer proxyServer = new MockWebServer()) {
proxyServer.enqueue(new MockResponse().setResponseCode(200).setBody("fullProxiedContent"));
proxyServer.start();
Settings settings = Settings.builder()
.put(HttpClient.SETTINGS_PROXY_HOST, "localhost")
.put(HttpClient.SETTINGS_PROXY_PORT, proxyServer.getPort())
@ -323,19 +298,16 @@ public class HttpClientTests extends ESTestCase {
assertThat(response.body().utf8ToString(), equalTo("fullProxiedContent"));
// ensure we hit the proxyServer and not the webserver
assertThat(webServer.getRequestCount(), equalTo(0));
assertThat(proxyServer.getRequestCount(), equalTo(1));
} finally {
proxyServer.shutdown();
assertThat(webServer.requests(), hasSize(0));
assertThat(proxyServer.requests(), hasSize(1));
}
}
public void testThatProxyCanBeOverriddenByRequest() throws Exception {
// this test fakes a proxy server that sends a response instead of forwarding it to the mock web server
MockWebServer proxyServer = startWebServer();
proxyServer.enqueue(new MockResponse().setResponseCode(200).setBody("fullProxiedContent"));
try {
try (MockWebServer proxyServer = new MockWebServer()) {
proxyServer.enqueue(new MockResponse().setResponseCode(200).setBody("fullProxiedContent"));
proxyServer.start();
Settings settings = Settings.builder()
.put(HttpClient.SETTINGS_PROXY_HOST, "localhost")
.put(HttpClient.SETTINGS_PROXY_PORT, proxyServer.getPort() + 1)
@ -352,26 +324,24 @@ public class HttpClientTests extends ESTestCase {
assertThat(response.body().utf8ToString(), equalTo("fullProxiedContent"));
// ensure we hit the proxyServer and not the webserver
assertThat(webServer.getRequestCount(), equalTo(0));
assertThat(proxyServer.getRequestCount(), equalTo(1));
} finally {
proxyServer.shutdown();
assertThat(webServer.requests(), hasSize(0));
assertThat(proxyServer.requests(), hasSize(1));
}
}
public void testThatUrlPathIsNotEncoded() throws Exception {
// %2F is a slash that needs to be encoded to not be misinterpreted as a path
String path = "/<logstash-{now%2Fd}>/_search";
String path = "/%3Clogstash-%7Bnow%2Fd%7D%3E/_search";
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("foo"));
HttpRequest request = HttpRequest.builder("localhost", webServer.getPort()).path(path).build();
httpClient.execute(request);
assertThat(webServer.getRequestCount(), is(1));
assertThat(webServer.requests(), hasSize(1));
RecordedRequest recordedRequest = webServer.takeRequest();
// under no circumstances have a double encode of %2F => %25 (percent sign)
assertThat(recordedRequest.getPath(), not(containsString("%25")));
assertThat(recordedRequest.getPath(), equalTo(path));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getRawPath(), not(containsString("%25")));
assertThat(webServer.requests().get(0).getUri().getPath(), is("/<logstash-{now/d}>/_search"));
}
public void testThatHttpClientFailsOnNonHttpResponse() throws Exception {
@ -397,64 +367,4 @@ public class HttpClientTests extends ESTestCase {
terminate(executor);
}
}
private MockWebServer startWebServer() throws IOException {
MockWebServer mockWebServer = new MockWebServer();
mockWebServer.setProtocolNegotiationEnabled(false);
mockWebServer.start();
return mockWebServer;
}
static class ClientAuthRequiringSSLSocketFactory extends SSLSocketFactory {
final SSLSocketFactory delegate;
ClientAuthRequiringSSLSocketFactory(SSLSocketFactory delegate) {
this.delegate = delegate;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
SSLSocket sslSocket = (SSLSocket) delegate.createSocket(socket, s, i, b);
sslSocket.setNeedClientAuth(true);
return sslSocket;
}
@Override
public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) delegate.createSocket(s, i);
sslSocket.setNeedClientAuth(true);
return sslSocket;
}
@Override
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) delegate.createSocket(s, i, inetAddress, i1);
sslSocket.setNeedClientAuth(true);
return sslSocket;
}
@Override
public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
SSLSocket sslSocket = (SSLSocket) delegate.createSocket(inetAddress, i);
sslSocket.setNeedClientAuth(true);
return sslSocket;
}
@Override
public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
SSLSocket sslSocket = (SSLSocket) delegate.createSocket(inetAddress, i, inetAddress1, i1);
sslSocket.setNeedClientAuth(true);
return sslSocket;
}
}
}

View File

@ -5,40 +5,35 @@
*/
package org.elasticsearch.xpack.common.http;
import com.squareup.okhttp.mockwebserver.Dispatcher;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.env.Environment;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.ssl.SSLService;
import org.junit.After;
import org.junit.Before;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.mockito.Mockito.mock;
public class HttpReadTimeoutTests extends ESTestCase {
private MockWebServer webServer;
private MockWebServer webServer = new MockWebServer();
@Before
public void init() throws Exception {
webServer = new MockWebServer();
webServer.start();
webServer.enqueue(new MockResponse().setBeforeReplyDelay(TimeValue.timeValueSeconds(20)));
}
@After
public void cleanup() throws Exception {
webServer.shutdown();
webServer.close();
}
public void testDefaultTimeout() throws Exception {
@ -46,11 +41,9 @@ public class HttpReadTimeoutTests extends ESTestCase {
HttpClient httpClient = new HttpClient(Settings.EMPTY, mock(HttpAuthRegistry.class),
new SSLService(environment.settings(), environment));
// we're not going to enqueue an response... so the server will just hang
HttpRequest request = HttpRequest.builder("localhost", webServer.getPort())
.method(HttpMethod.POST)
.path("/" + randomAsciiOfLength(5))
.path("/")
.build();
long start = System.nanoTime();
@ -61,9 +54,6 @@ public class HttpReadTimeoutTests extends ESTestCase {
// it's supposed to be 10, but we'll give it an error margin of 2 seconds
assertThat(timeout.seconds(), greaterThan(8L));
assertThat(timeout.seconds(), lessThan(12L));
// lets enqueue a response to relese the server.
webServer.enqueue(new MockResponse());
}
public void testDefaultTimeoutCustom() throws Exception {
@ -73,14 +63,9 @@ public class HttpReadTimeoutTests extends ESTestCase {
.put("xpack.http.default_read_timeout", "3s").build()
, mock(HttpAuthRegistry.class), new SSLService(environment.settings(), environment));
final String path = '/' + randomAsciiOfLength(5);
final CountDownLatch latch = new CountDownLatch(1);
final TimeValue sleepTime = TimeValue.timeValueSeconds(10);
webServer.setDispatcher(new CountDownLatchDispatcher(path, latch, sleepTime));
HttpRequest request = HttpRequest.builder("localhost", webServer.getPort())
.method(HttpMethod.POST)
.path(path)
.path("/")
.build();
long start = System.nanoTime();
@ -91,11 +76,6 @@ public class HttpReadTimeoutTests extends ESTestCase {
// it's supposed to be 3, but we'll give it an error margin of 2 seconds
assertThat(timeout.seconds(), greaterThan(1L));
assertThat(timeout.seconds(), lessThan(5L));
if (!latch.await(sleepTime.seconds(), TimeUnit.SECONDS)) {
// should never happen
fail("waited too long for the response to be returned");
}
}
public void testTimeoutCustomPerRequest() throws Exception {
@ -105,15 +85,10 @@ public class HttpReadTimeoutTests extends ESTestCase {
.put("xpack.http.default_read_timeout", "10s").build()
, mock(HttpAuthRegistry.class), new SSLService(environment.settings(), environment));
final String path = '/' + randomAsciiOfLength(5);
final CountDownLatch latch = new CountDownLatch(1);
final TimeValue sleepTime = TimeValue.timeValueSeconds(10);
webServer.setDispatcher(new CountDownLatchDispatcher(path, latch, sleepTime));
HttpRequest request = HttpRequest.builder("localhost", webServer.getPort())
.readTimeout(TimeValue.timeValueSeconds(5))
.method(HttpMethod.POST)
.path(path)
.path("/")
.build();
long start = System.nanoTime();
@ -124,32 +99,5 @@ public class HttpReadTimeoutTests extends ESTestCase {
// it's supposed to be 5, but we'll give it an error margin of 2 seconds
assertThat(timeout.seconds(), greaterThan(3L));
assertThat(timeout.seconds(), lessThan(7L));
if (!latch.await(sleepTime.seconds(), TimeUnit.SECONDS)) {
// should never happen
fail("waited too long for the response to be returned");
}
}
private class CountDownLatchDispatcher extends Dispatcher {
private final String path;
private final CountDownLatch latch;
private TimeValue sleepTime;
public CountDownLatchDispatcher(String path, CountDownLatch latch, TimeValue sleepTime) {
this.path = path;
this.latch = latch;
this.sleepTime = sleepTime;
}
@Override
public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
if (path.equals(request.getPath())) {
Thread.sleep(sleepTime.millis());
latch.countDown();
}
return new MockResponse().setStatus("200");
}
}
}

View File

@ -5,11 +5,6 @@
*/
package org.elasticsearch.xpack.monitoring.exporter.http;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.QueueDispatcher;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import okio.Buffer;
import org.elasticsearch.Version;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse;
@ -20,6 +15,7 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings;
@ -29,6 +25,9 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.Scope;
import org.elasticsearch.test.http.MockRequest;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.monitoring.MonitoredSystem;
import org.elasticsearch.xpack.monitoring.MonitoringSettings;
import org.elasticsearch.xpack.monitoring.collector.cluster.ClusterStateMonitoringDoc;
@ -45,8 +44,7 @@ import org.junit.After;
import org.junit.Before;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -79,7 +77,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
@After
public void stopWebServer() throws Exception {
webServer.shutdown();
webServer.close();
}
@Override
@ -223,8 +221,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
assertMonitorResources(webServer, templatesExistsAlready, pipelineExistsAlready, bwcIndexesExist, bwcAliasesExist);
assertBulk(webServer);
final MockWebServer secondWebServer = createMockWebServer();
try {
try (MockWebServer secondWebServer = createMockWebServer()) {
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(
Settings.builder().putArray("xpack.monitoring.exporters._http.host", getFormattedAddress(secondWebServer))));
@ -249,22 +246,22 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
assertMonitorVersion(secondWebServer);
for (Tuple<String, String> template : monitoringTemplates()) {
RecordedRequest recordedRequest = secondWebServer.takeRequest();
MockRequest recordedRequest = secondWebServer.takeRequest();
assertThat(recordedRequest.getMethod(), equalTo("GET"));
assertThat(recordedRequest.getPath(), equalTo("/_template/" + template.v1() + resourceQueryString()));
assertThat(recordedRequest.getUri().getPath(), equalTo("/_template/" + template.v1()));
assertThat(recordedRequest.getUri().getQuery(), equalTo(resourceQueryString()));
if (template.v1().contains(MonitoringBulkTimestampedResolver.Data.DATA) == false) {
recordedRequest = secondWebServer.takeRequest();
assertThat(recordedRequest.getMethod(), equalTo("PUT"));
assertThat(recordedRequest.getPath(), equalTo("/_template/" + template.v1() + resourceQueryString()));
assertThat(recordedRequest.getBody().readUtf8(), equalTo(template.v2()));
assertThat(recordedRequest.getUri().getPath(), equalTo("/_template/" + template.v1()));
assertThat(recordedRequest.getUri().getQuery(), equalTo(resourceQueryString()));
assertThat(recordedRequest.getBody(), equalTo(template.v2()));
}
}
assertMonitorPipelines(secondWebServer, !pipelineExistsAlready, null, null);
assertMonitorBackwardsCompatibilityAliases(secondWebServer, false, null, null);
assertBulk(secondWebServer);
} finally {
secondWebServer.shutdown();
}
}
@ -282,7 +279,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
// fire off what should be an unsuccessful request
assertNull(getExporter(agentNode).openBulk());
assertThat(webServer.getRequestCount(), equalTo(1));
assertThat(webServer.requests(), hasSize(1));
assertMonitorVersion(webServer);
}
@ -307,12 +304,12 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
export(Collections.singletonList(doc));
assertMonitorResources(webServer, templatesExistsAlready, pipelineExistsAlready, bwcIndexesExist, bwcAliasesExist);
RecordedRequest recordedRequest = assertBulk(webServer);
MockRequest recordedRequest = assertBulk(webServer);
@SuppressWarnings("unchecked")
String indexName = new ResolversRegistry(Settings.EMPTY).getResolver(doc).index(doc);
byte[] bytes = recordedRequest.getBody().readByteArray();
byte[] bytes = recordedRequest.getBody().getBytes(StandardCharsets.UTF_8);
Map<String, Object> data = XContentHelper.convertToMap(new BytesArray(bytes), false).v2();
@SuppressWarnings("unchecked")
Map<String, Object> index = (Map<String, Object>) data.get("index");
@ -335,7 +332,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
assertMonitorResources(webServer, true, true, false, false);
recordedRequest = assertBulk(webServer);
bytes = recordedRequest.getBody().readByteArray();
bytes = recordedRequest.getBody().getBytes(StandardCharsets.UTF_8);
data = XContentHelper.convertToMap(new BytesArray(bytes), false).v2();
@SuppressWarnings("unchecked")
final Map<String, Object> newIndex = (Map<String, Object>) data.get("index");
@ -348,11 +345,14 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private void assertMonitorVersion(final MockWebServer webServer, @Nullable final Map<String, String[]> customHeaders,
@Nullable final String basePath) throws Exception {
final String pathPrefix = basePathToAssertablePrefix(basePath);
final RecordedRequest request = webServer.takeRequest();
final MockRequest request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("GET"));
assertThat(request.getPath(), equalTo(pathPrefix + "/?filter_path=version.number"));
final String pathPrefix = basePathToAssertablePrefix(basePath);
if (Strings.isEmpty(pathPrefix) == false) {
assertThat(request.getUri().getPath(), equalTo(pathPrefix + "/"));
}
assertThat(request.getUri().getQuery(), equalTo("filter_path=version.number"));
assertHeaders(request, customHeaders);
}
@ -373,21 +373,23 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private void assertMonitorTemplates(final MockWebServer webServer, final boolean alreadyExists,
@Nullable final Map<String, String[]> customHeaders, @Nullable final String basePath) throws Exception {
final String pathPrefix = basePathToAssertablePrefix(basePath);
RecordedRequest request;
MockRequest request;
for (Tuple<String, String> template : monitoringTemplates()) {
request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("GET"));
assertThat(request.getPath(), equalTo(pathPrefix + "/_template/" + template.v1() + resourceQueryString()));
assertThat(request.getUri().getPath(), equalTo(pathPrefix + "/_template/" + template.v1()));
assertThat(request.getUri().getQuery(), equalTo(resourceQueryString()));
assertHeaders(request, customHeaders);
if (alreadyExists == false) {
request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("PUT"));
assertThat(request.getPath(), equalTo(pathPrefix + "/_template/" + template.v1() + resourceQueryString()));
assertThat(request.getBody().readUtf8(), equalTo(template.v2()));
assertThat(request.getUri().getPath(), equalTo(pathPrefix + "/_template/" + template.v1()));
assertThat(request.getUri().getQuery(), equalTo(resourceQueryString()));
assertThat(request.getBody(), equalTo(template.v2()));
assertHeaders(request, customHeaders);
}
}
@ -396,19 +398,20 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private void assertMonitorPipelines(final MockWebServer webServer, final boolean alreadyExists,
@Nullable final Map<String, String[]> customHeaders, @Nullable final String basePath) throws Exception {
final String pathPrefix = basePathToAssertablePrefix(basePath);
RecordedRequest request = webServer.takeRequest();
MockRequest request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("GET"));
assertThat(request.getPath(), equalTo(pathPrefix + "/_ingest/pipeline/" + Exporter.EXPORT_PIPELINE_NAME + resourceQueryString()));
assertThat(request.getUri().getPath(), equalTo(pathPrefix + "/_ingest/pipeline/" + Exporter.EXPORT_PIPELINE_NAME));
assertThat(request.getUri().getQuery(), equalTo(resourceQueryString()));
assertHeaders(request, customHeaders);
if (alreadyExists == false) {
request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("PUT"));
assertThat(request.getPath(),
equalTo(pathPrefix + "/_ingest/pipeline/" + Exporter.EXPORT_PIPELINE_NAME + resourceQueryString()));
assertThat(request.getBody().readUtf8(), equalTo(Exporter.emptyPipeline(XContentType.JSON).string()));
assertThat(request.getUri().getPath(), equalTo(pathPrefix + "/_ingest/pipeline/" + Exporter.EXPORT_PIPELINE_NAME));
assertThat(request.getUri().getQuery(), equalTo(resourceQueryString()));
assertThat(request.getBody(), equalTo(Exporter.emptyPipeline(XContentType.JSON).string()));
assertHeaders(request, customHeaders);
}
}
@ -416,40 +419,42 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private void assertMonitorBackwardsCompatibilityAliases(final MockWebServer webServer, final boolean expectPost,
@Nullable final Map<String, String[]> customHeaders, @Nullable final String basePath) throws Exception {
final String pathPrefix = basePathToAssertablePrefix(basePath);
RecordedRequest request = webServer.takeRequest();
MockRequest request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("GET"));
assertThat(request.getPath(), startsWith(pathPrefix + "/.marvel-es-1-*"));
assertThat(request.getPath(), containsString("filter_path=*.aliases"));
assertThat(request.getUri().getPath(), startsWith(pathPrefix + "/.marvel-es-1-*"));
assertThat(request.getUri().getQuery(), containsString("filter_path=*.aliases"));
assertHeaders(request, customHeaders);
if (expectPost) {
request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("POST"));
assertThat(request.getPath(), startsWith(pathPrefix + "/_aliases"));
assertThat(request.getPath(), containsString("master_timeout=30s"));
assertThat(request.getBody().readUtf8(), containsString("add"));
assertThat(request.getUri().getPath(), startsWith(pathPrefix + "/_aliases"));
assertThat(request.getUri().getQuery(), containsString("master_timeout=30s"));
assertThat(request.getBody(), containsString("add"));
assertHeaders(request, customHeaders);
}
}
private RecordedRequest assertBulk(final MockWebServer webServer) throws Exception {
private MockRequest assertBulk(final MockWebServer webServer) throws Exception {
return assertBulk(webServer, -1);
}
private RecordedRequest assertBulk(final MockWebServer webServer, final int docs) throws Exception {
private MockRequest assertBulk(final MockWebServer webServer, final int docs) throws Exception {
return assertBulk(webServer, docs, null, null);
}
private RecordedRequest assertBulk(final MockWebServer webServer, final int docs, @Nullable final Map<String, String[]> customHeaders,
@Nullable final String basePath) throws Exception {
private MockRequest assertBulk(final MockWebServer webServer, final int docs,
@Nullable final Map<String, String[]> customHeaders, @Nullable final String basePath)
throws Exception {
final String pathPrefix = basePathToAssertablePrefix(basePath);
final RecordedRequest request = webServer.takeRequest();
final MockRequest request = webServer.takeRequest();
assertThat(request.getMethod(), equalTo("POST"));
assertThat(request.getPath(), equalTo(pathPrefix + "/_bulk" + bulkQueryString()));
assertThat(request.getUri().getPath(), equalTo(pathPrefix + "/_bulk"));
assertThat(request.getUri().getQuery(), equalTo(bulkQueryString()));
assertHeaders(request, customHeaders);
if (docs != -1) {
@ -459,16 +464,18 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
return request;
}
private void assertHeaders(final RecordedRequest request, final Map<String, String[]> customHeaders) {
private void assertHeaders(final MockRequest request, final Map<String, String[]> customHeaders) {
if (customHeaders != null) {
for (final Map.Entry<String, String[]> entry : customHeaders.entrySet()) {
final String header = entry.getKey();
final String[] values = entry.getValue();
final List<String> headerValues = request.getHeaders().values(header);
final List<String> headerValues = request.getHeaders().get(header);
assertThat(header, headerValues, hasSize(values.length));
assertThat(header, headerValues, containsInAnyOrder(values));
if (values.length > 0) {
assertThat(headerValues, hasSize(values.length));
assertThat(headerValues, containsInAnyOrder(values));
}
}
}
}
@ -514,29 +521,20 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
return docs;
}
private String basePathToAssertablePrefix(@Nullable final String basePath) {
private String basePathToAssertablePrefix(@Nullable String basePath) {
if (basePath == null) {
return "";
}
return basePath.startsWith("/") == false ? "/" + basePath : basePath;
basePath = basePath.startsWith("/")? basePath : "/" + basePath;
return basePath;
}
private String resourceQueryString() {
return "?filter_path=" + urlEncode(FILTER_PATH_NONE);
return "filter_path=" + FILTER_PATH_NONE;
}
private String bulkQueryString() {
return "?pipeline=" + urlEncode(Exporter.EXPORT_PIPELINE_NAME) + "&filter_path=" + urlEncode("errors,items.*.error");
}
private String urlEncode(final String value) {
try {
return URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
// whelp, our JVM is broken
throw new RuntimeException(e);
}
return "pipeline=" + Exporter.EXPORT_PIPELINE_NAME + "&filter_path=" + "errors,items.*.error";
}
private void enqueueGetClusterVersionResponse(Version v) throws IOException {
@ -544,8 +542,9 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
}
private void enqueueGetClusterVersionResponse(MockWebServer mockWebServer, Version v) throws IOException {
mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(jsonBuilder().startObject().startObject("version")
.field("number", v.toString()).endObject().endObject().bytes().utf8ToString()));
mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(
jsonBuilder().startObject().startObject("version")
.field("number", v.toString()).endObject().endObject().bytes().utf8ToString()));
}
private void enqueueSetupResponses(MockWebServer webServer, boolean templatesAlreadyExists, boolean pipelineAlreadyExists,
@ -633,8 +632,8 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
mockWebServer.enqueue(new MockResponse().setResponseCode(responseCode).setBody(body));
}
private void assertBulkRequest(Buffer requestBody, int numberOfActions) throws Exception {
BulkRequest bulkRequest = Requests.bulkRequest().add(new BytesArray(requestBody.readByteArray()), null, null);
private void assertBulkRequest(String requestBody, int numberOfActions) throws Exception {
BulkRequest bulkRequest = Requests.bulkRequest().add(new BytesArray(requestBody.getBytes(StandardCharsets.UTF_8)), null, null);
assertThat(bulkRequest.numberOfActions(), equalTo(numberOfActions));
for (DocWriteRequest actionRequest : bulkRequest.requests()) {
assertThat(actionRequest, instanceOf(IndexRequest.class));
@ -648,9 +647,6 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private MockWebServer createMockWebServer() throws IOException {
MockWebServer server = new MockWebServer();
server.start();
final QueueDispatcher dispatcher = new QueueDispatcher();
dispatcher.setFailFast(true);
server.setDispatcher(dispatcher);
return server;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ssl;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import javax.net.ssl.SSLContext;
/**
* Extending SSLService to make helper methods public to access in tests
*/
public class TestsSSLService extends SSLService {
public TestsSSLService(Settings settings, Environment environment) {
super(settings, environment);
}
@Override
public SSLContext sslContext() {
return super.sslContext();
}
/**
* Allows to get alternative ssl context, like for the http client
*/
public SSLContext sslContext(Settings settings) {
return sslContextHolder(super.sslConfiguration(settings)).sslContext();
}
}

View File

@ -5,14 +5,13 @@
*/
package org.elasticsearch.xpack.watcher.actions.email;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.QueueDispatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.Scheme;
import org.elasticsearch.xpack.notification.email.DataAttachment;
@ -61,7 +60,6 @@ import static org.hamcrest.Matchers.startsWith;
public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase {
private MockWebServer webServer = new MockWebServer();
private QueueDispatcher dispatcher = new QueueDispatcher();
private MockResponse mockResponse = new MockResponse().setResponseCode(200)
.addHeader("Content-Type", "application/foo").setBody("This is the content");
private EmailServer server;
@ -69,9 +67,6 @@ public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
dispatcher.setFailFast(true);
webServer.setDispatcher(dispatcher);
webServer.enqueue(mockResponse);
webServer.start();
@ -81,7 +76,7 @@ public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase {
@After
public void cleanup() throws Exception {
server.stop();
webServer.shutdown();
webServer.close();
}
@Override

View File

@ -5,8 +5,6 @@
*/
package org.elasticsearch.xpack.watcher.actions.webhook;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
@ -15,12 +13,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.env.Environment;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
import org.elasticsearch.xpack.ssl.SSLService;
import org.elasticsearch.xpack.watcher.actions.Action;
import org.elasticsearch.xpack.watcher.actions.Action.Result.Status;
import org.elasticsearch.xpack.watcher.execution.TriggeredExecutionContext;
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpClient;
import org.elasticsearch.xpack.common.http.HttpMethod;
import org.elasticsearch.xpack.common.http.HttpProxy;
@ -29,8 +23,18 @@ import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.HttpResponse;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
import org.elasticsearch.xpack.notification.email.Attachment;
import org.elasticsearch.xpack.notification.email.Authentication;
import org.elasticsearch.xpack.notification.email.Email;
import org.elasticsearch.xpack.notification.email.Profile;
import org.elasticsearch.xpack.ssl.SSLService;
import org.elasticsearch.xpack.watcher.actions.Action;
import org.elasticsearch.xpack.watcher.actions.Action.Result.Status;
import org.elasticsearch.xpack.watcher.execution.TriggeredExecutionContext;
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
@ -38,10 +42,6 @@ import org.elasticsearch.xpack.watcher.test.WatcherTestUtils;
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
import org.elasticsearch.xpack.watcher.watch.Payload;
import org.elasticsearch.xpack.watcher.watch.Watch;
import org.elasticsearch.xpack.notification.email.Attachment;
import org.elasticsearch.xpack.notification.email.Authentication;
import org.elasticsearch.xpack.notification.email.Email;
import org.elasticsearch.xpack.notification.email.Profile;
import org.hamcrest.Matchers;
import org.joda.time.DateTime;
import org.junit.Before;
@ -58,6 +58,7 @@ import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.core.Is.is;
import static org.joda.time.DateTimeZone.UTC;
@ -225,8 +226,7 @@ public class WebhookActionTests extends ESTestCase {
HttpClient httpClient = new HttpClient(Settings.EMPTY, authRegistry,
new SSLService(environment.settings(), environment));
MockWebServer proxyServer = new MockWebServer();
try {
try (MockWebServer proxyServer = new MockWebServer()) {
proxyServer.start();
proxyServer.enqueue(new MockResponse().setResponseCode(200).setBody("fullProxiedContent"));
@ -241,9 +241,7 @@ public class WebhookActionTests extends ESTestCase {
new ScheduleTriggerEvent(watchId, new DateTime(UTC), new DateTime(UTC)), timeValueSeconds(5));
executable.execute("_id", ctx, new Payload.Simple());
assertThat(proxyServer.getRequestCount(), is(1));
} finally {
proxyServer.shutdown();
assertThat(proxyServer.requests(), hasSize(1));
}
}

View File

@ -5,18 +5,17 @@
*/
package org.elasticsearch.xpack.watcher.actions.webhook;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.QueueDispatcher;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.Scheme;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.ssl.SSLService;
import org.elasticsearch.xpack.ssl.TestsSSLService;
import org.elasticsearch.xpack.watcher.actions.ActionBuilders;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.history.WatchRecord;
@ -34,6 +33,7 @@ import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.xContentSour
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@ -53,20 +53,15 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
@Before
public void startWebservice() throws Exception {
webServer = new MockWebServer();
webServer.setProtocolNegotiationEnabled(false);
QueueDispatcher dispatcher = new QueueDispatcher();
dispatcher.setFailFast(true);
webServer.setDispatcher(dispatcher);
webServer.start();
SSLService sslService = getInstanceFromMaster(SSLService.class);
Settings settings = getInstanceFromMaster(Settings.class);
webServer.useHttps(sslService.sslSocketFactory(settings.getByPrefix("xpack.http.ssl.")), false);
TestsSSLService sslService = new TestsSSLService(settings, getInstanceFromMaster(Environment.class));
webServer = new MockWebServer(sslService.sslContext(settings.getByPrefix("xpack.http.ssl.")), false);
webServer.start();
}
@After
public void stopWebservice() throws Exception {
webServer.shutdown();
webServer.close();
}
public void testHttps() throws Exception {
@ -90,9 +85,9 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
}
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test/_id"));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("{key=value}"));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), equalTo("/test/_id"));
assertThat(webServer.requests().get(0).getBody(), equalTo("{key=value}"));
SearchResponse response =
searchWatchRecords(b -> b.setQuery(QueryBuilders.termQuery(WatchRecord.Field.STATE.getPreferredName(), "executed")));
@ -129,9 +124,9 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
}
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(), equalTo("/test/_id"));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("{key=value}"));
assertThat(recordedRequest.getHeader("Authorization"), equalTo("Basic X3VzZXJuYW1lOl9wYXNzd29yZA=="));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getPath(), equalTo("/test/_id"));
assertThat(webServer.requests().get(0).getBody(), equalTo("{key=value}"));
assertThat(webServer.requests().get(0).getHeader("Authorization"), equalTo("Basic X3VzZXJuYW1lOl9wYXNzd29yZA=="));
}
}

View File

@ -5,13 +5,10 @@
*/
package org.elasticsearch.xpack.watcher.actions.webhook;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.QueueDispatcher;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.text.TextTemplate;
@ -31,25 +28,22 @@ import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase {
private MockWebServer webServer;
private MockWebServer webServer = new MockWebServer();;
@Before
public void startWebservice() throws Exception {
webServer = new MockWebServer();
QueueDispatcher dispatcher = new QueueDispatcher();
dispatcher.setFailFast(true);
webServer.setDispatcher(dispatcher);
webServer.start();
}
@After
public void stopWebservice() throws Exception {
webServer.shutdown();
webServer.close();
}
public void testWebhook() throws Exception {
@ -74,10 +68,12 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
}
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(),
anyOf(equalTo("/test/_id?watch_id=_id&param1=value1"), equalTo("/test/_id?param1=value1&watch_id=_id")));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("_body"));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getQuery(),
anyOf(equalTo("watch_id=_id&param1=value1"), equalTo("param1=value1&watch_id=_id")));
assertThat(webServer.requests().get(0).getBody(), is("_body"));
SearchResponse response = searchWatchRecords(b -> QueryBuilders.termQuery(WatchRecord.Field.STATE.getPreferredName(), "executed"));
@ -114,10 +110,11 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
}
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
RecordedRequest recordedRequest = webServer.takeRequest();
assertThat(recordedRequest.getPath(),
anyOf(equalTo("/test/_id?watch_id=_id&param1=value1"), equalTo("/test/_id?param1=value1&watch_id=_id")));
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("_body"));
assertThat(recordedRequest.getHeader("Authorization"), equalTo("Basic X3VzZXJuYW1lOl9wYXNzd29yZA=="));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getUri().getQuery(),
anyOf(equalTo("watch_id=_id&param1=value1"), equalTo("param1=value1&watch_id=_id")));
assertThat(webServer.requests().get(0).getBody(), is("_body"));
assertThat(webServer.requests().get(0).getHeader("Authorization"), is(("Basic X3VzZXJuYW1lOl9wYXNzd29yZA==")));
}
}

View File

@ -5,12 +5,12 @@
*/
package org.elasticsearch.xpack.watcher.history;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.QueueDispatcher;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.execution.ExecutionState;
@ -26,6 +26,7 @@ import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBu
import static org.elasticsearch.xpack.watcher.input.InputBuilders.httpInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@ -35,20 +36,16 @@ import static org.hamcrest.Matchers.notNullValue;
*/
public class HistoryTemplateHttpMappingsTests extends AbstractWatcherIntegrationTestCase {
private MockWebServer webServer;
private MockWebServer webServer = new MockWebServer();
@Before
public void init() throws Exception {
QueueDispatcher dispatcher = new QueueDispatcher();
dispatcher.setFailFast(true);
webServer = new MockWebServer();
webServer.setDispatcher(dispatcher);
webServer.start();
}
@After
public void cleanup() throws Exception {
webServer.shutdown();
webServer.close();
}
@Override
@ -61,6 +58,7 @@ public class HistoryTemplateHttpMappingsTests extends AbstractWatcherIntegration
return false; // remove security noise from this test
}
@TestLogging("org.elasticsearch.test.http:TRACE")
public void testHttpFields() throws Exception {
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()
.trigger(schedule(interval("5s")))
@ -72,6 +70,8 @@ public class HistoryTemplateHttpMappingsTests extends AbstractWatcherIntegration
.get();
// one for the input, one for the webhook
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));
assertThat(putWatchResponse.isCreated(), is(true));
@ -104,5 +104,9 @@ public class HistoryTemplateHttpMappingsTests extends AbstractWatcherIntegration
assertThat(terms.getBuckets().size(), is(1));
assertThat(terms.getBucketByKey("/webhook/path"), notNullValue());
assertThat(terms.getBucketByKey("/webhook/path").getDocCount(), is(1L));
assertThat(webServer.requests(), hasSize(2));
assertThat(webServer.requests().get(0).getUri().getPath(), is("/input/path"));
assertThat(webServer.requests().get(1).getUri().getPath(), is("/webhook/path"));
}
}

View File

@ -5,12 +5,11 @@
*/
package org.elasticsearch.xpack.watcher.test.integration;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.auth.basic.ApplicableBasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
@ -39,7 +38,7 @@ import static org.elasticsearch.xpack.watcher.input.InputBuilders.httpInput;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.cron;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
@ -52,18 +51,17 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
static final String USERNAME = "_user";
static final String PASSWORD = "_passwd";
private MockWebServer webServer;
private MockWebServer webServer = new MockWebServer();;
private static Boolean encryptSensitiveData;
@Before
public void init() throws Exception {
webServer = new MockWebServer();
webServer.start();
}
@After
public void cleanup() throws Exception {
webServer.shutdown();
webServer.close();
}
@Override
@ -139,8 +137,9 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
assertThat(value, notNullValue());
assertThat(value, is((Object) 200));
RecordedRequest request = webServer.takeRequest();
assertThat(request.getHeader("Authorization"), equalTo(ApplicableBasicAuth.headerValue(USERNAME, PASSWORD.toCharArray())));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getHeader("Authorization"),
is(ApplicableBasicAuth.headerValue(USERNAME, PASSWORD.toCharArray())));
}
public void testWebhookAction() throws Exception {
@ -216,7 +215,8 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
value = contentSource.getValue("result.actions.0.webhook.request.auth.basic.password");
assertThat(value, nullValue()); // but the auth password was filtered out
RecordedRequest request = webServer.takeRequest();
assertThat(request.getHeader("Authorization"), equalTo(ApplicableBasicAuth.headerValue(USERNAME, PASSWORD.toCharArray())));
assertThat(webServer.requests(), hasSize(1));
assertThat(webServer.requests().get(0).getHeader("Authorization"),
is(ApplicableBasicAuth.headerValue(USERNAME, PASSWORD.toCharArray())));
}
}

View File

@ -5,10 +5,11 @@
*/
package org.elasticsearch.xpack.watcher.transport.action.delete;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import org.elasticsearch.action.ListenableActionFuture;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.history.HistoryStore;
@ -21,7 +22,6 @@ import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.carrotsearch.randomizedtesting.RandomizedTest.sleep;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
@ -76,12 +76,10 @@ public class DeleteWatchTests extends AbstractWatcherIntegrationTestCase {
MockResponse response = new MockResponse();
response.setBody("foo");
response.setResponseCode(200);
response.setBodyDelay(5, TimeUnit.SECONDS);
response.setBodyDelay(TimeValue.timeValueSeconds(5));
MockWebServer server = new MockWebServer();
server.enqueue(response);
try {
try (MockWebServer server = new MockWebServer()) {
server.enqueue(response);
server.start();
HttpRequestTemplate template = HttpRequestTemplate.builder(server.getHostName(), server.getPort()).path("/").build();
@ -119,8 +117,6 @@ public class DeleteWatchTests extends AbstractWatcherIntegrationTestCase {
assertThat(state, is("executed"));
// no exception occured
assertThat(source, not(hasKey("exception")));
} finally {
server.shutdown();
}
}
}