channelRef;
+ private boolean eof;
+
+ /**
+ * Create new async HTTP entity producer
+ * @param entity HTTP entity
+ * @param bufferSize buffer size
+ */
+ public HttpEntityAsyncEntityProducer(final HttpEntity entity, final int bufferSize) {
+ this.entity = Args.notNull(entity, "Http Entity");
+ this.byteBuffer = ByteBuffer.allocate(bufferSize);
+ this.chunked = entity.isChunked();
+ this.exception = new AtomicReference<>();
+ this.channelRef = new AtomicReference<>();
+ }
+
+ /**
+ * Create new async HTTP entity producer with default buffer size (8192 bytes)
+ * @param entity HTTP entity
+ */
+ public HttpEntityAsyncEntityProducer(final HttpEntity entity) {
+ this(entity, 8192);
+ }
+
+ /**
+ * Determines whether the producer can consistently produce the same content
+ * after invocation of {@link ResourceHolder#releaseResources()}.
+ */
+ @Override
+ public boolean isRepeatable() {
+ return entity.isRepeatable();
+ }
+
+ /**
+ * Returns content type of the entity, if known.
+ */
+ @Override
+ public String getContentType() {
+ return entity.getContentType();
+ }
+
+ /**
+ * Returns length of the entity, if known.
+ */
+ @Override
+ public long getContentLength() {
+ return entity.getContentLength();
+ }
+
+ /**
+ * Returns the number of bytes immediately available for output.
+ * This method can be used as a hint to control output events
+ * of the underlying I/O session.
+ *
+ * @return the number of bytes immediately available for output
+ */
+ @Override
+ public int available() {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * Returns content encoding of the entity, if known.
+ */
+ @Override
+ public String getContentEncoding() {
+ return entity.getContentEncoding();
+ }
+
+ /**
+ * Returns chunked transfer hint for this entity.
+ *
+ * The behavior of wrapping entities is implementation dependent,
+ * but should respect the primary purpose.
+ *
+ */
+ @Override
+ public boolean isChunked() {
+ return chunked;
+ }
+
+ /**
+ * Preliminary declaration of trailing headers.
+ */
+ @Override
+ public Set getTrailerNames() {
+ return entity.getTrailerNames();
+ }
+
+ /**
+ * Triggered to signal the ability of the underlying data channel
+ * to accept more data. The data producer can choose to write data
+ * immediately inside the call or asynchronously at some later point.
+ *
+ * @param channel the data channel capable to accepting more data.
+ */
+ @Override
+ public void produce(final DataStreamChannel channel) throws IOException {
+ ReadableByteChannel stream = channelRef.get();
+ if (stream == null) {
+ stream = Channels.newChannel(entity.getContent());
+ Asserts.check(channelRef.getAndSet(stream) == null, "Illegal producer state");
+ }
+ if (!eof) {
+ final int bytesRead = stream.read(byteBuffer);
+ if (bytesRead < 0) {
+ eof = true;
+ }
+ }
+ if (byteBuffer.position() > 0) {
+ byteBuffer.flip();
+ channel.write(byteBuffer);
+ byteBuffer.compact();
+ }
+ if (eof && byteBuffer.position() == 0) {
+ channel.endStream();
+ releaseResources();
+ }
+ }
+
+ /**
+ * Triggered to signal a failure in data generation.
+ *
+ * @param cause the cause of the failure.
+ */
+ @Override
+ public void failed(final Exception cause) {
+ if (exception.compareAndSet(null, cause)) {
+ releaseResources();
+ }
+ }
+
+ /**
+ * Release resources being held
+ */
+ @Override
+ public void releaseResources() {
+ eof = false;
+ final ReadableByteChannel stream = channelRef.getAndSet(null);
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (final IOException ex) {
+ /* Close quietly */
+ }
+ }
+ }
+
+}
diff --git a/client/rest/src/main/java/org/opensearch/client/nio/package-info.java b/client/rest/src/main/java/org/opensearch/client/nio/package-info.java
new file mode 100644
index 0000000000000..ce4961ed21f7c
--- /dev/null
+++ b/client/rest/src/main/java/org/opensearch/client/nio/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/**
+ * NIO support classes for REST client.
+ */
+package org.opensearch.client.nio;
diff --git a/client/rest/src/test/java/org/opensearch/client/FailureTrackingResponseListenerTests.java b/client/rest/src/test/java/org/opensearch/client/FailureTrackingResponseListenerTests.java
index 0a997a586acc9..9722ec867a376 100644
--- a/client/rest/src/test/java/org/opensearch/client/FailureTrackingResponseListenerTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/FailureTrackingResponseListenerTests.java
@@ -32,14 +32,11 @@
package org.opensearch.client;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.RequestLine;
-import org.apache.http.StatusLine;
-import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.message.BasicRequestLine;
-import org.apache.http.message.BasicStatusLine;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.message.RequestLine;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
import java.util.concurrent.atomic.AtomicReference;
@@ -116,9 +113,8 @@ public void onFailure(Exception exception) {
private static Response mockResponse() {
ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
- RequestLine requestLine = new BasicRequestLine("GET", "/", protocolVersion);
- StatusLine statusLine = new BasicStatusLine(protocolVersion, 200, "OK");
- HttpResponse httpResponse = new BasicHttpResponse(statusLine);
+ RequestLine requestLine = new RequestLine("GET", "/", protocolVersion);
+ ClassicHttpResponse httpResponse = new BasicClassicHttpResponse(200, "OK");
return new Response(requestLine, new HttpHost("localhost", 9200), httpResponse);
}
}
diff --git a/client/rest/src/test/java/org/opensearch/client/HasAttributeNodeSelectorTests.java b/client/rest/src/test/java/org/opensearch/client/HasAttributeNodeSelectorTests.java
index fd18bba6ee548..b5aca86e95d6c 100644
--- a/client/rest/src/test/java/org/opensearch/client/HasAttributeNodeSelectorTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/HasAttributeNodeSelectorTests.java
@@ -32,7 +32,7 @@
package org.opensearch.client;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node.Roles;
import java.util.ArrayList;
diff --git a/client/rest/src/test/java/org/opensearch/client/HeapBufferedAsyncResponseConsumerTests.java b/client/rest/src/test/java/org/opensearch/client/HeapBufferedAsyncResponseConsumerTests.java
index 22852fe4cb793..ed329d973eb78 100644
--- a/client/rest/src/test/java/org/opensearch/client/HeapBufferedAsyncResponseConsumerTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/HeapBufferedAsyncResponseConsumerTests.java
@@ -32,34 +32,31 @@
package org.opensearch.client;
-import org.apache.http.ContentTooLongException;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.StatusLine;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.message.BasicStatusLine;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.IOControl;
-import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
-import org.apache.http.protocol.HttpContext;
-
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentTooLongException;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.impl.BasicEntityDetails;
+import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.opensearch.client.nio.HeapBufferedAsyncResponseConsumer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
+import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
public class HeapBufferedAsyncResponseConsumerTests extends RestClientTestCase {
@@ -67,33 +64,6 @@ public class HeapBufferedAsyncResponseConsumerTests extends RestClientTestCase {
private static final int MAX_TEST_BUFFER_SIZE = 50 * 1024 * 1024;
private static final int TEST_BUFFER_LIMIT = 10 * 1024 * 1024;
- public void testResponseProcessing() throws Exception {
- ContentDecoder contentDecoder = mock(ContentDecoder.class);
- IOControl ioControl = mock(IOControl.class);
- HttpContext httpContext = mock(HttpContext.class);
-
- HeapBufferedAsyncResponseConsumer consumer = spy(new HeapBufferedAsyncResponseConsumer(TEST_BUFFER_LIMIT));
-
- ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
- StatusLine statusLine = new BasicStatusLine(protocolVersion, 200, "OK");
- HttpResponse httpResponse = new BasicHttpResponse(statusLine);
- httpResponse.setEntity(new StringEntity("test", ContentType.TEXT_PLAIN));
-
- // everything goes well
- consumer.responseReceived(httpResponse);
- consumer.consumeContent(contentDecoder, ioControl);
- consumer.responseCompleted(httpContext);
-
- verify(consumer).releaseResources();
- verify(consumer).buildResult(httpContext);
- assertTrue(consumer.isDone());
- assertSame(httpResponse, consumer.getResult());
-
- consumer.responseCompleted(httpContext);
- verify(consumer, times(1)).releaseResources();
- verify(consumer, times(1)).buildResult(httpContext);
- }
-
public void testDefaultBufferLimit() throws Exception {
HeapBufferedAsyncResponseConsumer consumer = new HeapBufferedAsyncResponseConsumer(TEST_BUFFER_LIMIT);
bufferLimitTest(consumer, TEST_BUFFER_LIMIT);
@@ -127,7 +97,7 @@ public void testCanConfigureHeapBufferLimitFromOutsidePackage() throws ClassNotF
assertThat(object, instanceOf(HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory.class));
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory =
(HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory) object;
- HttpAsyncResponseConsumer consumer = consumerFactory.createHttpAsyncResponseConsumer();
+ AsyncResponseConsumer consumer = consumerFactory.createHttpAsyncResponseConsumer();
assertThat(consumer, instanceOf(HeapBufferedAsyncResponseConsumer.class));
HeapBufferedAsyncResponseConsumer bufferedAsyncResponseConsumer = (HeapBufferedAsyncResponseConsumer) consumer;
assertEquals(bufferLimit, bufferedAsyncResponseConsumer.getBufferLimit());
@@ -138,23 +108,40 @@ public void testHttpAsyncResponseConsumerFactoryVisibility() throws ClassNotFoun
}
private static void bufferLimitTest(HeapBufferedAsyncResponseConsumer consumer, int bufferLimit) throws Exception {
- ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
- StatusLine statusLine = new BasicStatusLine(protocolVersion, 200, "OK");
- consumer.onResponseReceived(new BasicHttpResponse(statusLine));
+ HttpContext httpContext = mock(HttpContext.class);
+
+ BasicClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ consumer.consumeResponse(response, null, httpContext, null);
final AtomicReference contentLength = new AtomicReference<>();
- HttpEntity entity = new StringEntity("", ContentType.APPLICATION_JSON) {
+ HttpEntity entity = new AbstractHttpEntity(ContentType.APPLICATION_JSON, null, false) {
@Override
public long getContentLength() {
return contentLength.get();
}
+
+ @Override
+ public InputStream getContent() throws IOException, UnsupportedOperationException {
+ return new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
+ }
+
+ @Override
+ public boolean isStreaming() {
+ return false;
+ }
+
+ @Override
+ public void close() throws IOException {}
};
contentLength.set(randomLongBetween(0L, bufferLimit));
- consumer.onEntityEnclosed(entity, ContentType.APPLICATION_JSON);
+ response.setEntity(entity);
+
+ final EntityDetails details = new BasicEntityDetails(4096, ContentType.APPLICATION_JSON);
+ consumer.consumeResponse(response, details, httpContext, null);
contentLength.set(randomLongBetween(bufferLimit + 1, MAX_TEST_BUFFER_SIZE));
try {
- consumer.onEntityEnclosed(entity, ContentType.APPLICATION_JSON);
+ consumer.consumeResponse(response, details, httpContext, null);
} catch (ContentTooLongException e) {
assertEquals(
"entity content is too long [" + entity.getContentLength() + "] for the configured buffer limit [" + bufferLimit + "]",
diff --git a/client/rest/src/test/java/org/opensearch/client/HostsTrackingFailureListener.java b/client/rest/src/test/java/org/opensearch/client/HostsTrackingFailureListener.java
index 2b256e7205397..0e454c6f919f5 100644
--- a/client/rest/src/test/java/org/opensearch/client/HostsTrackingFailureListener.java
+++ b/client/rest/src/test/java/org/opensearch/client/HostsTrackingFailureListener.java
@@ -32,7 +32,7 @@
package org.opensearch.client;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import java.util.HashSet;
import java.util.List;
diff --git a/client/rest/src/test/java/org/opensearch/client/NodeSelectorTests.java b/client/rest/src/test/java/org/opensearch/client/NodeSelectorTests.java
index 65a831e59bfb0..cfc95f0281bcc 100644
--- a/client/rest/src/test/java/org/opensearch/client/NodeSelectorTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/NodeSelectorTests.java
@@ -32,7 +32,7 @@
package org.opensearch.client;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node.Roles;
import java.util.ArrayList;
diff --git a/client/rest/src/test/java/org/opensearch/client/NodeTests.java b/client/rest/src/test/java/org/opensearch/client/NodeTests.java
index 352296fa3024a..748bec5fb7de5 100644
--- a/client/rest/src/test/java/org/opensearch/client/NodeTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/NodeTests.java
@@ -32,7 +32,7 @@
package org.opensearch.client;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node.Roles;
import java.util.Arrays;
@@ -48,7 +48,9 @@
import static java.util.Collections.singletonMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.hamcrest.CoreMatchers.equalTo;
public class NodeTests extends RestClientTestCase {
public void testToString() {
@@ -161,4 +163,9 @@ public void testEqualsAndHashCode() {
)
);
}
+
+ public void testIsSearchNode() {
+ Roles searchRole = new Roles(Collections.singleton("search"));
+ assertThat(searchRole.isSearch(), equalTo(true));
+ }
}
diff --git a/client/rest/src/test/java/org/opensearch/client/PreferHasAttributeNodeSelectorTests.java b/client/rest/src/test/java/org/opensearch/client/PreferHasAttributeNodeSelectorTests.java
index 0135cde573743..7dde1b96b3b45 100644
--- a/client/rest/src/test/java/org/opensearch/client/PreferHasAttributeNodeSelectorTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/PreferHasAttributeNodeSelectorTests.java
@@ -32,7 +32,7 @@
package org.opensearch.client;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node.Roles;
import java.util.ArrayList;
diff --git a/client/rest/src/test/java/org/opensearch/client/RequestLoggerTests.java b/client/rest/src/test/java/org/opensearch/client/RequestLoggerTests.java
index 3c317db1b72d9..8dea2ad922bd6 100644
--- a/client/rest/src/test/java/org/opensearch/client/RequestLoggerTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RequestLoggerTests.java
@@ -32,27 +32,29 @@
package org.opensearch.client;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpHost;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpOptions;
-import org.apache.http.client.methods.HttpPatch;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpTrace;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.message.BasicStatusLine;
-import org.apache.http.nio.entity.NByteArrayEntity;
-import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.classic.methods.HttpDelete;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpHead;
+import org.apache.hc.client5.http.classic.methods.HttpOptions;
+import org.apache.hc.client5.http.classic.methods.HttpPatch;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.classic.methods.HttpPut;
+import org.apache.hc.client5.http.classic.methods.HttpTrace;
+import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.StatusLine;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -66,8 +68,8 @@
import static org.junit.Assert.assertThat;
public class RequestLoggerTests extends RestClientTestCase {
- public void testTraceRequest() throws IOException, URISyntaxException {
- HttpHost host = new HttpHost("localhost", 9200, randomBoolean() ? "http" : "https");
+ public void testTraceRequest() throws IOException, URISyntaxException, ParseException {
+ HttpHost host = new HttpHost(randomBoolean() ? "http" : "https", "localhost", 9200);
String expectedEndpoint = "/index/type/_api";
URI uri;
if (randomBoolean()) {
@@ -77,11 +79,10 @@ public void testTraceRequest() throws IOException, URISyntaxException {
}
HttpUriRequest request = randomHttpRequest(uri);
String expected = "curl -iX " + request.getMethod() + " '" + host + expectedEndpoint + "'";
- boolean hasBody = request instanceof HttpEntityEnclosingRequest && randomBoolean();
+ boolean hasBody = !(request instanceof HttpTrace) && randomBoolean();
String requestBody = "{ \"field\": \"value\" }";
if (hasBody) {
expected += " -d '" + requestBody + "'";
- HttpEntityEnclosingRequest enclosingRequest = (HttpEntityEnclosingRequest) request;
HttpEntity entity;
switch (randomIntBetween(0, 4)) {
case 0:
@@ -94,10 +95,10 @@ public void testTraceRequest() throws IOException, URISyntaxException {
);
break;
case 2:
- entity = new NStringEntity(requestBody, ContentType.APPLICATION_JSON);
+ entity = new StringEntity(requestBody, ContentType.APPLICATION_JSON);
break;
case 3:
- entity = new NByteArrayEntity(requestBody.getBytes(StandardCharsets.UTF_8), ContentType.APPLICATION_JSON);
+ entity = new ByteArrayEntity(requestBody.getBytes(StandardCharsets.UTF_8), ContentType.APPLICATION_JSON);
break;
case 4:
// Evil entity without a charset
@@ -106,24 +107,24 @@ public void testTraceRequest() throws IOException, URISyntaxException {
default:
throw new UnsupportedOperationException();
}
- enclosingRequest.setEntity(entity);
+ request.setEntity(entity);
}
String traceRequest = RequestLogger.buildTraceRequest(request, host);
assertThat(traceRequest, equalTo(expected));
if (hasBody) {
// check that the body is still readable as most entities are not repeatable
- String body = EntityUtils.toString(((HttpEntityEnclosingRequest) request).getEntity(), StandardCharsets.UTF_8);
+ String body = EntityUtils.toString(request.getEntity(), StandardCharsets.UTF_8);
assertThat(body, equalTo(requestBody));
}
}
- public void testTraceResponse() throws IOException {
+ public void testTraceResponse() throws IOException, ParseException {
ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
int statusCode = randomIntBetween(200, 599);
String reasonPhrase = "REASON";
- BasicStatusLine statusLine = new BasicStatusLine(protocolVersion, statusCode, reasonPhrase);
+ StatusLine statusLine = new StatusLine(protocolVersion, statusCode, reasonPhrase);
String expected = "# " + statusLine.toString();
- BasicHttpResponse httpResponse = new BasicHttpResponse(statusLine);
+ ClassicHttpResponse httpResponse = new BasicClassicHttpResponse(statusCode, reasonPhrase);
int numHeaders = randomIntBetween(0, 3);
for (int i = 0; i < numHeaders; i++) {
httpResponse.setHeader("header" + i, "value");
@@ -192,13 +193,13 @@ private static HttpUriRequest randomHttpRequest(URI uri) {
int requestType = randomIntBetween(0, 7);
switch (requestType) {
case 0:
- return new HttpGetWithEntity(uri);
+ return new HttpGet(uri);
case 1:
return new HttpPost(uri);
case 2:
return new HttpPut(uri);
case 3:
- return new HttpDeleteWithEntity(uri);
+ return new HttpDelete(uri);
case 4:
return new HttpHead(uri);
case 5:
diff --git a/client/rest/src/test/java/org/opensearch/client/RequestOptionsTests.java b/client/rest/src/test/java/org/opensearch/client/RequestOptionsTests.java
index aaa40db1442ee..a7f9a48c73393 100644
--- a/client/rest/src/test/java/org/opensearch/client/RequestOptionsTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RequestOptionsTests.java
@@ -32,8 +32,9 @@
package org.opensearch.client;
-import org.apache.http.Header;
-import org.apache.http.client.config.RequestConfig;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.util.Timeout;
import org.opensearch.client.HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory;
import java.util.ArrayList;
@@ -108,15 +109,15 @@ public void testSetRequestBuilder() {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
- int socketTimeout = 10000;
- int connectTimeout = 100;
- requestConfigBuilder.setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout);
+ Timeout responseTimeout = Timeout.ofMilliseconds(10000);
+ Timeout connectTimeout = Timeout.ofMilliseconds(100);
+ requestConfigBuilder.setResponseTimeout(responseTimeout).setConnectTimeout(connectTimeout);
RequestConfig requestConfig = requestConfigBuilder.build();
builder.setRequestConfig(requestConfig);
RequestOptions options = builder.build();
assertSame(options.getRequestConfig(), requestConfig);
- assertEquals(options.getRequestConfig().getSocketTimeout(), socketTimeout);
+ assertEquals(options.getRequestConfig().getResponseTimeout(), responseTimeout);
assertEquals(options.getRequestConfig().getConnectTimeout(), connectTimeout);
}
diff --git a/client/rest/src/test/java/org/opensearch/client/RequestTests.java b/client/rest/src/test/java/org/opensearch/client/RequestTests.java
index ba15c0d0b733c..d11982e9f9642 100644
--- a/client/rest/src/test/java/org/opensearch/client/RequestTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RequestTests.java
@@ -32,15 +32,17 @@
package org.opensearch.client;
-import org.apache.http.HttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.nio.entity.NStringEntity;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
import org.opensearch.client.HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -133,7 +135,7 @@ public void testSetJsonEntity() throws IOException {
final String json = randomAsciiLettersOfLengthBetween(1, 100);
request.setJsonEntity(json);
- assertEquals(ContentType.APPLICATION_JSON.toString(), request.getEntity().getContentType().getValue());
+ assertEquals(ContentType.APPLICATION_JSON.toString(), request.getEntity().getContentType());
ByteArrayOutputStream os = new ByteArrayOutputStream();
request.getEntity().writeTo(os);
assertEquals(json, new String(os.toByteArray(), ContentType.APPLICATION_JSON.getCharset()));
@@ -201,7 +203,10 @@ private static Request randomRequest() {
randomFrom(
new HttpEntity[] {
new StringEntity(randomAsciiAlphanumOfLength(10), ContentType.APPLICATION_JSON),
- new NStringEntity(randomAsciiAlphanumOfLength(10), ContentType.APPLICATION_JSON),
+ new InputStreamEntity(
+ new ByteArrayInputStream(randomAsciiAlphanumOfLength(10).getBytes(StandardCharsets.UTF_8)),
+ ContentType.APPLICATION_JSON
+ ),
new ByteArrayEntity(randomBytesOfLength(40), ContentType.APPLICATION_JSON) }
)
);
diff --git a/client/rest/src/test/java/org/opensearch/client/ResponseExceptionTests.java b/client/rest/src/test/java/org/opensearch/client/ResponseExceptionTests.java
index 8ecd3e1a29c99..dfbf105637962 100644
--- a/client/rest/src/test/java/org/opensearch/client/ResponseExceptionTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/ResponseExceptionTests.java
@@ -32,19 +32,17 @@
package org.opensearch.client;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.RequestLine;
-import org.apache.http.StatusLine;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.message.BasicRequestLine;
-import org.apache.http.message.BasicStatusLine;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.message.RequestLine;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -57,10 +55,9 @@
public class ResponseExceptionTests extends RestClientTestCase {
- public void testResponseException() throws IOException {
+ public void testResponseException() throws IOException, ParseException {
ProtocolVersion protocolVersion = new ProtocolVersion("http", 1, 1);
- StatusLine statusLine = new BasicStatusLine(protocolVersion, 500, "Internal Server Error");
- HttpResponse httpResponse = new BasicHttpResponse(statusLine);
+ ClassicHttpResponse httpResponse = new BasicClassicHttpResponse(500, "Internal Server Error");
String responseBody = "{\"error\":{\"root_cause\": {}}}";
boolean hasBody = getRandom().nextBoolean();
@@ -78,7 +75,7 @@ public void testResponseException() throws IOException {
httpResponse.setEntity(entity);
}
- RequestLine requestLine = new BasicRequestLine("GET", "/", protocolVersion);
+ RequestLine requestLine = new RequestLine("GET", "/", protocolVersion);
HttpHost httpHost = new HttpHost("localhost", 9200);
Response response = new Response(requestLine, httpHost, httpResponse);
ResponseException responseException = new ResponseException(response);
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientBuilderIntegTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientBuilderIntegTests.java
index 10bf9568c8798..f5e1735042e66 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientBuilderIntegTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientBuilderIntegTests.java
@@ -36,7 +36,8 @@
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer;
-import org.apache.http.HttpHost;
+
+import org.apache.hc.core5.http.HttpHost;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -117,7 +118,7 @@ public void testBuilderUsesDefaultSSLContext() throws Exception {
private RestClient buildRestClient() {
InetSocketAddress address = httpsServer.getAddress();
- return RestClient.builder(new HttpHost(address.getHostString(), address.getPort(), "https")).build();
+ return RestClient.builder(new HttpHost("https", address.getHostString(), address.getPort())).build();
}
private static SSLContext getSslContext() throws Exception {
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientBuilderTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientBuilderTests.java
index ac81cd1132a2f..7165174e688e1 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientBuilderTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientBuilderTests.java
@@ -32,11 +32,12 @@
package org.opensearch.client;
-import org.apache.http.Header;
-import org.apache.http.HttpHost;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
-import org.apache.http.message.BasicHeader;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.util.Timeout;
import java.io.IOException;
import java.util.Base64;
@@ -271,7 +272,7 @@ public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder reques
RequestConfig requestConfig = requestConfigBuilder.build();
assertEquals(RequestConfig.DEFAULT.getConnectionRequestTimeout(), requestConfig.getConnectionRequestTimeout());
// this way we get notified if the default ever changes
- assertEquals(-1, requestConfig.getConnectionRequestTimeout());
+ assertEquals(Timeout.ofMinutes(3), requestConfig.getConnectionRequestTimeout());
return requestConfigBuilder;
}
});
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientCompressionTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientCompressionTests.java
index e8b7742044f67..bf2c19b8127a1 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientCompressionTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientCompressionTests.java
@@ -11,10 +11,11 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
+
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.StringEntity;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -108,7 +109,7 @@ private static byte[] readAll(InputStream in) throws IOException {
private RestClient createClient(boolean enableCompression, boolean chunkedEnabled) {
InetSocketAddress address = httpServer.getAddress();
- return RestClient.builder(new HttpHost(address.getHostString(), address.getPort(), "http"))
+ return RestClient.builder(new HttpHost("http", address.getHostString(), address.getPort()))
.setCompressionEnabled(enableCompression)
.setChunkedEnabled(chunkedEnabled)
.build();
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientGzipCompressionTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientGzipCompressionTests.java
index 8c4d993517fee..fdcb65ff101c9 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientGzipCompressionTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientGzipCompressionTests.java
@@ -35,10 +35,11 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
+
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.StringEntity;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -126,7 +127,7 @@ private static byte[] readAll(InputStream in) throws IOException {
private RestClient createClient(boolean enableCompression) {
InetSocketAddress address = httpServer.getAddress();
- return RestClient.builder(new HttpHost(address.getHostString(), address.getPort(), "http"))
+ return RestClient.builder(new HttpHost("http", address.getHostString(), address.getPort()))
.setCompressionEnabled(enableCompression)
.build();
}
@@ -184,7 +185,7 @@ public void testCompressingClientSync() throws Exception {
public void testCompressingClientAsync() throws Exception {
InetSocketAddress address = httpServer.getAddress();
- RestClient restClient = RestClient.builder(new HttpHost(address.getHostString(), address.getPort(), "http"))
+ RestClient restClient = RestClient.builder(new HttpHost("http", address.getHostString(), address.getPort()))
.setCompressionEnabled(true)
.build();
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsIntegTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsIntegTests.java
index 277446191a36e..8c62533072c70 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsIntegTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsIntegTests.java
@@ -35,7 +35,8 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
-import org.apache.http.HttpHost;
+
+import org.apache.hc.core5.http.HttpHost;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -56,6 +57,7 @@
import static org.opensearch.client.RestClientTestUtil.getAllStatusCodes;
import static org.opensearch.client.RestClientTestUtil.randomErrorNoRetryStatusCode;
import static org.opensearch.client.RestClientTestUtil.randomOkStatusCode;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -63,7 +65,7 @@
import static org.junit.Assert.fail;
/**
- * Integration test to check interaction between {@link RestClient} and {@link org.apache.http.client.HttpClient}.
+ * Integration test to check interaction between {@link RestClient} and {@link org.apache.hc.client5.http.classic.HttpClient}.
* Works against real http servers, multiple hosts. Also tests failover by randomly shutting down hosts.
*/
public class RestClientMultipleHostsIntegTests extends RestClientTestCase {
@@ -299,7 +301,7 @@ public void testNodeSelector() throws Exception {
} catch (ConnectException e) {
// Windows isn't consistent here. Sometimes the message is even null!
if (false == System.getProperty("os.name").startsWith("Windows")) {
- assertEquals("Connection refused", e.getMessage());
+ assertThat(e.getMessage(), containsString("Connection refused"));
}
}
} else {
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsTests.java
index d88d4f4afd9b1..62574e5ed6d5a 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientMultipleHostsTests.java
@@ -33,9 +33,10 @@
package org.opensearch.client;
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
-import org.apache.http.Header;
-import org.apache.http.HttpHost;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHost;
import org.junit.After;
import java.io.IOException;
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostIntegTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostIntegTests.java
index 0500d282a506d..beee1c5ca21a0 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostIntegTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostIntegTests.java
@@ -36,30 +36,34 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
-import org.apache.http.Consts;
-import org.apache.http.Header;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.entity.ContentType;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.TargetAuthenticationStrategy;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.util.EntityUtils;
+
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
+import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
+import org.apache.hc.core5.net.URIBuilder;
import org.junit.After;
import org.junit.Before;
+import org.opensearch.client.http.HttpUriRequestProducer;
+import org.opensearch.client.nio.HeapBufferedAsyncResponseConsumer;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -86,7 +90,7 @@
import static org.junit.Assert.fail;
/**
- * Integration test to check interaction between {@link RestClient} and {@link org.apache.http.client.HttpClient}.
+ * Integration test to check interaction between {@link RestClient} and {@link org.apache.hc.client5.http.classic.HttpClient}.
* Works against a real http server, one single host.
*/
public class RestClientSingleHostIntegTests extends RestClientTestCase {
@@ -147,7 +151,7 @@ private static class ResponseHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) throws IOException {
// copy request body to response body so we can verify it was sent
StringBuilder body = new StringBuilder();
- try (InputStreamReader reader = new InputStreamReader(httpExchange.getRequestBody(), Consts.UTF_8)) {
+ try (InputStreamReader reader = new InputStreamReader(httpExchange.getRequestBody(), StandardCharsets.UTF_8)) {
char[] buffer = new char[256];
int read;
while ((read = reader.read(buffer)) != -1) {
@@ -164,7 +168,7 @@ public void handle(HttpExchange httpExchange) throws IOException {
httpExchange.sendResponseHeaders(statusCode, body.length() == 0 ? -1 : body.length());
if (body.length() > 0) {
try (OutputStream out = httpExchange.getResponseBody()) {
- out.write(body.toString().getBytes(Consts.UTF_8));
+ out.write(body.toString().getBytes(StandardCharsets.UTF_8));
}
}
httpExchange.close();
@@ -172,18 +176,20 @@ public void handle(HttpExchange httpExchange) throws IOException {
}
private RestClient createRestClient(final boolean useAuth, final boolean usePreemptiveAuth) {
- // provide the username/password for every request
- final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user", "pass"));
-
- final RestClientBuilder restClientBuilder = RestClient.builder(
- new HttpHost(httpServer.getAddress().getHostString(), httpServer.getAddress().getPort())
- ).setDefaultHeaders(defaultHeaders);
+ final HttpHost httpHost = new HttpHost(httpServer.getAddress().getHostString(), httpServer.getAddress().getPort());
+ final RestClientBuilder restClientBuilder = RestClient.builder(httpHost).setDefaultHeaders(defaultHeaders);
if (pathPrefix.length() > 0) {
restClientBuilder.setPathPrefix(pathPrefix);
}
if (useAuth) {
+ // provide the username/password for every request
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(
+ new AuthScope(httpHost, null, "Basic"),
+ new UsernamePasswordCredentials("user", "pass".toCharArray())
+ );
+
restClientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder httpClientBuilder) {
@@ -191,7 +197,7 @@ public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder h
// disable preemptive auth by ignoring any authcache
httpClientBuilder.disableAuthCaching();
// don't use the "persistent credentials strategy"
- httpClientBuilder.setTargetAuthenticationStrategy(new TargetAuthenticationStrategy());
+ httpClientBuilder.setTargetAuthenticationStrategy(DefaultAuthenticationStrategy.INSTANCE);
}
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
@@ -220,7 +226,7 @@ public void testManyAsyncRequests() throws Exception {
final List exceptions = new CopyOnWriteArrayList<>();
for (int i = 0; i < iters; i++) {
Request request = new Request("PUT", "/200");
- request.setEntity(new NStringEntity("{}", ContentType.APPLICATION_JSON));
+ request.setEntity(new StringEntity("{}", ContentType.APPLICATION_JSON));
restClient.performRequestAsync(request, new ResponseListener() {
@Override
public void onSuccess(Response response) {
@@ -271,7 +277,7 @@ public void onFailure(Exception exception) {
/**
* This test verifies some assumptions that we rely upon around the way the async http client works when reusing the same request
- * throughout multiple retries, and the use of the {@link HttpRequestBase#abort()} method.
+ * throughout multiple retries, and the use of the {@link HttpUriRequestBase#abort()} method.
* In fact the low-level REST client reuses the same request instance throughout multiple retries, and relies on the http client
* to set the future ref to the request properly so that when abort is called, the proper future gets cancelled.
*/
@@ -279,7 +285,10 @@ public void testRequestResetAndAbort() throws Exception {
try (CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create().build()) {
client.start();
HttpHost httpHost = new HttpHost(httpServer.getAddress().getHostString(), httpServer.getAddress().getPort());
- HttpGet httpGet = new HttpGet(pathPrefix + "/200");
+ HttpUriRequestBase httpGet = new HttpUriRequestBase(
+ "GET",
+ new URIBuilder().setHttpHost(httpHost).setPath(pathPrefix + "/200").build()
+ );
// calling abort before the request is sent is a no-op
httpGet.abort();
@@ -288,8 +297,11 @@ public void testRequestResetAndAbort() throws Exception {
{
httpGet.reset();
assertFalse(httpGet.isAborted());
+
+ Future future = client.execute(getRequestProducer(httpGet, httpHost), getResponseConsumer(), null);
+ httpGet.setDependency((org.apache.hc.core5.concurrent.Cancellable) future);
httpGet.abort();
- Future future = client.execute(httpHost, httpGet, null);
+
try {
future.get();
fail("expected cancellation exception");
@@ -300,8 +312,9 @@ public void testRequestResetAndAbort() throws Exception {
}
{
httpGet.reset();
- Future future = client.execute(httpHost, httpGet, null);
+ Future future = client.execute(getRequestProducer(httpGet, httpHost), getResponseConsumer(), null);
assertFalse(httpGet.isAborted());
+ httpGet.setDependency((org.apache.hc.core5.concurrent.Cancellable) future);
httpGet.abort();
assertTrue(httpGet.isAborted());
try {
@@ -315,9 +328,9 @@ public void testRequestResetAndAbort() throws Exception {
{
httpGet.reset();
assertFalse(httpGet.isAborted());
- Future future = client.execute(httpHost, httpGet, null);
+ Future future = client.execute(getRequestProducer(httpGet, httpHost), getResponseConsumer(), null);
assertFalse(httpGet.isAborted());
- assertEquals(200, future.get().getStatusLine().getStatusCode());
+ assertEquals(200, future.get().getCode());
assertFalse(future.isCancelled());
}
}
@@ -325,7 +338,7 @@ public void testRequestResetAndAbort() throws Exception {
/**
* End to end test for headers. We test it explicitly against a real http client as there are different ways
- * to set/add headers to the {@link org.apache.http.client.HttpClient}.
+ * to set/add headers to the {@link org.apache.hc.client5.http.classic.HttpClient}.
* Exercises the test http server ability to send back whatever headers it received.
*/
public void testHeaders() throws Exception {
@@ -365,7 +378,7 @@ public void testHeaders() throws Exception {
/**
* End to end test for delete with body. We test it explicitly as it is not supported
- * out of the box by {@link org.apache.http.client.HttpClient}.
+ * out of the box by {@link org.apache.hc.client5.http.classic.HttpClient}.
* Exercises the test http server ability to send back whatever body it received.
*/
public void testDeleteWithBody() throws Exception {
@@ -374,7 +387,7 @@ public void testDeleteWithBody() throws Exception {
/**
* End to end test for get with body. We test it explicitly as it is not supported
- * out of the box by {@link org.apache.http.client.HttpClient}.
+ * out of the box by {@link org.apache.hc.client5.http.classic.HttpClient}.
* Exercises the test http server ability to send back whatever body it received.
*/
public void testGetWithBody() throws Exception {
@@ -410,7 +423,7 @@ public void testEncodeParams() throws Exception {
Request request = new Request("PUT", "/200");
request.addParameter("routing", "foo bar");
Response response = RestClientSingleHostTests.performRequestSyncOrAsync(restClient, request);
- assertEquals(pathPrefix + "/200?routing=foo+bar", response.getRequestLine().getUri());
+ assertEquals(pathPrefix + "/200?routing=foo%20bar", response.getRequestLine().getUri());
}
{
Request request = new Request("PUT", "/200");
@@ -540,4 +553,13 @@ private Response bodyTest(RestClient restClient, String method, int statusCode,
return esResponse;
}
+
+ private AsyncResponseConsumer getResponseConsumer() {
+ return new HeapBufferedAsyncResponseConsumer(1024);
+ }
+
+ private HttpUriRequestProducer getRequestProducer(HttpUriRequestBase request, HttpHost host) {
+ return HttpUriRequestProducer.create(request, host);
+
+ }
}
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostTests.java
index e5ce5eb91ad5a..f46a91aa910f8 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientSingleHostTests.java
@@ -34,38 +34,42 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.http.ConnectionClosedException;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.StatusLine;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpOptions;
-import org.apache.http.client.methods.HttpPatch;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpTrace;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.concurrent.FutureCallback;
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.message.BasicStatusLine;
-import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
-import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.ConnectTimeoutException;
+import org.apache.hc.client5.http.classic.methods.HttpDelete;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpHead;
+import org.apache.hc.client5.http.classic.methods.HttpOptions;
+import org.apache.hc.client5.http.classic.methods.HttpPatch;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.classic.methods.HttpPut;
+import org.apache.hc.client5.http.classic.methods.HttpTrace;
+import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncPushConsumer;
+import org.apache.hc.core5.http.nio.AsyncRequestProducer;
+import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.net.URIBuilder;
+import org.apache.hc.core5.reactor.IOReactorStatus;
+import org.apache.hc.core5.util.TimeValue;
import org.junit.After;
import org.junit.Before;
-import org.mockito.ArgumentCaptor;
-import org.mockito.stubbing.Answer;
+import org.opensearch.client.http.HttpUriRequestProducer;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
@@ -85,6 +89,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.LongAdder;
import static java.util.Collections.singletonList;
import static org.opensearch.client.RestClientTestUtil.getAllErrorStatusCodes;
@@ -100,12 +105,6 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.nullable;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
/**
* Tests for basic functionality of {@link RestClient} against one single host: tests http requests being sent, headers,
@@ -122,10 +121,17 @@ public class RestClientSingleHostTests extends RestClientTestCase {
private CloseableHttpAsyncClient httpClient;
private HostsTrackingFailureListener failureListener;
private boolean strictDeprecationMode;
+ private LongAdder requests;
+ private AtomicReference requestProducerCapture;
@Before
public void createRestClient() {
- httpClient = mockHttpClient(exec);
+ requests = new LongAdder();
+ requestProducerCapture = new AtomicReference<>();
+ httpClient = mockHttpClient(exec, (target, requestProducer, responseConsumer, pushHandlerFactory, context, callback) -> {
+ requests.increment();
+ requestProducerCapture.set(requestProducer);
+ });
defaultHeaders = RestClientTestUtil.randomHeaders(getRandom(), "Header-default");
node = new Node(new HttpHost("localhost", 9200));
failureListener = new HostsTrackingFailureListener();
@@ -143,41 +149,78 @@ public void createRestClient() {
);
}
+ interface CloseableHttpAsyncClientListener {
+ void onExecute(
+ HttpHost target,
+ AsyncRequestProducer requestProducer,
+ AsyncResponseConsumer> responseConsumer,
+ HandlerFactory pushHandlerFactory,
+ HttpContext context,
+ FutureCallback> callback
+ );
+ }
+
@SuppressWarnings("unchecked")
- static CloseableHttpAsyncClient mockHttpClient(final ExecutorService exec) {
- CloseableHttpAsyncClient httpClient = mock(CloseableHttpAsyncClient.class);
- when(
- httpClient.execute(
- any(HttpAsyncRequestProducer.class),
- any(HttpAsyncResponseConsumer.class),
- any(HttpClientContext.class),
- nullable(FutureCallback.class)
- )
- ).thenAnswer((Answer>) invocationOnMock -> {
- final HttpAsyncRequestProducer requestProducer = (HttpAsyncRequestProducer) invocationOnMock.getArguments()[0];
- final FutureCallback futureCallback = (FutureCallback) invocationOnMock.getArguments()[3];
- // Call the callback asynchronous to better simulate how async http client works
- return exec.submit(() -> {
- if (futureCallback != null) {
- try {
- HttpResponse httpResponse = responseOrException(requestProducer);
- futureCallback.completed(httpResponse);
- } catch (Exception e) {
- futureCallback.failed(e);
+ static CloseableHttpAsyncClient mockHttpClient(final ExecutorService exec, final CloseableHttpAsyncClientListener... listeners) {
+ CloseableHttpAsyncClient httpClient = new CloseableHttpAsyncClient() {
+ @Override
+ public void close() throws IOException {}
+
+ @Override
+ public void close(CloseMode closeMode) {}
+
+ @Override
+ public void start() {}
+
+ @Override
+ public void register(String hostname, String uriPattern, Supplier supplier) {}
+
+ @Override
+ public void initiateShutdown() {}
+
+ @Override
+ public IOReactorStatus getStatus() {
+ return null;
+ }
+
+ @Override
+ protected Future doExecute(
+ HttpHost target,
+ AsyncRequestProducer requestProducer,
+ AsyncResponseConsumer responseConsumer,
+ HandlerFactory pushHandlerFactory,
+ HttpContext context,
+ FutureCallback callback
+ ) {
+ Arrays.stream(listeners)
+ .forEach(l -> l.onExecute(target, requestProducer, responseConsumer, pushHandlerFactory, context, callback));
+ // Call the callback asynchronous to better simulate how async http client works
+ return exec.submit(() -> {
+ if (callback != null) {
+ try {
+ ClassicHttpResponse httpResponse = responseOrException(requestProducer);
+ callback.completed((T) httpResponse);
+ } catch (Exception e) {
+ callback.failed(e);
+ }
+ return null;
}
- return null;
- }
- return responseOrException(requestProducer);
- });
- });
+ return (T) responseOrException(requestProducer);
+ });
+ }
+
+ @Override
+ public void awaitShutdown(TimeValue waitTime) throws InterruptedException {}
+ };
+
return httpClient;
}
- private static HttpResponse responseOrException(HttpAsyncRequestProducer requestProducer) throws Exception {
- final HttpUriRequest request = (HttpUriRequest) requestProducer.generateRequest();
- final HttpHost httpHost = requestProducer.getTarget();
+ private static ClassicHttpResponse responseOrException(AsyncRequestProducer requestProducer) throws Exception {
+ final ClassicHttpRequest request = getRequest(requestProducer);
+ final HttpHost httpHost = new HttpHost(request.getAuthority());
// return the desired status code or exception depending on the path
- switch (request.getURI().getPath()) {
+ switch (request.getRequestUri()) {
case "/soe":
throw new SocketTimeoutException(httpHost.toString());
case "/coe":
@@ -193,20 +236,17 @@ private static HttpResponse responseOrException(HttpAsyncRequestProducer request
case "/runtime":
throw new RuntimeException();
default:
- int statusCode = Integer.parseInt(request.getURI().getPath().substring(1));
- StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("http", 1, 1), statusCode, "");
+ int statusCode = Integer.parseInt(request.getRequestUri().substring(1));
- final HttpResponse httpResponse = new BasicHttpResponse(statusLine);
+ final ClassicHttpResponse httpResponse = new BasicClassicHttpResponse(statusCode, "");
// return the same body that was sent
- if (request instanceof HttpEntityEnclosingRequest) {
- HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
- if (entity != null) {
- assertTrue("the entity is not repeatable, cannot set it to the response directly", entity.isRepeatable());
- httpResponse.setEntity(entity);
- }
+ HttpEntity entity = request.getEntity();
+ if (entity != null) {
+ assertTrue("the entity is not repeatable, cannot set it to the response directly", entity.isRepeatable());
+ httpResponse.setEntity(entity);
}
// return the same headers that were sent
- httpResponse.setHeaders(request.getAllHeaders());
+ httpResponse.setHeaders(request.getHeaders());
return httpResponse;
}
}
@@ -224,26 +264,20 @@ public void shutdownExec() {
*/
@SuppressWarnings("unchecked")
public void testInternalHttpRequest() throws Exception {
- ArgumentCaptor requestArgumentCaptor = ArgumentCaptor.forClass(HttpAsyncRequestProducer.class);
int times = 0;
for (String httpMethod : getHttpMethods()) {
- HttpUriRequest expectedRequest = performRandomRequest(httpMethod);
- verify(httpClient, times(++times)).execute(
- requestArgumentCaptor.capture(),
- any(HttpAsyncResponseConsumer.class),
- any(HttpClientContext.class),
- nullable(FutureCallback.class)
- );
- HttpUriRequest actualRequest = (HttpUriRequest) requestArgumentCaptor.getValue().generateRequest();
- assertEquals(expectedRequest.getURI(), actualRequest.getURI());
- assertEquals(expectedRequest.getClass(), actualRequest.getClass());
- assertArrayEquals(expectedRequest.getAllHeaders(), actualRequest.getAllHeaders());
- if (expectedRequest instanceof HttpEntityEnclosingRequest) {
- HttpEntity expectedEntity = ((HttpEntityEnclosingRequest) expectedRequest).getEntity();
- if (expectedEntity != null) {
- HttpEntity actualEntity = ((HttpEntityEnclosingRequest) actualRequest).getEntity();
- assertEquals(EntityUtils.toString(expectedEntity), EntityUtils.toString(actualEntity));
- }
+ ClassicHttpRequest expectedRequest = performRandomRequest(httpMethod);
+ assertThat(requests.intValue(), equalTo(++times));
+
+ ClassicHttpRequest actualRequest = getRequest(requestProducerCapture.get());
+ assertEquals(expectedRequest.getRequestUri(), actualRequest.getRequestUri());
+ assertEquals(expectedRequest.getMethod(), actualRequest.getMethod());
+ assertArrayEquals(expectedRequest.getHeaders(), actualRequest.getHeaders());
+
+ HttpEntity expectedEntity = expectedRequest.getEntity();
+ if (expectedEntity != null) {
+ HttpEntity actualEntity = actualRequest.getEntity();
+ assertEquals(EntityUtils.toString(expectedEntity), EntityUtils.toString(actualEntity));
}
}
}
@@ -414,14 +448,14 @@ public void testBody() throws Exception {
}
}
}
- for (String method : Arrays.asList("HEAD", "OPTIONS", "TRACE")) {
+ for (String method : Arrays.asList("TRACE")) {
Request request = new Request(method, "/" + randomStatusCode(getRandom()));
request.setEntity(entity);
try {
performRequestSyncOrAsync(restClient, request);
fail("request should have failed");
- } catch (UnsupportedOperationException e) {
- assertThat(e.getMessage(), equalTo(method + " with body is not supported"));
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage(), equalTo(method + " requests may not include an entity."));
}
}
}
@@ -587,10 +621,10 @@ private HttpUriRequest performRandomRequest(String method) throws Exception {
HttpUriRequest expectedRequest;
switch (method) {
case "DELETE":
- expectedRequest = new HttpDeleteWithEntity(uri);
+ expectedRequest = new HttpDelete(uri);
break;
case "GET":
- expectedRequest = new HttpGetWithEntity(uri);
+ expectedRequest = new HttpGet(uri);
break;
case "HEAD":
expectedRequest = new HttpHead(uri);
@@ -614,14 +648,14 @@ private HttpUriRequest performRandomRequest(String method) throws Exception {
throw new UnsupportedOperationException("method not supported: " + method);
}
- if (expectedRequest instanceof HttpEntityEnclosingRequest && getRandom().nextBoolean()) {
+ if (getRandom().nextBoolean() && !(expectedRequest instanceof HttpTrace /* no entity */)) {
HttpEntity entity = new StringEntity(randomAsciiAlphanumOfLengthBetween(10, 100), ContentType.APPLICATION_JSON);
- ((HttpEntityEnclosingRequest) expectedRequest).setEntity(entity);
+ expectedRequest.setEntity(entity);
request.setEntity(entity);
}
final Set uniqueNames = new HashSet<>();
- if (randomBoolean()) {
+ if (randomBoolean() && !(expectedRequest instanceof HttpTrace /* no entity */)) {
Header[] headers = RestClientTestUtil.randomHeaders(getRandom(), "Header");
RequestOptions.Builder options = request.getOptions().toBuilder();
for (Header header : headers) {
@@ -698,4 +732,9 @@ private static void assertExceptionStackContainsCallingMethod(Throwable t) {
t.printStackTrace(new PrintWriter(stack));
fail("didn't find the calling method (looks like " + myMethod + ") in:\n" + stack);
}
+
+ private static ClassicHttpRequest getRequest(AsyncRequestProducer requestProducer) throws NoSuchFieldException, IllegalAccessException {
+ assertThat(requestProducer, instanceOf(HttpUriRequestProducer.class));
+ return ((HttpUriRequestProducer) requestProducer).getRequest();
+ }
}
diff --git a/client/rest/src/test/java/org/opensearch/client/RestClientTests.java b/client/rest/src/test/java/org/opensearch/client/RestClientTests.java
index ca761dcb6b9b6..dd51da3a30d8c 100644
--- a/client/rest/src/test/java/org/opensearch/client/RestClientTests.java
+++ b/client/rest/src/test/java/org/opensearch/client/RestClientTests.java
@@ -32,12 +32,13 @@
package org.opensearch.client;
-import org.apache.http.Header;
-import org.apache.http.HttpHost;
-import org.apache.http.client.AuthCache;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.auth.AuthCache;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.reactor.IOReactorStatus;
import org.opensearch.client.RestClient.NodeTuple;
import java.io.IOException;
@@ -410,10 +411,10 @@ public void testIsRunning() {
CloseableHttpAsyncClient client = mock(CloseableHttpAsyncClient.class);
RestClient restClient = new RestClient(client, new Header[] {}, nodes, null, null, null, false, false);
- when(client.isRunning()).thenReturn(true);
+ when(client.getStatus()).thenReturn(IOReactorStatus.ACTIVE);
assertTrue(restClient.isRunning());
- when(client.isRunning()).thenReturn(false);
+ when(client.getStatus()).thenReturn(IOReactorStatus.INACTIVE);
assertFalse(restClient.isRunning());
}
diff --git a/client/rest/src/test/java/org/opensearch/client/documentation/RestClientDocumentation.java b/client/rest/src/test/java/org/opensearch/client/documentation/RestClientDocumentation.java
index 066419844f048..b2807d35d230e 100644
--- a/client/rest/src/test/java/org/opensearch/client/documentation/RestClientDocumentation.java
+++ b/client/rest/src/test/java/org/opensearch/client/documentation/RestClientDocumentation.java
@@ -32,23 +32,30 @@
package org.opensearch.client.documentation;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.RequestLine;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.entity.ContentType;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
-import org.apache.http.impl.nio.reactor.IOReactorConfig;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.nio.entity.NStringEntity;
-import org.apache.http.ssl.SSLContextBuilder;
-import org.apache.http.ssl.SSLContexts;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
+import org.apache.hc.core5.function.Factory;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.RequestLine;
+import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.reactor.ssl.TlsDetails;
+import org.apache.hc.core5.ssl.SSLContextBuilder;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.Timeout;
import org.opensearch.client.Cancellable;
import org.opensearch.client.HttpAsyncResponseConsumerFactory;
import org.opensearch.client.Node;
@@ -62,6 +69,8 @@
import org.opensearch.client.RestClientBuilder.HttpClientConfigCallback;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@@ -109,12 +118,12 @@ public class RestClientDocumentation {
// end::rest-client-options-singleton
@SuppressWarnings("unused")
- public void usage() throws IOException, InterruptedException {
+ public void usage() throws IOException, InterruptedException, ParseException {
//tag::rest-client-init
RestClient restClient = RestClient.builder(
- new HttpHost("localhost", 9200, "http"),
- new HttpHost("localhost", 9201, "http")).build();
+ new HttpHost("http", "localhost", 9200),
+ new HttpHost("http", "localhost", 9201)).build();
//end::rest-client-init
//tag::rest-client-close
@@ -124,7 +133,7 @@ public void usage() throws IOException, InterruptedException {
{
//tag::rest-client-init-default-headers
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
Header[] defaultHeaders = new Header[]{new BasicHeader("header", "value")};
builder.setDefaultHeaders(defaultHeaders); // <1>
//end::rest-client-init-default-headers
@@ -132,14 +141,14 @@ public void usage() throws IOException, InterruptedException {
{
//tag::rest-client-init-node-selector
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
builder.setNodeSelector(NodeSelector.SKIP_DEDICATED_CLUSTER_MANAGERS); // <1>
//end::rest-client-init-node-selector
}
{
//tag::rest-client-init-allocation-aware-selector
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
builder.setNodeSelector(new NodeSelector() { // <1>
@Override
public void select(Iterable nodes) {
@@ -173,7 +182,7 @@ public void select(Iterable nodes) {
{
//tag::rest-client-init-failure-listener
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
builder.setFailureListener(new RestClient.FailureListener() {
@Override
public void onFailure(Node node) {
@@ -185,13 +194,13 @@ public void onFailure(Node node) {
{
//tag::rest-client-init-request-config-callback
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
builder.setRequestConfigCallback(
new RestClientBuilder.RequestConfigCallback() {
@Override
public RequestConfig.Builder customizeRequestConfig(
RequestConfig.Builder requestConfigBuilder) {
- return requestConfigBuilder.setSocketTimeout(10000); // <1>
+ return requestConfigBuilder.setResponseTimeout(Timeout.ofMilliseconds(10000)); // <1>
}
});
//end::rest-client-init-request-config-callback
@@ -199,13 +208,13 @@ public RequestConfig.Builder customizeRequestConfig(
{
//tag::rest-client-init-client-config-callback
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
builder.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setProxy(
- new HttpHost("proxy", 9000, "http")); // <1>
+ new HttpHost("http", "proxy", 9000)); // <1>
}
});
//end::rest-client-init-client-config-callback
@@ -244,7 +253,7 @@ public void onFailure(Exception exception) {
request.addParameter("pretty", "true");
//end::rest-client-parameters
//tag::rest-client-body
- request.setEntity(new NStringEntity(
+ request.setEntity(new StringEntity(
"{\"json\":\"text\"}",
ContentType.APPLICATION_JSON));
//end::rest-client-body
@@ -334,8 +343,8 @@ public void commonConfiguration() throws Exception {
public RequestConfig.Builder customizeRequestConfig(
RequestConfig.Builder requestConfigBuilder) {
return requestConfigBuilder
- .setConnectTimeout(5000)
- .setSocketTimeout(60000);
+ .setConnectTimeout(Timeout.ofMilliseconds(5000))
+ .setResponseTimeout(Timeout.ofMilliseconds(60000));
}
});
//end::rest-client-config-timeouts
@@ -343,8 +352,8 @@ public RequestConfig.Builder customizeRequestConfig(
{
//tag::rest-client-config-request-options-timeouts
RequestConfig requestConfig = RequestConfig.custom()
- .setConnectTimeout(5000)
- .setSocketTimeout(60000)
+ .setConnectTimeout(Timeout.ofMilliseconds(5000))
+ .setResponseTimeout(Timeout.ofMilliseconds(60000))
.build();
RequestOptions options = RequestOptions.DEFAULT.toBuilder()
.setRequestConfig(requestConfig)
@@ -359,7 +368,7 @@ public RequestConfig.Builder customizeRequestConfig(
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
- return httpClientBuilder.setDefaultIOReactorConfig(
+ return httpClientBuilder.setIOReactorConfig(
IOReactorConfig.custom()
.setIoThreadCount(1)
.build());
@@ -369,10 +378,9 @@ public HttpAsyncClientBuilder customizeHttpClient(
}
{
//tag::rest-client-config-basic-auth
- final CredentialsProvider credentialsProvider =
- new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY,
- new UsernamePasswordCredentials("user", "password"));
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(new HttpHost("localhost", 9200)),
+ new UsernamePasswordCredentials("user", "password".toCharArray()));
RestClientBuilder builder = RestClient.builder(
new HttpHost("localhost", 9200))
@@ -388,10 +396,10 @@ public HttpAsyncClientBuilder customizeHttpClient(
}
{
//tag::rest-client-config-disable-preemptive-auth
- final CredentialsProvider credentialsProvider =
+ final BasicCredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY,
- new UsernamePasswordCredentials("user", "password"));
+ credentialsProvider.setCredentials(new AuthScope(new HttpHost("localhost", 9200)),
+ new UsernamePasswordCredentials("user", "password".toCharArray()));
RestClientBuilder builder = RestClient.builder(
new HttpHost("localhost", 9200))
@@ -418,12 +426,27 @@ public HttpAsyncClientBuilder customizeHttpClient(
.loadTrustMaterial(truststore, null);
final SSLContext sslContext = sslBuilder.build();
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "https"))
+ new HttpHost("https", "localhost", 9200))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
- return httpClientBuilder.setSSLContext(sslContext);
+ final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
+ .setSslContext(sslContext)
+ // See https://issues.apache.org/jira/browse/HTTPCLIENT-2219
+ .setTlsDetailsFactory(new Factory() {
+ @Override
+ public TlsDetails create(final SSLEngine sslEngine) {
+ return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol());
+ }
+ })
+ .build();
+
+ final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
+ .setTlsStrategy(tlsStrategy)
+ .build();
+
+ return httpClientBuilder.setConnectionManager(connectionManager);
}
});
//end::rest-client-config-encrypted-communication
@@ -444,12 +467,27 @@ public HttpAsyncClientBuilder customizeHttpClient(
.loadTrustMaterial(trustStore, null);
final SSLContext sslContext = sslContextBuilder.build();
RestClient.builder(
- new HttpHost("localhost", 9200, "https"))
+ new HttpHost("https", "localhost", 9200))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
- return httpClientBuilder.setSSLContext(sslContext);
+ final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
+ .setSslContext(sslContext)
+ // See please https://issues.apache.org/jira/browse/HTTPCLIENT-2219
+ .setTlsDetailsFactory(new Factory() {
+ @Override
+ public TlsDetails create(final SSLEngine sslEngine) {
+ return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol());
+ }
+ })
+ .build();
+
+ final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
+ .setTlsStrategy(tlsStrategy)
+ .build();
+
+ return httpClientBuilder.setConnectionManager(connectionManager);
}
});
//end::rest-client-config-trust-ca-pem
@@ -473,12 +511,20 @@ public HttpAsyncClientBuilder customizeHttpClient(
.loadKeyMaterial(keyStore, keyStorePass.toCharArray());
final SSLContext sslContext = sslBuilder.build();
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "https"))
+ new HttpHost("https", "localhost", 9200))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
- return httpClientBuilder.setSSLContext(sslContext);
+ final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
+ .setSslContext(sslContext)
+ .build();
+
+ final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
+ .setTlsStrategy(tlsStrategy)
+ .build();
+
+ return httpClientBuilder.setConnectionManager(connectionManager);
}
});
//end::rest-client-config-mutual-tls-authentication
@@ -486,7 +532,7 @@ public HttpAsyncClientBuilder customizeHttpClient(
{
//tag::rest-client-auth-bearer-token
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
Header[] defaultHeaders =
new Header[]{new BasicHeader("Authorization",
"Bearer u6iuAxZ0RG1Kcm5jVFI4eU4tZU9aVFEwT2F3")};
@@ -502,7 +548,7 @@ public HttpAsyncClientBuilder customizeHttpClient(
(apiKeyId + ":" + apiKeySecret)
.getBytes(StandardCharsets.UTF_8));
RestClientBuilder builder = RestClient.builder(
- new HttpHost("localhost", 9200, "http"));
+ new HttpHost("http", "localhost", 9200));
Header[] defaultHeaders =
new Header[]{new BasicHeader("Authorization",
"ApiKey " + apiKeyAuth)};
diff --git a/client/sniffer/build.gradle b/client/sniffer/build.gradle
index b7cb0d87c02d9..eb3306cf2cea2 100644
--- a/client/sniffer/build.gradle
+++ b/client/sniffer/build.gradle
@@ -38,8 +38,8 @@ archivesBaseName = 'opensearch-rest-client-sniffer'
dependencies {
api project(":client:rest")
- api "org.apache.httpcomponents:httpclient:${versions.httpclient}"
- api "org.apache.httpcomponents:httpcore:${versions.httpcore}"
+ api "org.apache.httpcomponents.client5:httpclient5:${versions.httpclient5}"
+ api "org.apache.httpcomponents.core5:httpcore5:${versions.httpcore5}"
api "commons-codec:commons-codec:${versions.commonscodec}"
api "commons-logging:commons-logging:${versions.commonslogging}"
api "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
@@ -84,6 +84,7 @@ testingConventions {
}
thirdPartyAudit.ignoreMissingClasses(
+ 'org.conscrypt.Conscrypt',
//commons-logging optional dependencies
'org.apache.avalon.framework.logger.Logger',
'org.apache.log.Hierarchy',
diff --git a/client/sniffer/licenses/httpclient-4.5.13.jar.sha1 b/client/sniffer/licenses/httpclient-4.5.13.jar.sha1
deleted file mode 100644
index 3281e21595b39..0000000000000
--- a/client/sniffer/licenses/httpclient-4.5.13.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-e5f6cae5ca7ecaac1ec2827a9e2d65ae2869cada
\ No newline at end of file
diff --git a/client/sniffer/licenses/httpclient5-5.1.3.jar.sha1 b/client/sniffer/licenses/httpclient5-5.1.3.jar.sha1
new file mode 100644
index 0000000000000..b18cf050ac8df
--- /dev/null
+++ b/client/sniffer/licenses/httpclient5-5.1.3.jar.sha1
@@ -0,0 +1 @@
+13c984b7b881afcff3a7f0bb95878724a48a4b66
\ No newline at end of file
diff --git a/client/sniffer/licenses/httpcore-4.4.15.jar.sha1 b/client/sniffer/licenses/httpcore-4.4.15.jar.sha1
deleted file mode 100644
index 42a03b5d7a376..0000000000000
--- a/client/sniffer/licenses/httpcore-4.4.15.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-7f2e0c573eaa7a74bac2e89b359e1f73d92a0a1d
\ No newline at end of file
diff --git a/client/sniffer/licenses/httpcore5-5.1.4.jar.sha1 b/client/sniffer/licenses/httpcore5-5.1.4.jar.sha1
new file mode 100644
index 0000000000000..c8981fb933736
--- /dev/null
+++ b/client/sniffer/licenses/httpcore5-5.1.4.jar.sha1
@@ -0,0 +1 @@
+92538a62a4aacf96c9ea8992346a453e83da85fc
\ No newline at end of file
diff --git a/client/sniffer/src/main/java/org/opensearch/client/sniff/OpenSearchNodesSniffer.java b/client/sniffer/src/main/java/org/opensearch/client/sniff/OpenSearchNodesSniffer.java
index c1a0fcf9a8acf..e6696c1fc4039 100644
--- a/client/sniffer/src/main/java/org/opensearch/client/sniff/OpenSearchNodesSniffer.java
+++ b/client/sniffer/src/main/java/org/opensearch/client/sniff/OpenSearchNodesSniffer.java
@@ -37,8 +37,8 @@
import com.fasterxml.jackson.core.JsonToken;
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.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node;
import org.opensearch.client.Node.Roles;
import org.opensearch.client.Request;
@@ -192,12 +192,12 @@ private static Node readNode(String nodeId, JsonParser parser, Scheme scheme) th
publishAddressAsURI = URI.create(scheme + "://" + address);
host = publishAddressAsURI.getHost();
}
- publishedHost = new HttpHost(host, publishAddressAsURI.getPort(), publishAddressAsURI.getScheme());
+ publishedHost = new HttpHost(publishAddressAsURI.getScheme(), host, publishAddressAsURI.getPort());
} else if (parser.currentToken() == JsonToken.START_ARRAY && "bound_address".equals(parser.getCurrentName())) {
while (parser.nextToken() != JsonToken.END_ARRAY) {
URI boundAddressAsURI = URI.create(scheme + "://" + parser.getValueAsString());
boundHosts.add(
- new HttpHost(boundAddressAsURI.getHost(), boundAddressAsURI.getPort(), boundAddressAsURI.getScheme())
+ new HttpHost(boundAddressAsURI.getScheme(), boundAddressAsURI.getHost(), boundAddressAsURI.getPort())
);
}
} else if (parser.getCurrentToken() == JsonToken.START_OBJECT) {
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/MockNodesSniffer.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/MockNodesSniffer.java
index cbf349e534deb..9b5e89fbeb038 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/MockNodesSniffer.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/MockNodesSniffer.java
@@ -32,7 +32,7 @@
package org.opensearch.client.sniff;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node;
import java.util.Collections;
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferParseTests.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferParseTests.java
index 58b60ac13dee8..fd38eceee6224 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferParseTests.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferParseTests.java
@@ -33,10 +33,11 @@
package org.opensearch.client.sniff;
import com.fasterxml.jackson.core.JsonFactory;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.InputStreamEntity;
+
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
import org.opensearch.client.Node;
import org.opensearch.client.Node.Roles;
import org.opensearch.client.RestClientTestCase;
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferTests.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferTests.java
index 1d06e9353726d..b678fb050e8f8 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferTests.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferTests.java
@@ -40,14 +40,13 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
-import org.apache.http.Consts;
-import org.apache.http.HttpHost;
-import org.apache.http.client.methods.HttpGet;
import org.opensearch.client.Node;
import org.opensearch.client.Response;
import org.opensearch.client.ResponseException;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientTestCase;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.core5.http.HttpHost;
import org.junit.After;
import org.junit.Before;
@@ -56,6 +55,7 @@
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -181,7 +181,7 @@ public void handle(HttpExchange httpExchange) throws IOException {
String nodesInfoBody = sniffResponse.nodesInfoBody;
httpExchange.sendResponseHeaders(sniffResponse.nodesInfoResponseCode, nodesInfoBody.length());
try (OutputStream out = httpExchange.getResponseBody()) {
- out.write(nodesInfoBody.getBytes(Consts.UTF_8));
+ out.write(nodesInfoBody.getBytes(StandardCharsets.UTF_8));
return;
}
}
@@ -210,14 +210,14 @@ private static SniffResponse buildSniffResponse(OpenSearchNodesSniffer.Scheme sc
String nodeId = RandomStrings.randomAsciiOfLengthBetween(getRandom(), 5, 10);
String host = "host" + i;
int port = RandomNumbers.randomIntBetween(getRandom(), 9200, 9299);
- HttpHost publishHost = new HttpHost(host, port, scheme.toString());
+ HttpHost publishHost = new HttpHost(scheme.toString(), host, port);
Set boundHosts = new HashSet<>();
boundHosts.add(publishHost);
if (randomBoolean()) {
int bound = between(1, 5);
for (int b = 0; b < bound; b++) {
- boundHosts.add(new HttpHost(host + b, port, scheme.toString()));
+ boundHosts.add(new HttpHost(scheme.toString(), host + b, port));
}
}
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/SniffOnFailureListenerTests.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/SniffOnFailureListenerTests.java
index e4d1058282f5c..faab6babcaca6 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/SniffOnFailureListenerTests.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/SniffOnFailureListenerTests.java
@@ -32,7 +32,7 @@
package org.opensearch.client.sniff;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientTestCase;
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferBuilderTests.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferBuilderTests.java
index 25a3162e238ed..24ee540aa6364 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferBuilderTests.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferBuilderTests.java
@@ -33,7 +33,8 @@
package org.opensearch.client.sniff;
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
-import org.apache.http.HttpHost;
+
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientTestCase;
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferTests.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferTests.java
index 304243e73c078..36923281dde6b 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferTests.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/SnifferTests.java
@@ -32,12 +32,12 @@
package org.opensearch.client.sniff;
-import org.apache.http.HttpHost;
import org.opensearch.client.Node;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientTestCase;
import org.opensearch.client.sniff.Sniffer.DefaultScheduler;
import org.opensearch.client.sniff.Sniffer.Scheduler;
+import org.apache.hc.core5.http.HttpHost;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
diff --git a/client/sniffer/src/test/java/org/opensearch/client/sniff/documentation/SnifferDocumentation.java b/client/sniffer/src/test/java/org/opensearch/client/sniff/documentation/SnifferDocumentation.java
index 3b612aab80851..8f3e446d8aefb 100644
--- a/client/sniffer/src/test/java/org/opensearch/client/sniff/documentation/SnifferDocumentation.java
+++ b/client/sniffer/src/test/java/org/opensearch/client/sniff/documentation/SnifferDocumentation.java
@@ -32,7 +32,7 @@
package org.opensearch.client.sniff.documentation;
-import org.apache.http.HttpHost;
+import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.Node;
import org.opensearch.client.RestClient;
import org.opensearch.client.sniff.OpenSearchNodesSniffer;
@@ -69,7 +69,7 @@ public void usage() throws IOException {
{
//tag::sniffer-init
RestClient restClient = RestClient.builder(
- new HttpHost("localhost", 9200, "http"))
+ new HttpHost("http", "localhost", 9200))
.build();
Sniffer sniffer = Sniffer.builder(restClient).build();
//end::sniffer-init
@@ -82,7 +82,7 @@ public void usage() throws IOException {
{
//tag::sniffer-interval
RestClient restClient = RestClient.builder(
- new HttpHost("localhost", 9200, "http"))
+ new HttpHost("http", "localhost", 9200))
.build();
Sniffer sniffer = Sniffer.builder(restClient)
.setSniffIntervalMillis(60000).build();
@@ -105,7 +105,7 @@ public void usage() throws IOException {
{
//tag::sniffer-https
RestClient restClient = RestClient.builder(
- new HttpHost("localhost", 9200, "http"))
+ new HttpHost("http", "localhost", 9200))
.build();
NodesSniffer nodesSniffer = new OpenSearchNodesSniffer(
restClient,
@@ -118,7 +118,7 @@ public void usage() throws IOException {
{
//tag::sniff-request-timeout
RestClient restClient = RestClient.builder(
- new HttpHost("localhost", 9200, "http"))
+ new HttpHost("http", "localhost", 9200))
.build();
NodesSniffer nodesSniffer = new OpenSearchNodesSniffer(
restClient,
@@ -131,7 +131,7 @@ public void usage() throws IOException {
{
//tag::custom-nodes-sniffer
RestClient restClient = RestClient.builder(
- new HttpHost("localhost", 9200, "http"))
+ new HttpHost("http", "localhost", 9200))
.build();
NodesSniffer nodesSniffer = new NodesSniffer() {
@Override
diff --git a/client/test/build.gradle b/client/test/build.gradle
index 07d874cf01ea7..13e9bd6b9e34a 100644
--- a/client/test/build.gradle
+++ b/client/test/build.gradle
@@ -35,7 +35,7 @@ sourceCompatibility = JavaVersion.VERSION_11
group = "${group}.client.test"
dependencies {
- api "org.apache.httpcomponents:httpcore:${versions.httpcore}"
+ api "org.apache.httpcomponents.core5:httpcore5:${versions.httpcore5}"
api "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
api "junit:junit:${versions.junit}"
api "org.hamcrest:hamcrest:${versions.hamcrest}"
diff --git a/client/test/src/main/java/org/opensearch/client/RestClientTestCase.java b/client/test/src/main/java/org/opensearch/client/RestClientTestCase.java
index 2b3e867929e27..b4eacdbf88827 100644
--- a/client/test/src/main/java/org/opensearch/client/RestClientTestCase.java
+++ b/client/test/src/main/java/org/opensearch/client/RestClientTestCase.java
@@ -43,7 +43,8 @@
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies;
import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
-import org.apache.http.Header;
+
+import org.apache.hc.core5.http.Header;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/client/test/src/main/java/org/opensearch/client/RestClientTestUtil.java b/client/test/src/main/java/org/opensearch/client/RestClientTestUtil.java
index aeba9bde4bff4..6a01ed30e0c63 100644
--- a/client/test/src/main/java/org/opensearch/client/RestClientTestUtil.java
+++ b/client/test/src/main/java/org/opensearch/client/RestClientTestUtil.java
@@ -35,8 +35,9 @@
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
-import org.apache.http.Header;
-import org.apache.http.message.BasicHeader;
+
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.message.BasicHeader;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/distribution/README.md b/distribution/README.md
new file mode 100644
index 0000000000000..b9e948b625659
--- /dev/null
+++ b/distribution/README.md
@@ -0,0 +1,12 @@
+# Distributions
+This subproject contains the necessary tooling to build the various distributions.
+Note that some of this can only be run on the specific architecture and does not support cross-compile.
+
+The following distributions are being built:
+* Archives (`*.zip`, `*.tar`): these form the basis for all other OpenSearch distributions
+* Packages (`*.deb`, `*.rpm`): specific package formats for some Linux distributions
+* Docker images
+* Backwards compatibility tests: used internally for version compatibility testing, not for public consumption
+
+## With or Without JDK?
+For each supported platform there should be both a target bundled with a JDK and a target without a bundled JDK.
diff --git a/distribution/archives/build.gradle b/distribution/archives/build.gradle
index 1376b8d419f6e..587175eef4008 100644
--- a/distribution/archives/build.gradle
+++ b/distribution/archives/build.gradle
@@ -137,6 +137,13 @@ distribution_archives {
}
}
+ noJdkLinuxArm64Tar {
+ archiveClassifier = 'no-jdk-linux-arm64'
+ content {
+ archiveFiles(modulesFiles('linux-arm64'), 'tar', 'linux', 'arm64', false)
+ }
+ }
+
linuxTar {
archiveClassifier = 'linux-x64'
content {
@@ -151,6 +158,8 @@ distribution_archives {
}
}
+ // Should really be `no-jdk-linux-s390x` as it ships without a JDK, however it seems that the build can't handle
+ // the absence of the `linux-s390x` target.
linuxS390xTar {
archiveClassifier = 'linux-s390x'
content {
diff --git a/distribution/archives/integ-test-zip/src/test/java/org/opensearch/test/rest/WaitForRefreshAndCloseIT.java b/distribution/archives/integ-test-zip/src/test/java/org/opensearch/test/rest/WaitForRefreshAndCloseIT.java
index 37ffe32d19509..07576dacffb03 100644
--- a/distribution/archives/integ-test-zip/src/test/java/org/opensearch/test/rest/WaitForRefreshAndCloseIT.java
+++ b/distribution/archives/integ-test-zip/src/test/java/org/opensearch/test/rest/WaitForRefreshAndCloseIT.java
@@ -32,13 +32,14 @@
package org.opensearch.test.rest;
-import org.apache.http.util.EntityUtils;
import org.opensearch.action.ActionFuture;
import org.opensearch.action.support.PlainActionFuture;
import org.opensearch.client.Request;
import org.opensearch.client.Response;
import org.opensearch.client.ResponseException;
import org.opensearch.client.ResponseListener;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.junit.After;
import org.junit.Before;
@@ -145,6 +146,8 @@ public void onSuccess(Response response) {
future.onResponse(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
future.onFailure(e);
+ } catch (ParseException e) {
+ future.onFailure(e);
}
}
diff --git a/distribution/packages/build.gradle b/distribution/packages/build.gradle
index df3049d7684c4..d9db3448104c8 100644
--- a/distribution/packages/build.gradle
+++ b/distribution/packages/build.gradle
@@ -350,6 +350,10 @@ tasks.register('buildArm64Deb', Deb) {
configure(commonDebConfig(true, 'arm64'))
}
+tasks.register('buildNoJdkArm64Deb', Deb) {
+ configure(commonDebConfig(false, 'arm64'))
+}
+
tasks.register('buildDeb', Deb) {
configure(commonDebConfig(true, 'x64'))
}
@@ -387,6 +391,10 @@ tasks.register('buildArm64Rpm', Rpm) {
configure(commonRpmConfig(true, 'arm64'))
}
+tasks.register('buildNoJdkArm64Rpm', Rpm) {
+ configure(commonRpmConfig(false, 'arm64'))
+}
+
tasks.register('buildRpm', Rpm) {
configure(commonRpmConfig(true, 'x64'))
}
diff --git a/distribution/tools/upgrade-cli/licenses/jackson-databind-2.13.4.2.jar.sha1 b/distribution/tools/upgrade-cli/licenses/jackson-databind-2.13.4.2.jar.sha1
new file mode 100644
index 0000000000000..a7782e8aac18d
--- /dev/null
+++ b/distribution/tools/upgrade-cli/licenses/jackson-databind-2.13.4.2.jar.sha1
@@ -0,0 +1 @@
+325c06bdfeb628cfb80ebaaf1a26cc1eb558a585
\ No newline at end of file
diff --git a/distribution/tools/upgrade-cli/licenses/jackson-databind-2.13.4.jar.sha1 b/distribution/tools/upgrade-cli/licenses/jackson-databind-2.13.4.jar.sha1
deleted file mode 100644
index fcc6491d1f78d..0000000000000
--- a/distribution/tools/upgrade-cli/licenses/jackson-databind-2.13.4.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-98b0edfa8e4084078f10b7b356c300ded4a71491
\ No newline at end of file
diff --git a/distribution/tools/upgrade-cli/src/main/java/org/opensearch/upgrade/ValidateInputTask.java b/distribution/tools/upgrade-cli/src/main/java/org/opensearch/upgrade/ValidateInputTask.java
index f32581cd1791c..95e055cedda43 100644
--- a/distribution/tools/upgrade-cli/src/main/java/org/opensearch/upgrade/ValidateInputTask.java
+++ b/distribution/tools/upgrade-cli/src/main/java/org/opensearch/upgrade/ValidateInputTask.java
@@ -31,7 +31,7 @@ public void accept(final Tuple input) {
// check if the elasticsearch version is supported
if (taskInput.getVersion().isPresent()) {
final Version version = taskInput.getVersion().get();
- if (version.equals(LegacyESVersion.V_7_10_2) == false) {
+ if (version.equals(LegacyESVersion.fromId(7100299)) == false) {
throw new RuntimeException(
String.format(Locale.getDefault(), "The installed version %s of elasticsearch is not supported.", version)
);
diff --git a/distribution/tools/upgrade-cli/src/test/java/org/opensearch/upgrade/ValidateInputTaskTests.java b/distribution/tools/upgrade-cli/src/test/java/org/opensearch/upgrade/ValidateInputTaskTests.java
index 07cb19b132f31..195c57e5b457f 100644
--- a/distribution/tools/upgrade-cli/src/test/java/org/opensearch/upgrade/ValidateInputTaskTests.java
+++ b/distribution/tools/upgrade-cli/src/test/java/org/opensearch/upgrade/ValidateInputTaskTests.java
@@ -39,7 +39,7 @@ public void setTask() {
public void testUnsupportedEsVersion() {
TaskInput taskInput = new TaskInput(env);
- taskInput.setVersion(LegacyESVersion.V_7_10_1);
+ taskInput.setVersion(LegacyESVersion.fromId(7100199));
final RuntimeException e = expectThrows(RuntimeException.class, () -> task.accept(new Tuple<>(taskInput, terminal)));
@@ -51,7 +51,7 @@ public void testGetSummaryFields() {
taskInput.setEsConfig(PathUtils.get("es_home"));
taskInput.setCluster("some-cluster");
taskInput.setNode("some-node");
- taskInput.setVersion(LegacyESVersion.V_7_10_2);
+ taskInput.setVersion(LegacyESVersion.fromId(7100299));
taskInput.setBaseUrl("some-url");
taskInput.setPlugins(Arrays.asList("plugin-1", "plugin-2"));
diff --git a/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java b/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java
index 57865e15d523a..1ee4eff6ba055 100644
--- a/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java
+++ b/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java
@@ -124,7 +124,7 @@
import org.apache.lucene.analysis.tr.TurkishAnalyzer;
import org.apache.lucene.analysis.util.ElisionFilter;
import org.apache.lucene.util.SetOnce;
-import org.opensearch.LegacyESVersion;
+import org.opensearch.Version;
import org.opensearch.client.Client;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.service.ClusterService;
@@ -347,7 +347,12 @@ public Map> getTokenizers() {
tokenizers.put("simple_pattern_split", SimplePatternSplitTokenizerFactory::new);
tokenizers.put("thai", ThaiTokenizerFactory::new);
tokenizers.put("nGram", (IndexSettings indexSettings, Environment environment, String name, Settings settings) -> {
- if (indexSettings.getIndexVersionCreated().onOrAfter(LegacyESVersion.V_7_6_0)) {
+ if (indexSettings.getIndexVersionCreated().onOrAfter(Version.V_3_0_0)) {
+ throw new IllegalArgumentException(
+ "The [nGram] tokenizer name was deprecated pre 1.0. "
+ + "Please use the tokenizer name to [ngram] for indices created in versions 3.0 or higher instead."
+ );
+ } else {
deprecationLogger.deprecate(
"nGram_tokenizer_deprecation",
"The [nGram] tokenizer name is deprecated and will be removed in a future version. "
@@ -358,7 +363,12 @@ public Map> getTokenizers() {
});
tokenizers.put("ngram", NGramTokenizerFactory::new);
tokenizers.put("edgeNGram", (IndexSettings indexSettings, Environment environment, String name, Settings settings) -> {
- if (indexSettings.getIndexVersionCreated().onOrAfter(LegacyESVersion.V_7_6_0)) {
+ if (indexSettings.getIndexVersionCreated().onOrAfter(Version.V_3_0_0)) {
+ throw new IllegalArgumentException(
+ "The [edgeNGram] tokenizer name was deprecated pre 1.0. "
+ + "Please use the tokenizer name to [edge_ngram] for indices created in versions 3.0 or higher instead."
+ );
+ } else {
deprecationLogger.deprecate(
"edgeNGram_tokenizer_deprecation",
"The [edgeNGram] tokenizer name is deprecated and will be removed in a future version. "
@@ -485,19 +495,10 @@ public List getPreConfiguredTokenFilters() {
filters.add(PreConfiguredTokenFilter.singleton("dutch_stem", false, input -> new SnowballFilter(input, new DutchStemmer())));
filters.add(PreConfiguredTokenFilter.singleton("edge_ngram", false, false, input -> new EdgeNGramTokenFilter(input, 1)));
filters.add(PreConfiguredTokenFilter.openSearchVersion("edgeNGram", false, false, (reader, version) -> {
- if (version.onOrAfter(LegacyESVersion.V_7_0_0)) {
- throw new IllegalArgumentException(
- "The [edgeNGram] token filter name was deprecated in 6.4 and cannot be used in new indices. "
- + "Please change the filter name to [edge_ngram] instead."
- );
- } else {
- deprecationLogger.deprecate(
- "edgeNGram_deprecation",
- "The [edgeNGram] token filter name is deprecated and will be removed in a future version. "
- + "Please change the filter name to [edge_ngram] instead."
- );
- }
- return new EdgeNGramTokenFilter(reader, 1);
+ throw new IllegalArgumentException(
+ "The [edgeNGram] token filter name was deprecated in 6.4 and cannot be used in new indices. "
+ + "Please change the filter name to [edge_ngram] instead."
+ );
}));
filters.add(
PreConfiguredTokenFilter.singleton("elision", true, input -> new ElisionFilter(input, FrenchAnalyzer.DEFAULT_ARTICLES))
@@ -524,19 +525,10 @@ public List getPreConfiguredTokenFilters() {
);
filters.add(PreConfiguredTokenFilter.singleton("ngram", false, false, reader -> new NGramTokenFilter(reader, 1, 2, false)));
filters.add(PreConfiguredTokenFilter.openSearchVersion("nGram", false, false, (reader, version) -> {
- if (version.onOrAfter(LegacyESVersion.V_7_0_0)) {
- throw new IllegalArgumentException(
- "The [nGram] token filter name was deprecated in 6.4 and cannot be used in new indices. "
- + "Please change the filter name to [ngram] instead."
- );
- } else {
- deprecationLogger.deprecate(
- "nGram_deprecation",
- "The [nGram] token filter name is deprecated and will be removed in a future version. "
- + "Please change the filter name to [ngram] instead."
- );
- }
- return new NGramTokenFilter(reader, 1, 2, false);
+ throw new IllegalArgumentException(
+ "The [nGram] token filter name was deprecated in 6.4 and cannot be used in new indices. "
+ + "Please change the filter name to [ngram] instead."
+ );
}));
filters.add(PreConfiguredTokenFilter.singleton("persian_normalization", true, PersianNormalizationFilter::new));
filters.add(PreConfiguredTokenFilter.singleton("porter_stem", false, PorterStemFilter::new));
@@ -581,18 +573,22 @@ public List getPreConfiguredTokenFilters() {
)
)
);
- filters.add(PreConfiguredTokenFilter.openSearchVersion("word_delimiter_graph", false, false, (input, version) -> {
- boolean adjustOffsets = version.onOrAfter(LegacyESVersion.V_7_3_0);
- return new WordDelimiterGraphFilter(
- input,
- adjustOffsets,
- WordDelimiterIterator.DEFAULT_WORD_DELIM_TABLE,
- WordDelimiterGraphFilter.GENERATE_WORD_PARTS | WordDelimiterGraphFilter.GENERATE_NUMBER_PARTS
- | WordDelimiterGraphFilter.SPLIT_ON_CASE_CHANGE | WordDelimiterGraphFilter.SPLIT_ON_NUMERICS
- | WordDelimiterGraphFilter.STEM_ENGLISH_POSSESSIVE,
- null
- );
- }));
+ filters.add(
+ PreConfiguredTokenFilter.openSearchVersion(
+ "word_delimiter_graph",
+ false,
+ false,
+ (input, version) -> new WordDelimiterGraphFilter(
+ input,
+ true,
+ WordDelimiterIterator.DEFAULT_WORD_DELIM_TABLE,
+ WordDelimiterGraphFilter.GENERATE_WORD_PARTS | WordDelimiterGraphFilter.GENERATE_NUMBER_PARTS
+ | WordDelimiterGraphFilter.SPLIT_ON_CASE_CHANGE | WordDelimiterGraphFilter.SPLIT_ON_NUMERICS
+ | WordDelimiterGraphFilter.STEM_ENGLISH_POSSESSIVE,
+ null
+ )
+ )
+ );
return filters;
}
@@ -606,12 +602,12 @@ public List getPreConfiguredTokenizers() {
tokenizers.add(PreConfiguredTokenizer.singleton("letter", LetterTokenizer::new));
tokenizers.add(PreConfiguredTokenizer.singleton("whitespace", WhitespaceTokenizer::new));
tokenizers.add(PreConfiguredTokenizer.singleton("ngram", NGramTokenizer::new));
- tokenizers.add(PreConfiguredTokenizer.openSearchVersion("edge_ngram", (version) -> {
- if (version.onOrAfter(LegacyESVersion.V_7_3_0)) {
- return new EdgeNGramTokenizer(NGramTokenizer.DEFAULT_MIN_NGRAM_SIZE, NGramTokenizer.DEFAULT_MAX_NGRAM_SIZE);
- }
- return new EdgeNGramTokenizer(EdgeNGramTokenizer.DEFAULT_MIN_GRAM_SIZE, EdgeNGramTokenizer.DEFAULT_MAX_GRAM_SIZE);
- }));
+ tokenizers.add(
+ PreConfiguredTokenizer.openSearchVersion(
+ "edge_ngram",
+ (version) -> new EdgeNGramTokenizer(NGramTokenizer.DEFAULT_MIN_NGRAM_SIZE, NGramTokenizer.DEFAULT_MAX_NGRAM_SIZE)
+ )
+ );
tokenizers.add(PreConfiguredTokenizer.singleton("pattern", () -> new PatternTokenizer(Regex.compile("\\W+", null), -1)));
tokenizers.add(PreConfiguredTokenizer.singleton("thai", ThaiTokenizer::new));
// TODO deprecate and remove in API
@@ -620,7 +616,12 @@ public List getPreConfiguredTokenizers() {
// Temporary shim for aliases. TODO deprecate after they are moved
tokenizers.add(PreConfiguredTokenizer.openSearchVersion("nGram", (version) -> {
- if (version.onOrAfter(LegacyESVersion.V_7_6_0)) {
+ if (version.onOrAfter(Version.V_3_0_0)) {
+ throw new IllegalArgumentException(
+ "The [nGram] tokenizer name was deprecated pre 1.0. "
+ + "Please use the tokenizer name to [ngram] for indices created in versions 3.0 or higher instead."
+ );
+ } else {
deprecationLogger.deprecate(
"nGram_tokenizer_deprecation",
"The [nGram] tokenizer name is deprecated and will be removed in a future version. "
@@ -630,17 +631,19 @@ public List getPreConfiguredTokenizers() {
return new NGramTokenizer();
}));
tokenizers.add(PreConfiguredTokenizer.openSearchVersion("edgeNGram", (version) -> {
- if (version.onOrAfter(LegacyESVersion.V_7_6_0)) {
+ if (version.onOrAfter(Version.V_3_0_0)) {
+ throw new IllegalArgumentException(
+ "The [edgeNGram] tokenizer name was deprecated pre 1.0. "
+ + "Please use the tokenizer name to [edge_ngram] for indices created in versions 3.0 or higher instead."
+ );
+ } else {
deprecationLogger.deprecate(
"edgeNGram_tokenizer_deprecation",
"The [edgeNGram] tokenizer name is deprecated and will be removed in a future version. "
+ "Please change the tokenizer name to [edge_ngram] instead."
);
}
- if (version.onOrAfter(LegacyESVersion.V_7_3_0)) {
- return new EdgeNGramTokenizer(NGramTokenizer.DEFAULT_MIN_NGRAM_SIZE, NGramTokenizer.DEFAULT_MAX_NGRAM_SIZE);
- }
- return new EdgeNGramTokenizer(EdgeNGramTokenizer.DEFAULT_MIN_GRAM_SIZE, EdgeNGramTokenizer.DEFAULT_MAX_GRAM_SIZE);
+ return new EdgeNGramTokenizer(NGramTokenizer.DEFAULT_MIN_NGRAM_SIZE, NGramTokenizer.DEFAULT_MAX_NGRAM_SIZE);
}));
tokenizers.add(PreConfiguredTokenizer.singleton("PathHierarchy", PathHierarchyTokenizer::new));
diff --git a/modules/analysis-common/src/main/java/org/opensearch/analysis/common/ConcatenateGraphTokenFilterFactory.java b/modules/analysis-common/src/main/java/org/opensearch/analysis/common/ConcatenateGraphTokenFilterFactory.java
index 0d1a2b185d1d3..7c1c15ef74e30 100644
--- a/modules/analysis-common/src/main/java/org/opensearch/analysis/common/ConcatenateGraphTokenFilterFactory.java
+++ b/modules/analysis-common/src/main/java/org/opensearch/analysis/common/ConcatenateGraphTokenFilterFactory.java
@@ -11,7 +11,6 @@
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.miscellaneous.ConcatenateGraphFilter;
import org.apache.lucene.util.automaton.TooComplexToDeterminizeException;
-import org.opensearch.LegacyESVersion;
import org.opensearch.common.settings.Settings;
import org.opensearch.env.Environment;
import org.opensearch.index.IndexSettings;
@@ -24,11 +23,6 @@
* max_graph_expansions is 100 as the default value of 10_000 seems to be unnecessarily large and preserve_separator is false.
*
*