diff --git a/backends-common/opensearch/pom.xml b/backends-common/opensearch/pom.xml
index d693072e666..6ad41c82a9d 100644
--- a/backends-common/opensearch/pom.xml
+++ b/backends-common/opensearch/pom.xml
@@ -75,6 +75,16 @@
org.apache.commons
commons-configuration2
+
+ org.apache.httpcomponents.client5
+ httpclient5
+ 5.5
+
+
+ org.apache.httpcomponents.core5
+ httpcore5
+ 5.3.4
+
org.apache.logging.log4j
log4j-to-slf4j
@@ -87,12 +97,12 @@
org.opensearch.client
opensearch-java
- 2.25.0
+ 3.1.0
org.opensearch.client
opensearch-rest-client
- 2.19.2
+ 3.1.0
org.slf4j
diff --git a/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/ClientProvider.java b/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/ClientProvider.java
index bc87d19f36d..aca9f95ec42 100644
--- a/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/ClientProvider.java
+++ b/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/ClientProvider.java
@@ -35,16 +35,21 @@
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.time.DurationFormatUtils;
-import org.apache.http.HttpHost;
-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.conn.ssl.DefaultHostnameVerifier;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
-import org.apache.http.ssl.SSLContextBuilder;
-import org.apache.http.ssl.TrustStrategy;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.CredentialsStore;
+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.client5.http.ssl.DefaultHostnameVerifier;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+import org.apache.hc.core5.ssl.SSLContextBuilder;
+import org.apache.hc.core5.ssl.TrustStrategy;
+import org.apache.hc.core5.util.Timeout;
import org.apache.james.util.concurrent.NamedThreadFactory;
import org.opensearch.client.RestClient;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
@@ -60,7 +65,7 @@
public class ClientProvider implements Provider {
private static class HttpAsyncClientConfigurer {
-
+ private static final AuthScope ANY = new AuthScope(null, null, -1, null, null);
private static final TrustStrategy TRUST_ALL = (x509Certificates, authType) -> true;
private static final HostnameVerifier ACCEPT_ANY_HOSTNAME = (hostname, sslSession) -> true;
@@ -75,9 +80,6 @@ private HttpAsyncClientBuilder configure(HttpAsyncClientBuilder builder) {
configureHostScheme(builder);
configureTimeout(builder);
- configuration.getMaxConnections().ifPresent(builder::setMaxConnTotal);
- configuration.getMaxConnectionsPerHost().ifPresent(builder::setMaxConnPerRoute);
-
builder.setThreadFactory(NamedThreadFactory.withName("OpenSearch-driver"));
return builder;
@@ -99,19 +101,35 @@ private void configureHostScheme(HttpAsyncClientBuilder builder) {
}
private void configureSSLOptions(HttpAsyncClientBuilder builder) {
- try {
- builder
- .setSSLContext(sslContext())
- .setSSLHostnameVerifier(hostnameVerifier());
- } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | IOException e) {
- throw new RuntimeException("Cannot set SSL options to the builder", e);
- }
+ builder.setConnectionManager(connectionManager());
}
private void configureTimeout(HttpAsyncClientBuilder builder) {
builder.setDefaultRequestConfig(requestConfig());
}
+ private PoolingAsyncClientConnectionManager connectionManager() {
+ PoolingAsyncClientConnectionManagerBuilder builder = PoolingAsyncClientConnectionManagerBuilder
+ .create()
+ .setTlsStrategy(tlsStrategy());
+
+ configuration.getMaxConnections().ifPresent(builder::setMaxConnTotal);
+ configuration.getMaxConnectionsPerHost().ifPresent(builder::setMaxConnPerRoute);
+
+ return builder.build();
+ }
+
+ private TlsStrategy tlsStrategy() {
+ try {
+ return ClientTlsStrategyBuilder.create()
+ .setSslContext(sslContext())
+ .setHostnameVerifier(hostnameVerifier())
+ .buildAsync();
+ } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | IOException e) {
+ throw new RuntimeException("Cannot set SSL options to the builder", e);
+ }
+ }
+
private SSLContext sslContext() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException,
CertificateException, IOException {
@@ -152,9 +170,9 @@ private HostnameVerifier hostnameVerifier() {
private RequestConfig requestConfig() {
return RequestConfig.custom()
- .setConnectTimeout(Math.toIntExact(configuration.getRequestTimeout().toMillis()))
- .setConnectionRequestTimeout(Math.toIntExact(configuration.getRequestTimeout().toMillis()))
- .setSocketTimeout(Math.toIntExact(configuration.getRequestTimeout().toMillis()))
+ .setConnectTimeout(Timeout.of(configuration.getRequestTimeout()))
+ .setConnectionRequestTimeout(Timeout.of(configuration.getRequestTimeout()))
+ .setResponseTimeout(Timeout.of(configuration.getRequestTimeout()))
.build();
}
@@ -172,9 +190,9 @@ private SSLContextBuilder applyTrustStore(SSLContextBuilder sslContextBuilder) t
private void configureAuthentication(HttpAsyncClientBuilder builder) {
configuration.getCredential()
.ifPresent(credential -> {
- CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY,
- new UsernamePasswordCredentials(credential.getUsername(), String.valueOf(credential.getPassword())));
+ CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(ANY,
+ new UsernamePasswordCredentials(credential.getUsername(), credential.getPassword()));
builder.setDefaultCredentialsProvider(credentialsProvider);
});
}
@@ -225,7 +243,7 @@ private OpenSearchAsyncClient connectToCluster() {
private HttpHost[] hostsToHttpHosts() {
return configuration.getHosts().stream()
- .map(host -> new HttpHost(host.getHostName(), host.getPort(), configuration.getHostScheme().name()))
+ .map(host -> new HttpHost(configuration.getHostScheme().name(), host.getHostName(), host.getPort()))
.toArray(HttpHost[]::new);
}
diff --git a/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/IndexCreationFactory.java b/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/IndexCreationFactory.java
index b2864f63e14..76b3d35fcbd 100644
--- a/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/IndexCreationFactory.java
+++ b/backends-common/opensearch/src/main/java/org/apache/james/backends/opensearch/IndexCreationFactory.java
@@ -264,8 +264,8 @@ private boolean indexExists(ReactorOpenSearchClient client, IndexName indexName)
private IndexSettings generateSetting() {
return new IndexSettings.Builder()
- .numberOfShards(Integer.toString(nbShards))
- .numberOfReplicas(Integer.toString(nbReplica))
+ .numberOfShards(nbShards)
+ .numberOfReplicas(nbReplica)
.analysis(new IndexSettingsAnalysis.Builder()
.normalizer(CASE_INSENSITIVE, new Normalizer.Builder()
.custom(generateNormalizer())
diff --git a/backends-common/opensearch/src/test/java/org/apache/james/backends/opensearch/OpenSearchHealthCheckTest.java b/backends-common/opensearch/src/test/java/org/apache/james/backends/opensearch/OpenSearchHealthCheckTest.java
index 1e40074c7f1..c3c9875ad28 100644
--- a/backends-common/opensearch/src/test/java/org/apache/james/backends/opensearch/OpenSearchHealthCheckTest.java
+++ b/backends-common/opensearch/src/test/java/org/apache/james/backends/opensearch/OpenSearchHealthCheckTest.java
@@ -33,7 +33,7 @@ private static HealthResponse fakeHealthResponse(HealthStatus status) {
.clusterName("fake-cluster")
.activePrimaryShards(0)
.activeShards(0)
- .activeShardsPercentAsNumber("0")
+ .activeShardsPercentAsNumber(0)
.delayedUnassignedShards(0)
.initializingShards(0)
.numberOfDataNodes(0)
@@ -41,7 +41,7 @@ private static HealthResponse fakeHealthResponse(HealthStatus status) {
.numberOfNodes(0)
.numberOfPendingTasks(0)
.relocatingShards(0)
- .taskMaxWaitingInQueueMillis(String.valueOf(System.currentTimeMillis()))
+ .taskMaxWaitingInQueueMillis(System.currentTimeMillis())
.timedOut(false)
.unassignedShards(0)
.status(status)
diff --git a/server/testing/src/main/java/org/apache/james/util/docker/Images.java b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
index 48c4a6dc527..349677eaf25 100644
--- a/server/testing/src/main/java/org/apache/james/util/docker/Images.java
+++ b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
@@ -24,7 +24,7 @@ public interface Images {
String RABBITMQ = "rabbitmq:4.1.1-management";
String ELASTICSEARCH_2 = "elasticsearch:2.4.6";
String ELASTICSEARCH_6 = "docker.elastic.co/elasticsearch/elasticsearch:6.3.2";
- String OPENSEARCH = "opensearchproject/opensearch:2.19.2";
+ String OPENSEARCH = "opensearchproject/opensearch:3.1.0";
String TIKA = "apache/tika:3.2.0.0";
String MOCK_SMTP_SERVER = "linagora/mock-smtp-server:0.7";
String OPEN_LDAP = "osixia/openldap:1.5.0";