add builders for simple creation of RestClient and SniffingConnectionPool instances

We have quite some constructor parameters and some defaults should be applied, builders help simplifying creation of objects for users.
This commit is contained in:
javanna 2016-05-09 16:37:39 +02:00 committed by Luca Cavanna
parent e040d2fc77
commit 9569ebc262
7 changed files with 476 additions and 275 deletions

View File

@ -21,6 +21,8 @@ package org.elasticsearch.client;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpHead;
@ -29,6 +31,8 @@ import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import java.io.Closeable; import java.io.Closeable;
@ -38,7 +42,6 @@ import java.net.URISyntaxException;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -50,12 +53,7 @@ public final class RestClient implements Closeable {
private final ConnectionPool connectionPool; private final ConnectionPool connectionPool;
private final long maxRetryTimeout; private final long maxRetryTimeout;
public RestClient(CloseableHttpClient client, ConnectionPool connectionPool, long maxRetryTimeout) { private RestClient(CloseableHttpClient client, ConnectionPool connectionPool, long maxRetryTimeout) {
Objects.requireNonNull(client, "client cannot be null");
Objects.requireNonNull(connectionPool, "connectionPool cannot be null");
if (maxRetryTimeout <= 0) {
throw new IllegalArgumentException("maxRetryTimeout must be greater than 0");
}
this.client = client; this.client = client;
this.connectionPool = connectionPool; this.connectionPool = connectionPool;
this.maxRetryTimeout = maxRetryTimeout; this.maxRetryTimeout = maxRetryTimeout;
@ -192,4 +190,101 @@ public final class RestClient implements Closeable {
connectionPool.close(); connectionPool.close();
client.close(); client.close();
} }
/**
* Returns a new {@link Builder} to help with {@link RestClient} creation.
*/
public static Builder builder() {
return new Builder();
}
/**
* Rest client builder. Helps creating a new {@link RestClient}.
*/
public static final class Builder {
private static final int DEFAULT_MAX_RETRY_TIMEOUT = 10000;
private ConnectionPool connectionPool;
private CloseableHttpClient httpClient;
private int maxRetryTimeout = DEFAULT_MAX_RETRY_TIMEOUT;
private HttpHost[] hosts;
private Builder() {
}
/**
* Sets the connection pool. {@link StaticConnectionPool} will be used if not specified.
* @see ConnectionPool
*/
public Builder setConnectionPool(ConnectionPool connectionPool) {
this.connectionPool = connectionPool;
return this;
}
/**
* Sets the http client. A new default one will be created if not specified, by calling {@link #createDefaultHttpClient()}.
* @see CloseableHttpClient
*/
public Builder setHttpClient(CloseableHttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
/**
* Sets the maximum timeout to honour in case of multiple retries of the same request.
* {@link #DEFAULT_MAX_RETRY_TIMEOUT} if not specified.
* @throws IllegalArgumentException if maxRetryTimeout is not greater than 0
*/
public Builder setMaxRetryTimeout(int maxRetryTimeout) {
if (maxRetryTimeout <= 0) {
throw new IllegalArgumentException("maxRetryTimeout must be greater than 0");
}
this.maxRetryTimeout = maxRetryTimeout;
return this;
}
/**
* Sets the hosts that the client will send requests to. Mandatory if no connection pool is specified,
* as the provided hosts will be used to create the default static connection pool.
*/
public Builder setHosts(HttpHost... hosts) {
if (hosts == null || hosts.length == 0) {
throw new IllegalArgumentException("no hosts provided");
}
this.hosts = hosts;
return this;
}
/**
* Creates a new {@link RestClient} based on the provided configuration.
*/
public RestClient build() {
if (httpClient == null) {
httpClient = createDefaultHttpClient();
}
if (connectionPool == null) {
connectionPool = new StaticConnectionPool(hosts);
}
return new RestClient(httpClient, connectionPool, maxRetryTimeout);
}
/**
* Creates an http client with default settings
*
* @see CloseableHttpClient
*/
public static CloseableHttpClient createDefaultHttpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
//default settings may be too constraining
connectionManager.setDefaultMaxPerRoute(10);
connectionManager.setMaxTotal(30);
//default timeouts are all infinite
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(500).setSocketTimeout(10000)
.setConnectionRequestTimeout(500).build();
return HttpClientBuilder.create().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();
}
}
} }

View File

@ -40,7 +40,6 @@ import java.io.InputStream;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Calls nodes info api and returns a list of http hosts extracted from it. * Calls nodes info api and returns a list of http hosts extracted from it.
@ -57,12 +56,6 @@ final class Sniffer {
private final JsonFactory jsonFactory; private final JsonFactory jsonFactory;
Sniffer(CloseableHttpClient client, RequestConfig sniffRequestConfig, int sniffRequestTimeout, String scheme) { Sniffer(CloseableHttpClient client, RequestConfig sniffRequestConfig, int sniffRequestTimeout, String scheme) {
Objects.requireNonNull(client, "client cannot be null");
Objects.requireNonNull(sniffRequestConfig, "sniffRequestConfig cannot be null");
if (sniffRequestTimeout <=0) {
throw new IllegalArgumentException("sniffRequestTimeout must be greater than 0");
}
Objects.requireNonNull(scheme, "scheme cannot be null");
this.client = client; this.client = client;
this.sniffRequestConfig = sniffRequestConfig; this.sniffRequestConfig = sniffRequestConfig;
this.sniffRequestTimeout = sniffRequestTimeout; this.sniffRequestTimeout = sniffRequestTimeout;

View File

@ -24,8 +24,9 @@ import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.elasticsearch.client.ConnectionPool;
import org.elasticsearch.client.Connection; import org.elasticsearch.client.Connection;
import org.elasticsearch.client.ConnectionPool;
import org.elasticsearch.client.RestClient;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
@ -52,23 +53,8 @@ public class SniffingConnectionPool extends ConnectionPool {
private volatile List<Connection> connections; private volatile List<Connection> connections;
private final SnifferTask snifferTask; private final SnifferTask snifferTask;
//TODO do we still need the sniff request timeout? or should we just use a low connect timeout? private SniffingConnectionPool(int sniffInterval, boolean sniffOnFailure, int sniffAfterFailureDelay, CloseableHttpClient client,
public SniffingConnectionPool(int sniffInterval, boolean sniffOnFailure, int sniffAfterFailureDelay, RequestConfig sniffRequestConfig, int sniffRequestTimeout, String scheme, HttpHost... hosts) {
CloseableHttpClient client, RequestConfig sniffRequestConfig, int sniffRequestTimeout, String scheme,
HttpHost... hosts) {
if (sniffInterval <= 0) {
throw new IllegalArgumentException("sniffInterval must be greater than 0");
}
if (sniffAfterFailureDelay <= 0) {
throw new IllegalArgumentException("sniffAfterFailureDelay must be greater than 0");
}
Objects.requireNonNull(scheme, "scheme cannot be null");
if (scheme.equals("http") == false && scheme.equals("https") == false) {
throw new IllegalArgumentException("scheme must be either http or https");
}
if (hosts == null || hosts.length == 0) {
throw new IllegalArgumentException("no hosts provided");
}
this.sniffOnFailure = sniffOnFailure; this.sniffOnFailure = sniffOnFailure;
this.sniffer = new Sniffer(client, sniffRequestConfig, sniffRequestTimeout, scheme); this.sniffer = new Sniffer(client, sniffRequestConfig, sniffRequestTimeout, scheme);
this.connections = createConnections(hosts); this.connections = createConnections(hosts);
@ -188,4 +174,134 @@ public class SniffingConnectionPool extends ConnectionPool {
scheduledExecutorService.shutdownNow(); scheduledExecutorService.shutdownNow();
} }
} }
/**
* Returns a new {@link Builder} to help with {@link SniffingConnectionPool} creation.
*/
public static Builder builder() {
return new Builder();
}
/**
* Sniffing connection pool builder. Helps creating a new {@link SniffingConnectionPool}.
*/
public static final class Builder {
private int sniffInterval = 5 * 1000 * 60;
private boolean sniffOnFailure = true;
private int sniffAfterFailureDelay = 60000;
private CloseableHttpClient httpClient;
private RequestConfig sniffRequestConfig;
private int sniffRequestTimeout = 1000;
private String scheme = "http";
private HttpHost[] hosts;
private Builder() {
}
/**
* Sets the interval between consecutive ordinary sniff executions. Will be honoured when sniffOnFailure is disabled or
* when there are no failures between consecutive sniff executions.
* @throws IllegalArgumentException if sniffInterval is not greater than 0
*/
public Builder setSniffInterval(int sniffInterval) {
if (sniffInterval <= 0) {
throw new IllegalArgumentException("sniffInterval must be greater than 0");
}
this.sniffInterval = sniffInterval;
return this;
}
/**
* Enables/disables sniffing on failure. If enabled, at each failure nodes will be reloaded, and a new sniff execution will
* be scheduled after a shorter time than usual (sniffAfterFailureDelay).
*/
public Builder setSniffOnFailure(boolean sniffOnFailure) {
this.sniffOnFailure = sniffOnFailure;
return this;
}
/**
* Sets the delay of a sniff execution scheduled after a failure.
*/
public Builder setSniffAfterFailureDelay(int sniffAfterFailureDelay) {
if (sniffAfterFailureDelay <= 0) {
throw new IllegalArgumentException("sniffAfterFailureDelay must be greater than 0");
}
this.sniffAfterFailureDelay = sniffAfterFailureDelay;
return this;
}
/**
* Sets the http client. Mandatory argument. Best practice is to use the same client used
* within {@link org.elasticsearch.client.RestClient} which can be created manually or
* through {@link RestClient.Builder#createDefaultHttpClient()}.
* @see CloseableHttpClient
*/
public Builder setHttpClient(CloseableHttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
/**
* Sets the configuration to be used for each sniff request. Useful as sniff can have
* different timeouts compared to ordinary requests.
* @see RequestConfig
*/
public Builder setSniffRequestConfig(RequestConfig sniffRequestConfig) {
this.sniffRequestConfig = sniffRequestConfig;
return this;
}
/**
* Sets the sniff request timeout to be passed in as a query string parameter to elasticsearch.
* Allows to halt the request without any failure, as only the nodes that have responded
* within this timeout will be returned.
*/
public Builder setSniffRequestTimeout(int sniffRequestTimeout) {
if (sniffRequestTimeout <=0) {
throw new IllegalArgumentException("sniffRequestTimeout must be greater than 0");
}
this.sniffRequestTimeout = sniffRequestTimeout;
return this;
}
/**
* Sets the scheme to be used for sniffed nodes. This information is not returned by elasticsearch,
* default is http but should be customized if https is needed/enabled.
*/
public Builder setScheme(String scheme) {
Objects.requireNonNull(scheme, "scheme cannot be null");
if (scheme.equals("http") == false && scheme.equals("https") == false) {
throw new IllegalArgumentException("scheme must be either http or https");
}
this.scheme = scheme;
return this;
}
/**
* Sets the hosts that the client will send requests to.
*/
public Builder setHosts(HttpHost... hosts) {
this.hosts = hosts;
return this;
}
/**
* Creates the {@link SniffingConnectionPool} based on the provided configuration.
*/
public SniffingConnectionPool build() {
Objects.requireNonNull(httpClient, "httpClient cannot be null");
if (hosts == null || hosts.length == 0) {
throw new IllegalArgumentException("no hosts provided");
}
if (sniffRequestConfig == null) {
sniffRequestConfig = RequestConfig.custom().setConnectTimeout(500).setSocketTimeout(1000)
.setConnectionRequestTimeout(500).build();
}
return new SniffingConnectionPool(sniffInterval, sniffOnFailure, sniffAfterFailureDelay, httpClient, sniffRequestConfig,
sniffRequestTimeout, scheme, hosts);
}
}
} }

View File

@ -0,0 +1,102 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client;
import com.carrotsearch.randomizedtesting.generators.RandomInts;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.lucene.util.LuceneTestCase;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.logging.LogManager;
public class RestClientBuilderTests extends LuceneTestCase {
static {
LogManager.getLogManager().reset();
}
public void testBuild() throws IOException {
try {
RestClient.builder().setMaxRetryTimeout(RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0));
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "maxRetryTimeout must be greater than 0");
}
try {
RestClient.builder().setHosts((HttpHost[])null);
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
try {
RestClient.builder().setHosts();
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
RestClient.Builder builder = RestClient.builder();
if (random().nextBoolean()) {
ConnectionPool connectionPool = new ConnectionPool() {
@Override
protected List<Connection> getConnections() {
return Collections.emptyList();
}
@Override
public void onSuccess(Connection connection) {
}
@Override
public void onFailure(Connection connection) throws IOException {
}
@Override
public void close() throws IOException {
}
};
builder.setConnectionPool(connectionPool);
} else {
int numNodes = RandomInts.randomIntBetween(random(), 1, 5);
HttpHost[] hosts = new HttpHost[numNodes];
for (int i = 0; i < numNodes; i++) {
hosts[i] = new HttpHost("localhost", 9200 + i);
}
builder.setHosts(hosts);
}
if (random().nextBoolean()) {
builder.setHttpClient(HttpClientBuilder.create().build());
}
if (random().nextBoolean()) {
builder.setMaxRetryTimeout(RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE));
}
try (RestClient restClient = builder.build()) {
assertNotNull(restClient);
}
}
}

View File

@ -1,87 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client;
import com.carrotsearch.randomizedtesting.generators.RandomInts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.lucene.util.LuceneTestCase;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.logging.LogManager;
public class RestClientTests extends LuceneTestCase {
static {
LogManager.getLogManager().reset();
}
public void testConstructor() throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
ConnectionPool connectionPool = new ConnectionPool() {
@Override
protected List<Connection> getConnections() {
return Collections.emptyList();
}
@Override
public void onSuccess(Connection connection) {
}
@Override
public void onFailure(Connection connection) throws IOException {
}
@Override
public void close() throws IOException {
}
};
try {
new RestClient(null, connectionPool, RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE));
fail("transport creation should have failed");
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "client cannot be null");
}
try {
new RestClient(httpClient, null, RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE));
fail("transport creation should have failed");
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "connectionPool cannot be null");
}
try {
new RestClient(httpClient, connectionPool, RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0));
fail("transport creation should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "maxRetryTimeout must be greater than 0");
}
try(RestClient client = new RestClient(httpClient, connectionPool, RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE))) {
assertNotNull(client);
}
}
}

View File

@ -0,0 +1,138 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client.sniff;
import com.carrotsearch.randomizedtesting.generators.RandomInts;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.lucene.util.LuceneTestCase;
import java.util.Arrays;
import java.util.logging.LogManager;
public class SniffingConnectionPoolBuilderTests extends LuceneTestCase {
static {
LogManager.getLogManager().reset();
}
public void testBuild() throws Exception {
try {
SniffingConnectionPool.builder().setScheme(null);
fail("should have failed");
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "scheme cannot be null");
}
try {
SniffingConnectionPool.builder().setScheme("whatever");
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "scheme must be either http or https");
}
try {
SniffingConnectionPool.builder().setSniffInterval(RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0));
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "sniffInterval must be greater than 0");
}
try {
SniffingConnectionPool.builder().setSniffRequestTimeout(RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0));
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "sniffRequestTimeout must be greater than 0");
}
try {
SniffingConnectionPool.builder().setSniffAfterFailureDelay(RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0));
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "sniffAfterFailureDelay must be greater than 0");
}
try {
SniffingConnectionPool.builder().build();
fail("should have failed");
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "httpClient cannot be null");
}
try {
SniffingConnectionPool.builder().setHttpClient(HttpClientBuilder.create().build()).build();
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
try {
SniffingConnectionPool.builder().setHttpClient(HttpClientBuilder.create().build()).setHosts((HttpHost[])null).build();
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
try {
SniffingConnectionPool.builder().setHttpClient(HttpClientBuilder.create().build()).setHosts().build();
fail("should have failed");
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
int numNodes = RandomInts.randomIntBetween(random(), 1, 5);
HttpHost[] hosts = new HttpHost[numNodes];
for (int i = 0; i < numNodes; i++) {
hosts[i] = new HttpHost("localhost", 9200 + i);
}
try (SniffingConnectionPool connectionPool = SniffingConnectionPool.builder()
.setHttpClient(HttpClientBuilder.create().build()).setHosts(hosts).build()) {
assertNotNull(connectionPool);
}
SniffingConnectionPool.Builder builder = SniffingConnectionPool.builder()
.setHttpClient(HttpClientBuilder.create().build()).setHosts(hosts);
if (random().nextBoolean()) {
builder.setScheme(RandomPicks.randomFrom(random(), Arrays.asList("http", "https")));
}
if (random().nextBoolean()) {
builder.setSniffInterval(RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE));
}
if (random().nextBoolean()) {
builder.setSniffAfterFailureDelay(RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE));
}
if (random().nextBoolean()) {
builder.setSniffRequestTimeout(RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE));
}
if (random().nextBoolean()) {
builder.setSniffOnFailure(random().nextBoolean());
}
if (random().nextBoolean()) {
builder.setSniffRequestConfig(RequestConfig.DEFAULT);
}
try (SniffingConnectionPool connectionPool = builder.build()) {
assertNotNull(connectionPool);
}
}
}

View File

@ -1,156 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client.sniff;
import com.carrotsearch.randomizedtesting.generators.RandomInts;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.lucene.util.LuceneTestCase;
import java.util.logging.LogManager;
public class SniffingConnectionPoolTests extends LuceneTestCase {
static {
LogManager.getLogManager().reset();
}
public void testConstructor() throws Exception {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
String[] schemes = new String[]{"http", "https"};
int numNodes = RandomInts.randomIntBetween(random(), 1, 5);
HttpHost[] hosts = new HttpHost[numNodes];
for (int i = 0; i < numNodes; i++) {
hosts[i] = new HttpHost("localhost", 9200);
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "sniffInterval must be greater than 0");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "sniffAfterFailureDelay must be greater than 0");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), null, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "client cannot be null");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, null,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "sniffRequestConfig cannot be null");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0),
RandomPicks.randomFrom(random(), schemes), hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "sniffRequestTimeout must be greater than 0");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0),
null, hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "scheme cannot be null");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), Integer.MIN_VALUE, 0),
"whatever", hosts)) {
fail("pool creation should have failed " + connectionPool);
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "scheme must be either http or https");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), (HttpHost[])null)) {
fail("pool creation should have failed " + connectionPool);
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), (HttpHost) null)) {
fail("pool creation should have failed " + connectionPool);
} catch(NullPointerException e) {
assertEquals(e.getMessage(), "host cannot be null");
}
try (SniffingConnectionPool connectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes))) {
fail("pool creation should have failed " + connectionPool);
} catch(IllegalArgumentException e) {
assertEquals(e.getMessage(), "no hosts provided");
}
try (SniffingConnectionPool sniffingConnectionPool = new SniffingConnectionPool(
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), random().nextBoolean(),
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE), httpClient, RequestConfig.DEFAULT,
RandomInts.randomIntBetween(random(), 1, Integer.MAX_VALUE),
RandomPicks.randomFrom(random(), schemes), hosts)) {
assertNotNull(sniffingConnectionPool);
}
}
}