Added a `scheme` option to the `http` input that supports the values http or https.
Closes elastic/elasticsearch#174 Original commit: elastic/x-pack-elasticsearch@9ad7665b66
This commit is contained in:
parent
a778f1978d
commit
feb745763b
|
@ -10,6 +10,7 @@ import org.elasticsearch.action.search.SearchRequestBuilder;
|
|||
import org.elasticsearch.watcher.input.http.HttpInput;
|
||||
import org.elasticsearch.watcher.input.search.SearchInput;
|
||||
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||
import org.elasticsearch.watcher.support.http.TemplatedHttpRequest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -38,7 +39,7 @@ public final class InputBuilders {
|
|||
return new SimpleInput.SourceBuilder(data);
|
||||
}
|
||||
|
||||
public static HttpInput.SourceBuilder httpInput() {
|
||||
return new HttpInput.SourceBuilder();
|
||||
public static HttpInput.SourceBuilder httpInput(TemplatedHttpRequest.SourceBuilder requestSource) {
|
||||
return new HttpInput.SourceBuilder(requestSource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ import org.elasticsearch.watcher.support.http.HttpClient;
|
|||
import org.elasticsearch.watcher.support.http.HttpRequest;
|
||||
import org.elasticsearch.watcher.support.http.HttpResponse;
|
||||
import org.elasticsearch.watcher.support.http.TemplatedHttpRequest;
|
||||
import org.elasticsearch.watcher.support.http.auth.HttpAuth;
|
||||
import org.elasticsearch.watcher.support.template.Template;
|
||||
import org.elasticsearch.watcher.watch.Payload;
|
||||
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||
|
||||
|
@ -78,7 +76,7 @@ public class HttpInput extends Input<HttpInput.Result> {
|
|||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(Parser.REQUEST_FIELD.getPreferredName());
|
||||
builder = request.toXContent(builder, params);
|
||||
builder = request.toXContent(builder, params);
|
||||
if (extractKeys != null) {
|
||||
builder.startArray(Parser.EXTRACT_FIELD.getPreferredName());
|
||||
for (String extractKey : extractKeys) {
|
||||
|
@ -232,54 +230,11 @@ public class HttpInput extends Input<HttpInput.Result> {
|
|||
|
||||
public final static class SourceBuilder implements Input.SourceBuilder {
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
private String method;
|
||||
private Template path;
|
||||
private Map<String, Template> params;
|
||||
private Map<String, Template> headers;
|
||||
private HttpAuth auth;
|
||||
private Template body;
|
||||
private TemplatedHttpRequest.SourceBuilder request;
|
||||
private Set<String> extractKeys;
|
||||
|
||||
public SourceBuilder setHost(String host) {
|
||||
this.host = host;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setPort(int port) {
|
||||
this.port = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setMethod(String method) {
|
||||
this.method = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setPath(Template path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setParams(Map<String, Template> params) {
|
||||
this.params = params;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setHeaders(Map<String, Template> headers) {
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setAuth(HttpAuth auth) {
|
||||
this.auth = auth;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setBody(Template body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
public SourceBuilder(TemplatedHttpRequest.SourceBuilder request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public SourceBuilder addExtractKey(String key) {
|
||||
|
@ -296,7 +251,7 @@ public class HttpInput extends Input<HttpInput.Result> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params p) throws IOException {
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
if (extractKeys != null) {
|
||||
builder.startArray(Parser.EXTRACT_FIELD.getPreferredName());
|
||||
|
@ -305,28 +260,8 @@ public class HttpInput extends Input<HttpInput.Result> {
|
|||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.startObject(Parser.REQUEST_FIELD.getPreferredName());
|
||||
builder.field(HttpRequest.Parser.HOST_FIELD.getPreferredName(), host);
|
||||
builder.field(HttpRequest.Parser.PORT_FIELD.getPreferredName(), port);
|
||||
if (method != null) {
|
||||
builder.field(HttpRequest.Parser.METHOD_FIELD.getPreferredName(), method);
|
||||
}
|
||||
if (path != null) {
|
||||
builder.field(HttpRequest.Parser.PATH_FIELD.getPreferredName(), path);
|
||||
}
|
||||
if (params != null) {
|
||||
builder.field(HttpRequest.Parser.PARAMS_FIELD.getPreferredName(), params);
|
||||
}
|
||||
if (headers != null) {
|
||||
builder.field(HttpRequest.Parser.HEADERS_FIELD.getPreferredName(), headers);
|
||||
}
|
||||
if (auth != null) {
|
||||
builder.field(HttpRequest.Parser.AUTH_FIELD.getPreferredName(), auth);
|
||||
}
|
||||
if (body != null) {
|
||||
builder.field(HttpRequest.Parser.BODY_FIELD.getPreferredName(), body);
|
||||
}
|
||||
builder.endObject();
|
||||
builder.field(Parser.REQUEST_FIELD.getPreferredName());
|
||||
request.toXContent(builder, params);
|
||||
return builder.endObject();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,22 @@
|
|||
*/
|
||||
package org.elasticsearch.watcher.support.http;
|
||||
|
||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.common.base.Charsets;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -20,9 +28,30 @@ import java.util.Map;
|
|||
*/
|
||||
public class HttpClient extends AbstractComponent {
|
||||
|
||||
private static final String SETTINGS_SSL_PREFIX = "watcher.http.ssl.";
|
||||
private static final String SETTINGS_SSL_SHIELD_PREFIX = "shield.ssl.";
|
||||
|
||||
public static final String SETTINGS_SSL_PROTOCOL = SETTINGS_SSL_PREFIX + "protocol";
|
||||
private static final String SETTINGS_SSL_SHIELD_CONTEXT_ALGORITHM = SETTINGS_SSL_SHIELD_PREFIX + "context.algorithm";
|
||||
public static final String SETTINGS_SSL_TRUSTSTORE = SETTINGS_SSL_PREFIX + "truststore.path";
|
||||
private static final String SETTINGS_SSL_SHIELD_TRUSTSTORE = SETTINGS_SSL_SHIELD_PREFIX + "truststore.path";
|
||||
public static final String SETTINGS_SSL_TRUSTSTORE_PASSWORD = SETTINGS_SSL_PREFIX + "truststore.password";
|
||||
private static final String SETTINGS_SSL_SHIELD_TRUSTSTORE_PASSWORD = SETTINGS_SSL_SHIELD_PREFIX + "truststore.password";
|
||||
public static final String SETTINGS_SSL_TRUSTSTORE_ALGORITHM = SETTINGS_SSL_PREFIX + "truststore.algorithm";
|
||||
private static final String SETTINGS_SSL_SHIELD_TRUSTSTORE_ALGORITHM = SETTINGS_SSL_SHIELD_PREFIX + "truststore.algorithm";
|
||||
|
||||
final SSLSocketFactory sslSocketFactory;
|
||||
|
||||
@Inject
|
||||
public HttpClient(Settings settings) {
|
||||
super(settings);
|
||||
if (!settings.getByPrefix(SETTINGS_SSL_PREFIX).getAsMap().isEmpty() ||
|
||||
!settings.getByPrefix(SETTINGS_SSL_SHIELD_PREFIX).getAsMap().isEmpty()) {
|
||||
sslSocketFactory = createSSLSocketFactory(settings);
|
||||
} else {
|
||||
logger.trace("no ssl context configured");
|
||||
sslSocketFactory = null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove this when webhook action has been refactored to use this client properly
|
||||
|
@ -50,7 +79,7 @@ public class HttpClient extends AbstractComponent {
|
|||
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI("http", null, request.host(), request.port(), request.path(), queryString, null);
|
||||
uri = new URI(request.scheme().scheme(), null, request.host(), request.port(), request.path(), queryString, null);
|
||||
} catch (URISyntaxException e) {
|
||||
throw ExceptionsHelper.convertToElastic(e);
|
||||
}
|
||||
|
@ -63,6 +92,11 @@ public class HttpClient extends AbstractComponent {
|
|||
logger.debug("making [{}] request to [{}]", request.method().method(), url);
|
||||
logger.trace("sending [{}] as body of request", request.body());
|
||||
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||
if (urlConnection instanceof HttpsURLConnection && sslSocketFactory != null) {
|
||||
HttpsURLConnection httpsConn = (HttpsURLConnection) urlConnection;
|
||||
httpsConn.setSSLSocketFactory(sslSocketFactory);
|
||||
}
|
||||
|
||||
urlConnection.setRequestMethod(request.method().method());
|
||||
if (request.headers() != null) {
|
||||
for (Map.Entry<String, String> entry : request.headers().entrySet()) {
|
||||
|
@ -89,4 +123,57 @@ public class HttpClient extends AbstractComponent {
|
|||
return response;
|
||||
}
|
||||
|
||||
/** SSL Initialization * */
|
||||
private SSLSocketFactory createSSLSocketFactory(Settings settings) {
|
||||
SSLContext sslContext;
|
||||
// Initialize sslContext
|
||||
try {
|
||||
String sslContextProtocol = settings.get(SETTINGS_SSL_PROTOCOL, settings.get(SETTINGS_SSL_SHIELD_CONTEXT_ALGORITHM, "TLS"));
|
||||
String trustStore = settings.get(SETTINGS_SSL_TRUSTSTORE, settings.get(SETTINGS_SSL_SHIELD_TRUSTSTORE, System.getProperty("javax.net.ssl.trustStore")));
|
||||
String trustStorePassword = settings.get(SETTINGS_SSL_TRUSTSTORE_PASSWORD, settings.get(SETTINGS_SSL_SHIELD_TRUSTSTORE_PASSWORD, System.getProperty("javax.net.ssl.trustStorePassword")));
|
||||
String trustStoreAlgorithm = settings.get(SETTINGS_SSL_TRUSTSTORE_ALGORITHM, settings.get(SETTINGS_SSL_SHIELD_TRUSTSTORE_ALGORITHM, System.getProperty("ssl.TrustManagerFactory.algorithm")));
|
||||
|
||||
if (trustStore == null) {
|
||||
throw new RuntimeException("truststore is not configured, use " + SETTINGS_SSL_TRUSTSTORE);
|
||||
}
|
||||
|
||||
if (trustStoreAlgorithm == null) {
|
||||
trustStoreAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
}
|
||||
|
||||
logger.debug("SSL: using trustStore[{}], trustAlgorithm[{}]", trustStore, trustStoreAlgorithm);
|
||||
Path path = Paths.get(trustStore);
|
||||
if (Files.notExists(path)) {
|
||||
throw new ElasticsearchIllegalStateException("Truststore at path [" + trustStore + "] does not exist");
|
||||
}
|
||||
|
||||
KeyManager[] keyManagers;
|
||||
TrustManager[] trustManagers;
|
||||
try (InputStream trustStoreStream = Files.newInputStream(path)) {
|
||||
// Load TrustStore
|
||||
KeyStore ks = KeyStore.getInstance("jks");
|
||||
ks.load(trustStoreStream, trustStorePassword == null ? null : trustStorePassword.toCharArray());
|
||||
|
||||
KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
factory.init(ks, trustStorePassword == null ? null : trustStorePassword.toCharArray());
|
||||
keyManagers = factory.getKeyManagers();
|
||||
|
||||
// Initialize a trust manager factory with the trusted store
|
||||
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(trustStoreAlgorithm);
|
||||
trustFactory.init(ks);
|
||||
|
||||
// Retrieve the trust managers from the factory
|
||||
trustManagers = trustFactory.getTrustManagers();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to initialize a TrustManagerFactory", e);
|
||||
}
|
||||
|
||||
sslContext = SSLContext.getInstance(sslContextProtocol);
|
||||
sslContext.init(keyManagers, trustManagers, new SecureRandom());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("[http.client] failed to initialize the SSLContext", e);
|
||||
}
|
||||
return sslContext.getSocketFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
|||
|
||||
public class HttpRequest implements ToXContent {
|
||||
|
||||
private Scheme scheme;
|
||||
private String host;
|
||||
private int port;
|
||||
private HttpMethod method;
|
||||
|
@ -31,9 +32,18 @@ public class HttpRequest implements ToXContent {
|
|||
private String body;
|
||||
|
||||
public HttpRequest() {
|
||||
scheme = Scheme.HTTP;
|
||||
method = HttpMethod.GET;
|
||||
}
|
||||
|
||||
public Scheme scheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public void scheme(Scheme scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public String host() {
|
||||
return host;
|
||||
}
|
||||
|
@ -129,6 +139,7 @@ public class HttpRequest implements ToXContent {
|
|||
|
||||
HttpRequest request = (HttpRequest) o;
|
||||
|
||||
if (scheme != request.scheme) return false;
|
||||
if (port != request.port) return false;
|
||||
if (auth != null ? !auth.equals(request.auth) : request.auth != null) return false;
|
||||
if (body != null ? !body.equals(request.body) : request.body != null) return false;
|
||||
|
@ -146,6 +157,7 @@ public class HttpRequest implements ToXContent {
|
|||
int result = host.hashCode();
|
||||
result = 31 * result + port;
|
||||
result = 31 * result + method.hashCode();
|
||||
result = 31 * result + scheme.hashCode();
|
||||
result = 31 * result + (path != null ? path.hashCode() : 0);
|
||||
result = 31 * result + (params != null ? params.hashCode() : 0);
|
||||
result = 31 * result + (headers != null ? headers.hashCode() : 0);
|
||||
|
@ -156,6 +168,7 @@ public class HttpRequest implements ToXContent {
|
|||
|
||||
public static class Parser {
|
||||
|
||||
public static final ParseField SCHEME_FIELD = new ParseField("scheme");
|
||||
public static final ParseField HOST_FIELD = new ParseField("host");
|
||||
public static final ParseField PORT_FIELD = new ParseField("port");
|
||||
public static final ParseField METHOD_FIELD = new ParseField("method");
|
||||
|
@ -192,7 +205,9 @@ public class HttpRequest implements ToXContent {
|
|||
throw new ElasticsearchParseException("could not parse http request. unexpected field [" + currentFieldName + "]");
|
||||
}
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
if (METHOD_FIELD.match(currentFieldName)) {
|
||||
if (SCHEME_FIELD.match(currentFieldName)) {
|
||||
request.scheme(Scheme.parse(parser.text()));
|
||||
} else if (METHOD_FIELD.match(currentFieldName)) {
|
||||
request.method(HttpMethod.parse(parser.text()));
|
||||
} else if (HOST_FIELD.match(currentFieldName)) {
|
||||
request.host(parser.text());
|
||||
|
@ -210,7 +225,7 @@ public class HttpRequest implements ToXContent {
|
|||
throw new ElasticsearchParseException("could not parse http request. unexpected field [" + currentFieldName + "]");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("could not parse http request. unexpected token [" + token + "]");
|
||||
throw new ElasticsearchParseException("could not parse http request. unexpected token [" + token + "] for field [" + currentFieldName + "]");
|
||||
}
|
||||
}
|
||||
return request;
|
||||
|
@ -220,6 +235,7 @@ public class HttpRequest implements ToXContent {
|
|||
|
||||
public final static class SourceBuilder implements ToXContent {
|
||||
|
||||
private String scheme;
|
||||
private String host;
|
||||
private int port;
|
||||
private String method;
|
||||
|
@ -229,6 +245,11 @@ public class HttpRequest implements ToXContent {
|
|||
private HttpAuth auth;
|
||||
private Template body;
|
||||
|
||||
public SourceBuilder setScheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setHost(String host) {
|
||||
this.host = host;
|
||||
return this;
|
||||
|
@ -272,6 +293,9 @@ public class HttpRequest implements ToXContent {
|
|||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params p) throws IOException {
|
||||
builder.startObject();
|
||||
if (scheme != null) {
|
||||
builder.field(Parser.SCHEME_FIELD.getPreferredName(), scheme);
|
||||
}
|
||||
builder.field(HttpRequest.Parser.HOST_FIELD.getPreferredName(), host);
|
||||
builder.field(HttpRequest.Parser.PORT_FIELD.getPreferredName(), port);
|
||||
if (method != null) {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.watcher.support.http;
|
||||
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public enum Scheme {
|
||||
|
||||
HTTP("http"),
|
||||
HTTPS("https");
|
||||
|
||||
private final String scheme;
|
||||
|
||||
Scheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public String scheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public static Scheme parse(String value) {
|
||||
value = value.toLowerCase(Locale.ROOT);
|
||||
switch (value) {
|
||||
case "http":
|
||||
return HTTP;
|
||||
case "https":
|
||||
return HTTPS;
|
||||
default:
|
||||
throw new ElasticsearchIllegalArgumentException("unsupported http scheme [" + value + "]");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ import java.util.Map;
|
|||
*/
|
||||
public class TemplatedHttpRequest implements ToXContent {
|
||||
|
||||
private Scheme scheme;
|
||||
private String host;
|
||||
private int port;
|
||||
private HttpMethod method;
|
||||
|
@ -34,9 +35,18 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
private Template body;
|
||||
|
||||
public TemplatedHttpRequest() {
|
||||
scheme = Scheme.HTTP;
|
||||
method = HttpMethod.GET;
|
||||
}
|
||||
|
||||
public Scheme scheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public void scheme(Scheme scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public String host() {
|
||||
return host;
|
||||
}
|
||||
|
@ -132,6 +142,7 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
|
||||
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(Parser.SCHEME_FIELD.getPreferredName(), scheme);
|
||||
builder.field(Parser.HOST_FIELD.getPreferredName(), host);
|
||||
builder.field(Parser.PORT_FIELD.getPreferredName(), port);
|
||||
builder.field(Parser.METHOD_FIELD.getPreferredName(), method);
|
||||
|
@ -155,6 +166,7 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
|
||||
public static class Parser {
|
||||
|
||||
public static final ParseField SCHEME_FIELD = new ParseField("scheme");
|
||||
public static final ParseField HOST_FIELD = new ParseField("host");
|
||||
public static final ParseField PORT_FIELD = new ParseField("port");
|
||||
public static final ParseField METHOD_FIELD = new ParseField("method");
|
||||
|
@ -195,7 +207,9 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
throw new ElasticsearchParseException("could not parse templated http request. unexpected field [" + currentFieldName + "]");
|
||||
}
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
if (METHOD_FIELD.match(currentFieldName)) {
|
||||
if (SCHEME_FIELD.match(currentFieldName)) {
|
||||
request.scheme(Scheme.parse(parser.text()));
|
||||
} else if (METHOD_FIELD.match(currentFieldName)) {
|
||||
request.method(HttpMethod.parse(parser.text()));
|
||||
} else if (HOST_FIELD.match(currentFieldName)) {
|
||||
request.host(parser.text());
|
||||
|
@ -213,7 +227,7 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
throw new ElasticsearchParseException("could not parse templated http request. unexpected field [" + currentFieldName + "]");
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("could not parse templated http request. unexpected token [" + token + "]");
|
||||
throw new ElasticsearchParseException("could not parse templated http request. unexpected token [" + token + "] for field [" + currentFieldName + "]");
|
||||
}
|
||||
}
|
||||
return request;
|
||||
|
@ -240,4 +254,92 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
|
||||
}
|
||||
|
||||
public final static class SourceBuilder implements ToXContent {
|
||||
|
||||
private String scheme;
|
||||
private String host;
|
||||
private int port;
|
||||
private String method;
|
||||
private Template path;
|
||||
private Map<String, Template> params;
|
||||
private Map<String, Template> headers;
|
||||
private HttpAuth auth;
|
||||
private Template body;
|
||||
|
||||
public SourceBuilder setScheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setHost(String host) {
|
||||
this.host = host;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setPort(int port) {
|
||||
this.port = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setMethod(String method) {
|
||||
this.method = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setPath(Template path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setParams(Map<String, Template> params) {
|
||||
this.params = params;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setHeaders(Map<String, Template> headers) {
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setAuth(HttpAuth auth) {
|
||||
this.auth = auth;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SourceBuilder setBody(Template body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params p) throws IOException {
|
||||
builder.startObject();
|
||||
if (scheme != null) {
|
||||
builder.field(Parser.SCHEME_FIELD.getPreferredName(), scheme);
|
||||
}
|
||||
builder.field(Parser.HOST_FIELD.getPreferredName(), host);
|
||||
builder.field(Parser.PORT_FIELD.getPreferredName(), port);
|
||||
if (method != null) {
|
||||
builder.field(Parser.METHOD_FIELD.getPreferredName(), method);
|
||||
}
|
||||
if (path != null) {
|
||||
builder.field(Parser.PATH_FIELD.getPreferredName(), path);
|
||||
}
|
||||
if (params != null) {
|
||||
builder.field(Parser.PARAMS_FIELD.getPreferredName(), params);
|
||||
}
|
||||
if (headers != null) {
|
||||
builder.field(Parser.HEADERS_FIELD.getPreferredName(), headers);
|
||||
}
|
||||
if (auth != null) {
|
||||
builder.field(Parser.AUTH_FIELD.getPreferredName(), auth);
|
||||
}
|
||||
if (body != null) {
|
||||
builder.field(Parser.BODY_FIELD.getPreferredName(), body);
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.watcher.actions.Action;
|
|||
import org.elasticsearch.watcher.actions.Actions;
|
||||
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
|
||||
import org.elasticsearch.watcher.input.Input;
|
||||
import org.elasticsearch.watcher.input.InputBuilders;
|
||||
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||
import org.elasticsearch.watcher.support.clock.ClockMock;
|
||||
import org.elasticsearch.watcher.support.http.*;
|
||||
|
@ -108,6 +109,7 @@ public class HttpInputTests extends ElasticsearchTestCase {
|
|||
@Repeat(iterations = 12)
|
||||
public void testParser() throws Exception {
|
||||
final String httpMethod = randomFrom("PUT", "POST", "GET", "DELETE", "HEAD", null);
|
||||
String scheme = randomFrom("http", "https", null);
|
||||
String host = randomAsciiOfLength(3);
|
||||
int port = randomInt();
|
||||
Template path = new MockTemplate(randomAsciiOfLength(3));
|
||||
|
@ -115,7 +117,8 @@ public class HttpInputTests extends ElasticsearchTestCase {
|
|||
Map<String, Template> params = randomBoolean() ? new MapBuilder<String, Template>().put("a", new MockTemplate("b")).map() : null;
|
||||
Map<String, Template> headers = randomBoolean() ? new MapBuilder<String, Template>().put("c", new MockTemplate("d")).map() : null;
|
||||
HttpAuth auth = randomBoolean() ? new BasicAuth("username", "password") : null;
|
||||
HttpInput.SourceBuilder sourceBuilder = new HttpInput.SourceBuilder()
|
||||
TemplatedHttpRequest.SourceBuilder requestSource = new TemplatedHttpRequest.SourceBuilder()
|
||||
.setScheme(scheme)
|
||||
.setMethod(httpMethod)
|
||||
.setHost(host)
|
||||
.setPort(port)
|
||||
|
@ -124,11 +127,12 @@ public class HttpInputTests extends ElasticsearchTestCase {
|
|||
.setParams(params)
|
||||
.setHeaders(headers)
|
||||
.setAuth(auth);
|
||||
XContentParser parser = XContentHelper.createParser(jsonBuilder().value(sourceBuilder).bytes());
|
||||
XContentParser parser = XContentHelper.createParser(jsonBuilder().value(InputBuilders.httpInput(requestSource)).bytes());
|
||||
parser.nextToken();
|
||||
HttpInput result = httpParser.parse(parser);
|
||||
|
||||
assertThat(result.type(), equalTo(HttpInput.TYPE));
|
||||
assertThat(result.getRequest().scheme().scheme(), equalTo(scheme != null ? scheme : "http")); // http is the default
|
||||
assertThat(result.getRequest().method().method(), equalTo(httpMethod != null ? httpMethod : "GET")); // get is the default
|
||||
assertThat(result.getRequest().host(), equalTo(host));
|
||||
assertThat(result.getRequest().port(), equalTo(port));
|
||||
|
@ -146,13 +150,13 @@ public class HttpInputTests extends ElasticsearchTestCase {
|
|||
@Test(expected = ElasticsearchIllegalArgumentException.class)
|
||||
public void testParser_invalidHttpMethod() throws Exception {
|
||||
Map<String, Template> headers = new MapBuilder<String, Template>().put("a", new MockTemplate("b")).map();
|
||||
HttpInput.SourceBuilder sourceBuilder = new HttpInput.SourceBuilder()
|
||||
TemplatedHttpRequest.SourceBuilder requestBuilder = new TemplatedHttpRequest.SourceBuilder()
|
||||
.setMethod("_method")
|
||||
.setHost("_host")
|
||||
.setPort(123)
|
||||
.setBody(new MockTemplate("_body"))
|
||||
.setHeaders(headers);
|
||||
XContentParser parser = XContentHelper.createParser(jsonBuilder().value(sourceBuilder).bytes());
|
||||
XContentParser parser = XContentHelper.createParser(jsonBuilder().value(InputBuilders.httpInput(requestBuilder)).bytes());
|
||||
parser.nextToken();
|
||||
httpParser.parse(parser);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import java.net.BindException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
|
@ -105,4 +107,29 @@ public class HttpClientTest extends ElasticsearchTestCase {
|
|||
assertThat(recordedRequest.getHeader("Authorization"), equalTo("Basic dXNlcjpwYXNz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttps() throws Exception {
|
||||
Path resource = Paths.get(HttpClientTest.class.getResource("/org/elasticsearch/shield/keystore/testnode.jks").toURI());
|
||||
HttpClient httpClient = new HttpClient(
|
||||
ImmutableSettings.builder()
|
||||
.put(HttpClient.SETTINGS_SSL_TRUSTSTORE, resource.toString())
|
||||
.put(HttpClient.SETTINGS_SSL_TRUSTSTORE_PASSWORD, "testnode")
|
||||
.build()
|
||||
);
|
||||
webServer.useHttps(httpClient.sslSocketFactory, false);
|
||||
|
||||
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
|
||||
HttpRequest request = new HttpRequest();
|
||||
request.scheme(Scheme.HTTPS);
|
||||
request.host("localhost");
|
||||
request.port(webPort);
|
||||
request.path("/test");
|
||||
request.body("body");
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
assertThat(response.status(), equalTo(200));
|
||||
assertThat(new String(response.body(), Charsets.UTF_8), equalTo("body"));
|
||||
RecordedRequest recordedRequest = webServer.takeRequest();
|
||||
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("body"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
|
|||
import org.elasticsearch.watcher.WatcherPlugin;
|
||||
import org.elasticsearch.watcher.client.WatchSourceBuilder;
|
||||
import org.elasticsearch.watcher.client.WatcherClient;
|
||||
import org.elasticsearch.watcher.support.http.TemplatedHttpRequest;
|
||||
import org.elasticsearch.watcher.transport.actions.put.PutWatchRequest;
|
||||
import org.elasticsearch.watcher.trigger.ScheduleTriggerEngineMock;
|
||||
import org.elasticsearch.watcher.trigger.TriggerModule;
|
||||
|
@ -168,7 +169,7 @@ public class WatcherBenchmark {
|
|||
final String name = "_name" + i;
|
||||
PutWatchRequest putAlertRequest = new PutWatchRequest(name, new WatchSourceBuilder()
|
||||
.trigger(schedule(interval("5s")))
|
||||
.input(httpInput().setHost("localhost").setPort(9200))
|
||||
.input(httpInput(new TemplatedHttpRequest.SourceBuilder().setHost("localhost").setPort(9200)))
|
||||
.condition(scriptCondition("ctx.payload.tagline == \"You Know, for Search\"")));
|
||||
putAlertRequest.setName(name);
|
||||
watcherClient.putWatch(putAlertRequest).actionGet();
|
||||
|
|
|
@ -13,7 +13,8 @@ import org.elasticsearch.node.internal.InternalNode;
|
|||
import org.elasticsearch.watcher.client.WatchSourceBuilder;
|
||||
import org.elasticsearch.watcher.client.WatcherClient;
|
||||
import org.elasticsearch.watcher.history.HistoryStore;
|
||||
import org.elasticsearch.watcher.input.http.HttpInput;
|
||||
import org.elasticsearch.watcher.input.InputBuilders;
|
||||
import org.elasticsearch.watcher.support.http.TemplatedHttpRequest;
|
||||
import org.elasticsearch.watcher.support.http.auth.BasicAuth;
|
||||
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||
import org.elasticsearch.watcher.support.template.ScriptTemplate;
|
||||
|
@ -32,7 +33,6 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitC
|
|||
import static org.elasticsearch.watcher.actions.ActionBuilders.indexAction;
|
||||
import static org.elasticsearch.watcher.client.WatchSourceBuilder.watchSourceBuilder;
|
||||
import static org.elasticsearch.watcher.condition.ConditionBuilders.scriptCondition;
|
||||
import static org.elasticsearch.watcher.input.InputBuilders.httpInput;
|
||||
import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule;
|
||||
import static org.elasticsearch.watcher.trigger.schedule.Schedules.interval;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -61,17 +61,17 @@ public class HttpInputIntegrationTest extends AbstractWatcherIntegrationTests {
|
|||
client().prepareIndex("index", "type", "id").setSource("{}").setRefresh(true).get();
|
||||
|
||||
InetSocketAddress address = internalTestCluster().httpAddresses()[0];
|
||||
HttpInput.SourceBuilder input = httpInput()
|
||||
TemplatedHttpRequest.SourceBuilder requestBuilder = new TemplatedHttpRequest.SourceBuilder()
|
||||
.setHost(address.getHostName())
|
||||
.setPort(address.getPort())
|
||||
.setPath(new ScriptTemplate(sc, "/index/_search"))
|
||||
.setBody(new ScriptTemplate(sc, jsonBuilder().startObject().field("size", 1).endObject().string()));
|
||||
if (shieldEnabled()) {
|
||||
input.setAuth(new BasicAuth("test", "changeme"));
|
||||
requestBuilder.setAuth(new BasicAuth("test", "changeme"));
|
||||
}
|
||||
WatchSourceBuilder source = watchSourceBuilder()
|
||||
.trigger(TriggerBuilders.schedule(interval("5s")))
|
||||
.input(input)
|
||||
.input(InputBuilders.httpInput(requestBuilder))
|
||||
.condition(scriptCondition("ctx.payload.hits.total == 1"))
|
||||
.addAction(indexAction("idx", "action"));
|
||||
watcherClient().preparePutWatch("_name")
|
||||
|
@ -98,20 +98,19 @@ public class HttpInputIntegrationTest extends AbstractWatcherIntegrationTests {
|
|||
String body = jsonBuilder().prettyPrint().startObject()
|
||||
.field("query").value(termQuery("field", "value"))
|
||||
.endObject().string();
|
||||
HttpInput.SourceBuilder httpInputBuilder = httpInput()
|
||||
TemplatedHttpRequest.SourceBuilder requestBuilder = new TemplatedHttpRequest.SourceBuilder()
|
||||
.setHost(address.getHostName())
|
||||
.setPort(address.getPort())
|
||||
.setPath(new ScriptTemplate(sc, "/idx/_search"))
|
||||
.setBody(new ScriptTemplate(sc, body))
|
||||
.addExtractKey("hits.total");
|
||||
.setBody(new ScriptTemplate(sc, body));
|
||||
if (shieldEnabled()) {
|
||||
httpInputBuilder.setAuth(new BasicAuth("test", "changeme"));
|
||||
requestBuilder.setAuth(new BasicAuth("test", "changeme"));
|
||||
}
|
||||
|
||||
watcherClient.preparePutWatch("_name1")
|
||||
.source(watchSourceBuilder()
|
||||
.trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS)))
|
||||
.input(httpInputBuilder)
|
||||
.input(InputBuilders.httpInput(requestBuilder).addExtractKey("hits.total"))
|
||||
.condition(scriptCondition("ctx.payload.hits.total == 1")))
|
||||
.get();
|
||||
|
||||
|
@ -119,7 +118,7 @@ public class HttpInputIntegrationTest extends AbstractWatcherIntegrationTests {
|
|||
watcherClient.preparePutWatch("_name2")
|
||||
.source(watchSourceBuilder()
|
||||
.trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS)))
|
||||
.input(httpInputBuilder)
|
||||
.input(InputBuilders.httpInput(requestBuilder).addExtractKey("hits.total"))
|
||||
.condition(scriptCondition("ctx.payload.hits.max_score >= 0")))
|
||||
.get();
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDbTCCAlWgAwIBAgIJAJ+K5mGS3n/AMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
|
||||
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp
|
||||
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTQxMjE2MTcwNDQ1WhcNMTgxMjE1MTcwNDQ1
|
||||
WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV
|
||||
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAzhpW7iwkm+Og+HP7U00nbmh0Hy9Z2Ldp5i8tJSlSQwTxCCvO
|
||||
rse6jwJQN98Dk1ApaSzimZrlKOotFyPV1L3fnOzJbTp1Yq/VsYP4zJkjWtID0qUf
|
||||
8Rg8bLhjKAG+ZlLuai5XZqnLkdmqvQeR61VhpXWFm0Om153tWmAiHL18ywY71gXN
|
||||
EnkeFo9OW4fDqkz6h7NJziYvU6URSKErZDEixk5GIPv9K9hiIfi0KQM6xaHp0d2w
|
||||
VCyFVC0OUdugz6untURzJVx4U3X1bQcv/o2BoUotWh/5h8o5eeiiv2OGZ1XlO+33
|
||||
1tweYI4wFjDwnAyHHRr/rk2ZIBiBYGaSzHnuhQIDAQABo1owWDAJBgNVHRMEAjAA
|
||||
MB0GA1UdDgQWBBTwGg2LF8+mzsvBBWxJKv6VXv3dMTAsBgNVHREEJTAjgglsb2Nh
|
||||
bGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAIwDQYJKoZIhvcNAQELBQADggEB
|
||||
ABP4ufLToJhcUselVxV9LPD5VGPEHGLdIFqsUEix7DMsiNpR76X6a8qNQbZpdbd6
|
||||
+qPKqoaMgC7znX7qZtCqRbIXTWbudZPxFkcHdiWx3SiALMQYabeUGetClX3sCndU
|
||||
SUoV8f34i8dJxfNcqhLcsh4zpgxtmwsvs5OLMTBvm0Xo2zUFUjlmrt41pBrWEuq9
|
||||
nkObc/cr6Syiz3sy4pYVJO1/YwHaZgE/URqjVlari70DR3ES4YnIUnLQajKx2Q0/
|
||||
gXVgzjbe68KPOUGCz6GYiWq+d4tcWdHzLv1GsaqQ1MD9P21ArfrX4DpzgPDrO6MP
|
||||
9Ppq5DQGa2q4mz3kipd5RIs=
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
Loading…
Reference in New Issue