From 9569ebc262a20f629a9953f3da2724f7bc0c3841 Mon Sep 17 00:00:00 2001 From: javanna Date: Mon, 9 May 2016 16:37:39 +0200 Subject: [PATCH] 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. --- .../org/elasticsearch/client/RestClient.java | 109 +++++++++++- .../elasticsearch/client/sniff/Sniffer.java | 7 - .../client/sniff/SniffingConnectionPool.java | 152 +++++++++++++++-- .../client/RestClientBuilderTests.java | 102 ++++++++++++ .../elasticsearch/client/RestClientTests.java | 87 ---------- .../SniffingConnectionPoolBuilderTests.java | 138 ++++++++++++++++ .../sniff/SniffingConnectionPoolTests.java | 156 ------------------ 7 files changed, 476 insertions(+), 275 deletions(-) create mode 100644 client/src/test/java/org/elasticsearch/client/RestClientBuilderTests.java delete mode 100644 client/src/test/java/org/elasticsearch/client/RestClientTests.java create mode 100644 client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolBuilderTests.java delete mode 100644 client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolTests.java diff --git a/client/src/main/java/org/elasticsearch/client/RestClient.java b/client/src/main/java/org/elasticsearch/client/RestClient.java index 945934d5ffe..7fdc8e57e3a 100644 --- a/client/src/main/java/org/elasticsearch/client/RestClient.java +++ b/client/src/main/java/org/elasticsearch/client/RestClient.java @@ -21,6 +21,8 @@ package org.elasticsearch.client; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.HttpEntityEnclosingRequestBase; 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.utils.URIBuilder; 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 java.io.Closeable; @@ -38,7 +42,6 @@ import java.net.URISyntaxException; import java.util.Iterator; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -50,12 +53,7 @@ public final class RestClient implements Closeable { private final ConnectionPool connectionPool; private final long maxRetryTimeout; - public 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"); - } + private RestClient(CloseableHttpClient client, ConnectionPool connectionPool, long maxRetryTimeout) { this.client = client; this.connectionPool = connectionPool; this.maxRetryTimeout = maxRetryTimeout; @@ -192,4 +190,101 @@ public final class RestClient implements Closeable { connectionPool.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(); + } + } } diff --git a/client/src/main/java/org/elasticsearch/client/sniff/Sniffer.java b/client/src/main/java/org/elasticsearch/client/sniff/Sniffer.java index 7aa4e5f5f35..09a72fedb62 100644 --- a/client/src/main/java/org/elasticsearch/client/sniff/Sniffer.java +++ b/client/src/main/java/org/elasticsearch/client/sniff/Sniffer.java @@ -40,7 +40,6 @@ import java.io.InputStream; import java.net.URI; import java.util.ArrayList; import java.util.List; -import java.util.Objects; /** * 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; 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.sniffRequestConfig = sniffRequestConfig; this.sniffRequestTimeout = sniffRequestTimeout; diff --git a/client/src/main/java/org/elasticsearch/client/sniff/SniffingConnectionPool.java b/client/src/main/java/org/elasticsearch/client/sniff/SniffingConnectionPool.java index a2973638ad4..525645e9598 100644 --- a/client/src/main/java/org/elasticsearch/client/sniff/SniffingConnectionPool.java +++ b/client/src/main/java/org/elasticsearch/client/sniff/SniffingConnectionPool.java @@ -24,8 +24,9 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; -import org.elasticsearch.client.ConnectionPool; import org.elasticsearch.client.Connection; +import org.elasticsearch.client.ConnectionPool; +import org.elasticsearch.client.RestClient; import java.io.IOException; import java.util.Iterator; @@ -52,23 +53,8 @@ public class SniffingConnectionPool extends ConnectionPool { private volatile List connections; private final SnifferTask snifferTask; - //TODO do we still need the sniff request timeout? or should we just use a low connect timeout? - public SniffingConnectionPool(int sniffInterval, boolean sniffOnFailure, int sniffAfterFailureDelay, - 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"); - } + private SniffingConnectionPool(int sniffInterval, boolean sniffOnFailure, int sniffAfterFailureDelay, CloseableHttpClient client, + RequestConfig sniffRequestConfig, int sniffRequestTimeout, String scheme, HttpHost... hosts) { this.sniffOnFailure = sniffOnFailure; this.sniffer = new Sniffer(client, sniffRequestConfig, sniffRequestTimeout, scheme); this.connections = createConnections(hosts); @@ -188,4 +174,134 @@ public class SniffingConnectionPool extends ConnectionPool { 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); + } + } } diff --git a/client/src/test/java/org/elasticsearch/client/RestClientBuilderTests.java b/client/src/test/java/org/elasticsearch/client/RestClientBuilderTests.java new file mode 100644 index 00000000000..11008d52b19 --- /dev/null +++ b/client/src/test/java/org/elasticsearch/client/RestClientBuilderTests.java @@ -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 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); + } + } +} diff --git a/client/src/test/java/org/elasticsearch/client/RestClientTests.java b/client/src/test/java/org/elasticsearch/client/RestClientTests.java deleted file mode 100644 index 0d9930d9c9f..00000000000 --- a/client/src/test/java/org/elasticsearch/client/RestClientTests.java +++ /dev/null @@ -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 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); - } - } -} diff --git a/client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolBuilderTests.java b/client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolBuilderTests.java new file mode 100644 index 00000000000..b5b4eaa3ce1 --- /dev/null +++ b/client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolBuilderTests.java @@ -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); + } + } +} diff --git a/client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolTests.java b/client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolTests.java deleted file mode 100644 index 4e54f8074db..00000000000 --- a/client/src/test/java/org/elasticsearch/client/sniff/SniffingConnectionPoolTests.java +++ /dev/null @@ -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); - } - } -}