This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 2e87e12dbce48737c21ad29138e445ceb1b8a35b
Author: Tran Tien Duc <[email protected]>
AuthorDate: Wed Nov 13 18:20:06 2019 +0700

    JAMES-2905 One more option about HostNameVerifier
---
 .../apache/james/backends/es/ClientProvider.java   |  29 ++++-
 .../backends/es/ElasticSearchConfiguration.java    | 144 ++++++++++++++++-----
 ...iderImplConnectionAuthESIgnoreSSLCheckTest.java |   7 +-
 ...ImplConnectionAuthESOverrideTrustStoreTest.java |  10 +-
 .../es/ElasticSearchConfigurationTest.java         | 118 +++++++++++++----
 .../destination/conf/elasticsearch.properties      |   6 +
 .../destination/conf/elasticsearch.properties      |   6 +
 .../destination/conf/elasticsearch.properties      |   6 +
 .../destination/conf/elasticsearch.properties      |   6 +
 src/site/xdoc/server/config-elasticsearch.xml      |  15 +++
 10 files changed, 282 insertions(+), 65 deletions(-)

diff --git 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
index 50a51e7..1ff14cd 100644
--- 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
+++ 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
@@ -38,13 +38,15 @@ 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.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.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLTrustStore;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLValidationStrategy;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.HostNameVerifier;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLValidationStrategy;
 import org.elasticsearch.client.RestClient;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
@@ -60,7 +62,7 @@ public class ClientProvider implements 
Provider<RestHighLevelClient> {
     private static class HttpAsyncClientConfigurer {
 
         private static final TrustStrategy TRUST_ALL = (x509Certificates, 
authType) -> true;
-        private static final HostnameVerifier ACCEPT_ANY_HOST = (hostname, 
sslSession) -> true;
+        private static final HostnameVerifier ACCEPT_ANY_HOSTNAME = (hostname, 
sslSession) -> true;
 
         private final ElasticSearchConfiguration configuration;
 
@@ -94,7 +96,7 @@ public class ClientProvider implements 
Provider<RestHighLevelClient> {
             try {
                 builder
                     .setSSLContext(sslContext())
-                    .setSSLHostnameVerifier(ACCEPT_ANY_HOST);
+                    .setSSLHostnameVerifier(hostnameVerifier());
             } catch (NoSuchAlgorithmException | KeyManagementException | 
KeyStoreException | CertificateException | IOException e) {
                 throw new RuntimeException("Cannot set SSL options to the 
builder", e);
             }
@@ -105,7 +107,7 @@ public class ClientProvider implements 
Provider<RestHighLevelClient> {
 
             SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
 
-            SSLValidationStrategy strategy = 
configuration.getSslTrustConfiguration()
+            SSLValidationStrategy strategy = 
configuration.getSslConfiguration()
                 .getStrategy();
 
             switch (strategy) {
@@ -123,10 +125,25 @@ public class ClientProvider implements 
Provider<RestHighLevelClient> {
             }
         }
 
+        private HostnameVerifier hostnameVerifier() {
+            HostNameVerifier hostnameVerifier = 
configuration.getSslConfiguration()
+                .getHostNameVerifier();
+
+            switch (hostnameVerifier) {
+                case DEFAULT:
+                    return new DefaultHostnameVerifier();
+                case ACCEPT_ANY_HOSTNAME:
+                    return ACCEPT_ANY_HOSTNAME;
+                default:
+                    throw new NotImplementedException(
+                        String.format("unrecognized HostNameVerifier '%s'", 
hostnameVerifier.name()));
+            }
+        }
+
         private SSLContextBuilder applyTrustStore(SSLContextBuilder 
sslContextBuilder) throws CertificateException, NoSuchAlgorithmException,
             KeyStoreException, IOException {
 
-            SSLTrustStore trustStore = configuration.getSslTrustConfiguration()
+            SSLTrustStore trustStore = configuration.getSslConfiguration()
                 .getTrustStore()
                 .orElseThrow(() -> new IllegalStateException("SSLTrustStore 
cannot to be empty"));
 
diff --git 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
index 47681a5..16727ea 100644
--- 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
+++ 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.backends.es;
 
-import static 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLValidationStrategy.OVERRIDE;
+import static 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLValidationStrategy.OVERRIDE;
 
 import java.io.File;
 import java.nio.file.Files;
@@ -35,8 +35,9 @@ import java.util.stream.Stream;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLTrustStore;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLValidationStrategy;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.HostNameVerifier;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLValidationStrategy;
 import org.apache.james.util.Host;
 
 import com.github.steveash.guavate.Guavate;
@@ -110,7 +111,7 @@ public class ElasticSearchConfiguration {
         }
     }
 
-    public static class SSLTrustConfiguration {
+    public static class SSLConfiguration {
 
         public enum SSLValidationStrategy {
             DEFAULT,
@@ -128,6 +129,21 @@ public class ElasticSearchConfiguration {
             }
         }
 
+        public enum HostNameVerifier {
+            DEFAULT,
+            ACCEPT_ANY_HOSTNAME;
+
+            static HostNameVerifier from(String rawValue) {
+                Preconditions.checkNotNull(rawValue);
+
+                return Stream.of(values())
+                    .filter(verifier -> 
verifier.name().equalsIgnoreCase(rawValue))
+                    .findAny()
+                    .orElseThrow(() -> new 
IllegalArgumentException(String.format("invalid HostNameVerifier '%s'", 
rawValue)));
+
+            }
+        }
+
         public static class SSLTrustStore {
 
             public static SSLTrustStore of(String filePath, String password) {
@@ -174,28 +190,79 @@ public class ElasticSearchConfiguration {
             }
         }
 
-        static SSLTrustConfiguration defaultBehavior() {
-            return new SSLTrustConfiguration(SSLValidationStrategy.DEFAULT, 
Optional.empty());
+        static class Builder {
+
+            interface RequireSSLStrategyTrustStore {
+                RequireHostNameVerifier sslStrategy(SSLValidationStrategy 
strategy, Optional<SSLTrustStore> trustStore);
+
+                default RequireHostNameVerifier strategyIgnore() {
+                    return sslStrategy(SSLValidationStrategy.IGNORE, 
Optional.empty());
+                }
+
+                default RequireHostNameVerifier strategyOverride(SSLTrustStore 
trustStore) {
+                    return sslStrategy(SSLValidationStrategy.OVERRIDE, 
Optional.of(trustStore));
+                }
+
+                default RequireHostNameVerifier strategyDefault() {
+                    return sslStrategy(SSLValidationStrategy.DEFAULT, 
Optional.empty());
+                }
+            }
+
+            interface RequireHostNameVerifier {
+                ReadyToBuild hostNameVerifier(HostNameVerifier 
hostNameVerifier);
+
+                default ReadyToBuild acceptAnyHostNameVerifier() {
+                    return 
hostNameVerifier(HostNameVerifier.ACCEPT_ANY_HOSTNAME);
+                }
+
+                default ReadyToBuild defaultHostNameVerifier() {
+                    return hostNameVerifier(HostNameVerifier.DEFAULT);
+                }
+            }
+
+            static class ReadyToBuild {
+                private final SSLValidationStrategy sslValidationStrategy;
+                private final HostNameVerifier hostNameVerifier;
+                private Optional<SSLTrustStore> sslTrustStore;
+
+                private ReadyToBuild(SSLValidationStrategy 
sslValidationStrategy, HostNameVerifier hostNameVerifier, 
Optional<SSLTrustStore> sslTrustStore) {
+                    this.sslValidationStrategy = sslValidationStrategy;
+                    this.hostNameVerifier = hostNameVerifier;
+                    this.sslTrustStore = sslTrustStore;
+                }
+
+                public ReadyToBuild sslTrustStore(SSLTrustStore sslTrustStore) 
{
+                    this.sslTrustStore = Optional.of(sslTrustStore);
+                    return this;
+                }
+
+                public SSLConfiguration build() {
+                    return new SSLConfiguration(sslValidationStrategy, 
hostNameVerifier, sslTrustStore);
+                }
+            }
         }
 
-        static SSLTrustConfiguration ignore() {
-            return new SSLTrustConfiguration(SSLValidationStrategy.IGNORE, 
Optional.empty());
+        static SSLConfiguration defaultBehavior() {
+            return new SSLConfiguration(SSLValidationStrategy.DEFAULT, 
HostNameVerifier.DEFAULT, Optional.empty());
         }
 
-        static SSLTrustConfiguration override(SSLTrustStore sslTrustStore) {
-            return new SSLTrustConfiguration(OVERRIDE, 
Optional.of(sslTrustStore));
+        static Builder.RequireSSLStrategyTrustStore builder() {
+            return (strategy, trustStore) -> hostNameVerifier -> new 
Builder.ReadyToBuild(strategy, hostNameVerifier, trustStore);
         }
 
         private final SSLValidationStrategy strategy;
+        private final HostNameVerifier hostNameVerifier;
         private final Optional<SSLTrustStore> trustStore;
 
-        private SSLTrustConfiguration(SSLValidationStrategy strategy, 
Optional<SSLTrustStore> trustStore) {
+        private SSLConfiguration(SSLValidationStrategy strategy, 
HostNameVerifier hostNameVerifier, Optional<SSLTrustStore> trustStore) {
             Preconditions.checkNotNull(strategy);
             Preconditions.checkNotNull(trustStore);
+            Preconditions.checkNotNull(hostNameVerifier);
             Preconditions.checkArgument(strategy != OVERRIDE || 
trustStore.isPresent(), OVERRIDE.name() + " strategy requires trustStore to be 
present");
 
             this.strategy = strategy;
             this.trustStore = trustStore;
+            this.hostNameVerifier = hostNameVerifier;
         }
 
         public SSLValidationStrategy getStrategy() {
@@ -206,20 +273,25 @@ public class ElasticSearchConfiguration {
             return trustStore;
         }
 
+        public HostNameVerifier getHostNameVerifier() {
+            return hostNameVerifier;
+        }
+
         @Override
         public final boolean equals(Object o) {
-            if (o instanceof SSLTrustConfiguration) {
-                SSLTrustConfiguration that = (SSLTrustConfiguration) o;
+            if (o instanceof SSLConfiguration) {
+                SSLConfiguration that = (SSLConfiguration) o;
 
                 return Objects.equals(this.strategy, that.strategy)
-                    && Objects.equals(this.trustStore, that.trustStore);
+                    && Objects.equals(this.trustStore, that.trustStore)
+                    && Objects.equals(this.hostNameVerifier, 
that.hostNameVerifier);
             }
             return false;
         }
 
         @Override
         public final int hashCode() {
-            return Objects.hash(strategy, trustStore);
+            return Objects.hash(strategy, trustStore, hostNameVerifier);
         }
     }
 
@@ -234,7 +306,7 @@ public class ElasticSearchConfiguration {
         private Optional<Duration> requestTimeout;
         private Optional<HostScheme> hostScheme;
         private Optional<Credential> credential;
-        private Optional<SSLTrustConfiguration> sslTrustConfiguration;
+        private Optional<SSLConfiguration> sslTrustConfiguration;
 
         public Builder() {
             hosts = ImmutableList.builder();
@@ -302,12 +374,12 @@ public class ElasticSearchConfiguration {
             return this;
         }
 
-        public Builder sslTrustConfiguration(SSLTrustConfiguration 
sslTrustConfiguration) {
-            this.sslTrustConfiguration = Optional.of(sslTrustConfiguration);
+        public Builder sslTrustConfiguration(SSLConfiguration 
sslConfiguration) {
+            this.sslTrustConfiguration = Optional.of(sslConfiguration);
             return this;
         }
 
-        public Builder sslTrustConfiguration(Optional<SSLTrustConfiguration> 
sslTrustStore) {
+        public Builder sslTrustConfiguration(Optional<SSLConfiguration> 
sslTrustStore) {
             this.sslTrustConfiguration = sslTrustStore;
             return this;
         }
@@ -338,6 +410,7 @@ public class ElasticSearchConfiguration {
     public static final String ELASTICSEARCH_PORT = "elasticsearch.port";
     public static final String ELASTICSEARCH_HOST_SCHEME = 
"elasticsearch.hostScheme";
     public static final String ELASTICSEARCH_HTTPS_SSL_VALIDATION_STRATEGY = 
"elasticsearch.hostScheme.https.sslValidationStrategy";
+    public static final String ELASTICSEARCH_HTTPS_HOSTNAME_VERIFIER = 
"elasticsearch.hostScheme.https.hostNameVerifier";
     public static final String ELASTICSEARCH_HTTPS_TRUST_STORE_PATH = 
"elasticsearch.hostScheme.https.trustStorePath";
     public static final String ELASTICSEARCH_HTTPS_TRUST_STORE_PASSWORD = 
"elasticsearch.hostScheme.https.trustStorePassword";
     public static final String ELASTICSEARCH_USER = "elasticsearch.user";
@@ -358,7 +431,7 @@ public class ElasticSearchConfiguration {
     public static final String LOCALHOST = "127.0.0.1";
     public static final Optional<Integer> DEFAULT_PORT_AS_OPTIONAL = 
Optional.of(DEFAULT_PORT);
     public static final HostScheme DEFAULT_SCHEME = HostScheme.HTTP;
-    public static final SSLTrustConfiguration DEFAULT_SSL_TRUST_CONFIGURATION 
= SSLTrustConfiguration.defaultBehavior();
+    public static final SSLConfiguration DEFAULT_SSL_TRUST_CONFIGURATION = 
SSLConfiguration.defaultBehavior();
 
     public static final ElasticSearchConfiguration DEFAULT_CONFIGURATION = 
builder()
         .addHost(Host.from(LOCALHOST, DEFAULT_PORT))
@@ -378,10 +451,21 @@ public class ElasticSearchConfiguration {
             .build();
     }
 
-    private static Optional<SSLTrustConfiguration> 
sslTrustConfiguration(Configuration configuration) {
-        return 
Optional.ofNullable(configuration.getString(ELASTICSEARCH_HTTPS_SSL_VALIDATION_STRATEGY))
+    private static SSLConfiguration sslTrustConfiguration(Configuration 
configuration) {
+        SSLValidationStrategy sslStrategy = Optional
+            
.ofNullable(configuration.getString(ELASTICSEARCH_HTTPS_SSL_VALIDATION_STRATEGY))
             .map(SSLValidationStrategy::from)
-            .map(strategy -> new SSLTrustConfiguration(strategy, 
getSSLTrustStore(configuration)));
+            .orElse(SSLValidationStrategy.DEFAULT);
+
+        HostNameVerifier hostNameVerifier = Optional
+            
.ofNullable(configuration.getString(ELASTICSEARCH_HTTPS_HOSTNAME_VERIFIER))
+            .map(HostNameVerifier::from)
+            .orElse(HostNameVerifier.DEFAULT);
+
+        return SSLConfiguration.builder()
+            .sslStrategy(sslStrategy, getSSLTrustStore(configuration))
+            .hostNameVerifier(hostNameVerifier)
+            .build();
     }
 
     private static Optional<SSLTrustStore> getSSLTrustStore(Configuration 
configuration) {
@@ -455,10 +539,10 @@ public class ElasticSearchConfiguration {
     private final Duration requestTimeout;
     private final HostScheme hostScheme;
     private final Optional<Credential> credential;
-    private final SSLTrustConfiguration sslTrustConfiguration;
+    private final SSLConfiguration sslConfiguration;
 
     private ElasticSearchConfiguration(ImmutableList<Host> hosts, int 
nbShards, int nbReplica, int waitForActiveShards, int minDelay, int maxRetries, 
Duration requestTimeout,
-                                       HostScheme hostScheme, 
Optional<Credential> credential, SSLTrustConfiguration sslTrustConfiguration) {
+                                       HostScheme hostScheme, 
Optional<Credential> credential, SSLConfiguration sslConfiguration) {
         this.hosts = hosts;
         this.nbShards = nbShards;
         this.nbReplica = nbReplica;
@@ -468,7 +552,7 @@ public class ElasticSearchConfiguration {
         this.requestTimeout = requestTimeout;
         this.hostScheme = hostScheme;
         this.credential = credential;
-        this.sslTrustConfiguration = sslTrustConfiguration;
+        this.sslConfiguration = sslConfiguration;
     }
 
     public ImmutableList<Host> getHosts() {
@@ -507,8 +591,8 @@ public class ElasticSearchConfiguration {
         return credential;
     }
 
-    public SSLTrustConfiguration getSslTrustConfiguration() {
-        return sslTrustConfiguration;
+    public SSLConfiguration getSslConfiguration() {
+        return sslConfiguration;
     }
 
     @Override
@@ -525,7 +609,7 @@ public class ElasticSearchConfiguration {
                 && Objects.equals(this.requestTimeout, that.requestTimeout)
                 && Objects.equals(this.hostScheme, that.hostScheme)
                 && Objects.equals(this.credential, that.credential)
-                && Objects.equals(this.sslTrustConfiguration, 
that.sslTrustConfiguration);
+                && Objects.equals(this.sslConfiguration, 
that.sslConfiguration);
         }
         return false;
     }
@@ -533,6 +617,6 @@ public class ElasticSearchConfiguration {
     @Override
     public final int hashCode() {
         return Objects.hash(hosts, nbShards, nbReplica, waitForActiveShards, 
minDelay, maxRetries, requestTimeout,
-            hostScheme, credential, sslTrustConfiguration);
+            hostScheme, credential, sslConfiguration);
     }
 }
diff --git 
a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
 
b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
index 1de1996..a97c6a3 100644
--- 
a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
+++ 
b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
@@ -24,7 +24,7 @@ import static 
org.apache.james.backends.es.ElasticSearchClusterExtension.Elastic
 import java.util.Optional;
 
 import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class ClientProviderImplConnectionAuthESIgnoreSSLCheckTest implements 
ClientProviderImplConnectionContract {
@@ -39,6 +39,9 @@ class ClientProviderImplConnectionAuthESIgnoreSSLCheckTest 
implements ClientProv
         return ElasticSearchConfiguration.builder()
             
.credential(Optional.of(DockerElasticSearch.WithAuth.DEFAULT_CREDENTIAL))
             .hostScheme(Optional.of(HostScheme.HTTPS))
-            .sslTrustConfiguration(SSLTrustConfiguration.ignore());
+            .sslTrustConfiguration(SSLConfiguration.builder()
+                .strategyIgnore()
+                .acceptAnyHostNameVerifier()
+                .build());
     }
 }
diff --git 
a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
 
b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
index 5b92cf7..7493681 100644
--- 
a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
+++ 
b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
@@ -21,8 +21,8 @@ package org.apache.james.backends.es;
 
 import java.util.Optional;
 
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLTrustStore;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 public class ClientProviderImplConnectionAuthESOverrideTrustStoreTest 
implements ClientProviderImplConnectionContract {
@@ -40,7 +40,9 @@ public class 
ClientProviderImplConnectionAuthESOverrideTrustStoreTest implements
         return ElasticSearchConfiguration.builder()
             
.credential(Optional.of(DockerElasticSearch.WithAuth.DEFAULT_CREDENTIAL))
             
.hostScheme(Optional.of(ElasticSearchConfiguration.HostScheme.HTTPS))
-            .sslTrustConfiguration(SSLTrustConfiguration.override(
-                SSLTrustStore.of(TRUST_STORE_FILE_PATH, 
TRUST_STORE_PASSWORD)));
+            .sslTrustConfiguration(SSLConfiguration.builder()
+                .strategyOverride(SSLTrustStore.of(TRUST_STORE_FILE_PATH, 
TRUST_STORE_PASSWORD))
+                .acceptAnyHostNameVerifier()
+                .build());
     }
 }
\ No newline at end of file
diff --git 
a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
 
b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
index cf50942..35bf3f4 100644
--- 
a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
+++ 
b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
@@ -29,8 +29,8 @@ import 
org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.james.backends.es.ElasticSearchConfiguration.Credential;
 import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration;
-import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLTrustConfiguration.SSLTrustStore;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration;
+import 
org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
 import org.apache.james.util.Host;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -62,7 +62,7 @@ class ElasticSearchConfigurationTest {
     }
 
     @Nested
-    class SSLTrustConfigurationTest {
+    class SSLConfigurationTest {
 
         @Test
         void sslTrustStoreShouldMatchBeanContact() {
@@ -72,45 +72,112 @@ class ElasticSearchConfigurationTest {
 
         @Test
         void shouldMatchBeanContact() {
-            EqualsVerifier.forClass(SSLTrustConfiguration.class)
+            EqualsVerifier.forClass(SSLConfiguration.class)
                 .verify();
         }
 
+        @Test
+        void getSSLConfigurationShouldReturnDefaultValueWhenEmpty() throws 
Exception {
+            PropertiesConfiguration configuration = new 
PropertiesConfiguration();
+            configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+            assertThat(ElasticSearchConfiguration.fromProperties(configuration)
+                    .getSslConfiguration())
+                .isEqualTo(SSLConfiguration.defaultBehavior());
+        }
+
+        @Test
+        void getSSLConfigurationShouldReturnConfiguredValue() throws Exception 
{
+            PropertiesConfiguration configuration = new 
PropertiesConfiguration();
+            configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+            String trustStorePath = "src/test/resources/auth-es/server.jks";
+            String trustStorePassword = "secret";
+
+            
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "override");
+            
configuration.addProperty("elasticsearch.hostScheme.https.trustStorePath", 
trustStorePath);
+            
configuration.addProperty("elasticsearch.hostScheme.https.trustStorePassword", 
trustStorePassword);
+            
configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", 
"default");
+
+            assertThat(ElasticSearchConfiguration.fromProperties(configuration)
+                    .getSslConfiguration())
+                .isEqualTo(SSLConfiguration.builder()
+                    .strategyOverride(SSLTrustStore.of(trustStorePath, 
trustStorePassword))
+                    .defaultHostNameVerifier()
+                    .build());
+        }
+
         @Nested
         class WithSSLValidationStrategy {
 
             @Test
-            void getSSLConfigurationShouldReturnDefaultValueWhenEmpty() throws 
Exception {
+            void getSSLConfigurationShouldAcceptCaseInsensitiveStrategy() 
throws Exception {
                 PropertiesConfiguration configuration = new 
PropertiesConfiguration();
                 configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
+                
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "DEfault");
+
                 
assertThat(ElasticSearchConfiguration.fromProperties(configuration)
-                        .getSslTrustConfiguration())
-                    .isEqualTo(SSLTrustConfiguration.defaultBehavior());
+                        .getSslConfiguration())
+                    .isEqualTo(SSLConfiguration.defaultBehavior());
             }
 
             @Test
-            void getSSLConfigurationShouldAcceptCaseInsensitiveStrategy() 
throws Exception {
+            void fromPropertiesShouldThrowWhenInvalidStrategy() throws 
Exception {
                 PropertiesConfiguration configuration = new 
PropertiesConfiguration();
                 configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
-                
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "DEfault");
+                
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "invalid");
+
+                assertThatThrownBy(() -> 
ElasticSearchConfiguration.fromProperties(configuration))
+                    .isInstanceOf(IllegalArgumentException.class)
+                    .hasMessage("invalid strategy 'invalid'");
+            }
+        }
+
+        @Nested
+        class WithHostNameVerifier {
+
+            @Test
+            void getSSLConfigurationShouldReturnConfiguredValue() throws 
Exception {
+                PropertiesConfiguration configuration = new 
PropertiesConfiguration();
+                configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+                
configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", 
"DEFAULT");
 
                 
assertThat(ElasticSearchConfiguration.fromProperties(configuration)
-                        .getSslTrustConfiguration())
-                    .isEqualTo(SSLTrustConfiguration.defaultBehavior());
+                        .getSslConfiguration())
+                    .isEqualTo(SSLConfiguration.builder()
+                        .strategyDefault()
+                        .defaultHostNameVerifier()
+                        .build());
             }
 
             @Test
-            void fromPropertiesShouldThrowWhenInvalidStrategy() throws 
Exception {
+            void getSSLConfigurationShouldAcceptCaseInsensitiveVerifier() 
throws Exception {
                 PropertiesConfiguration configuration = new 
PropertiesConfiguration();
                 configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
-                
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "invalid");
+                
configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", 
"Accept_Any_Hostname");
+
+                
assertThat(ElasticSearchConfiguration.fromProperties(configuration)
+                        .getSslConfiguration())
+                    .isEqualTo(SSLConfiguration.builder()
+                        .strategyDefault()
+                        .acceptAnyHostNameVerifier()
+                        .build());
+            }
+
+            @Test
+            void fromPropertiesShouldThrowWhenInvalidVerifier() throws 
Exception {
+                PropertiesConfiguration configuration = new 
PropertiesConfiguration();
+                configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+                
configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", 
"invalid");
 
                 assertThatThrownBy(() -> 
ElasticSearchConfiguration.fromProperties(configuration))
                     .isInstanceOf(IllegalArgumentException.class)
-                    .hasMessage("invalid strategy 'invalid'");
+                    .hasMessage("invalid HostNameVerifier 'invalid'");
             }
         }
 
@@ -125,8 +192,8 @@ class ElasticSearchConfigurationTest {
                 
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "default");
 
                 
assertThat(ElasticSearchConfiguration.fromProperties(configuration)
-                        .getSslTrustConfiguration())
-                    .isEqualTo(SSLTrustConfiguration.defaultBehavior());
+                        .getSslConfiguration())
+                    .isEqualTo(SSLConfiguration.defaultBehavior());
             }
         }
 
@@ -141,8 +208,11 @@ class ElasticSearchConfigurationTest {
                 
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "ignore");
 
                 
assertThat(ElasticSearchConfiguration.fromProperties(configuration)
-                        .getSslTrustConfiguration())
-                    .isEqualTo(SSLTrustConfiguration.ignore());
+                        .getSslConfiguration())
+                    .isEqualTo(SSLConfiguration.builder()
+                        .strategyIgnore()
+                        .defaultHostNameVerifier()
+                        .build());
             }
         }
 
@@ -206,18 +276,20 @@ class ElasticSearchConfigurationTest {
                 PropertiesConfiguration configuration = new 
PropertiesConfiguration();
                 configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
-                String strategy = "override";
                 String trustStorePath = 
"src/test/resources/auth-es/server.jks";
                 String trustStorePassword = "secret";
 
-                
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 strategy);
+                
configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy",
 "override");
                 
configuration.addProperty("elasticsearch.hostScheme.https.trustStorePath", 
trustStorePath);
                 
configuration.addProperty("elasticsearch.hostScheme.https.trustStorePassword", 
trustStorePassword);
+                
configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", 
"default");
 
                 
assertThat(ElasticSearchConfiguration.fromProperties(configuration)
-                        .getSslTrustConfiguration())
-                    .isEqualTo(SSLTrustConfiguration.override(
-                        SSLTrustStore.of(trustStorePath, trustStorePassword)));
+                        .getSslConfiguration())
+                    .isEqualTo(SSLConfiguration.builder()
+                        .strategyOverride(SSLTrustStore.of(trustStorePath, 
trustStorePassword))
+                        .defaultHostNameVerifier()
+                        .build());
             }
         }
     }
diff --git 
a/dockerfiles/run/guice/cassandra-ldap/destination/conf/elasticsearch.properties
 
b/dockerfiles/run/guice/cassandra-ldap/destination/conf/elasticsearch.properties
index b2eefc5..74e5a3d 100644
--- 
a/dockerfiles/run/guice/cassandra-ldap/destination/conf/elasticsearch.properties
+++ 
b/dockerfiles/run/guice/cassandra-ldap/destination/conf/elasticsearch.properties
@@ -45,6 +45,12 @@ elasticsearch.port=9200
 # You need to specify both trustStorePath and trustStorePassword
 # elasticsearch.hostScheme.https.trustStorePassword=myJKSPassword
 
+# Optional. default is `default`
+# Configure Elasticsearch rest client to use host name verifier during SSL 
handshake
+# default: using the default hostname verifier provided by apache http client.
+# accept_any_hostname: accept any hostname (not recommended).
+# elasticsearch.hostScheme.https.hostNameVerifier=default
+
 # Optional.
 # Basic auth username to access elasticsearch.
 # Ignore elasticsearch.user and elasticsearch.password to not be using 
authentication (default behaviour).
diff --git 
a/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/elasticsearch.properties
 
b/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/elasticsearch.properties
index eecf449..0ea86db 100644
--- 
a/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/elasticsearch.properties
+++ 
b/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/elasticsearch.properties
@@ -44,6 +44,12 @@ elasticsearch.port=9200
 # You need to specify both trustStorePath and trustStorePassword
 # elasticsearch.hostScheme.https.trustStorePassword=myJKSPassword
 
+# Optional. default is `default`
+# Configure Elasticsearch rest client to use host name verifier during SSL 
handshake
+# default: using the default hostname verifier provided by apache http client.
+# accept_any_hostname: accept any hostname (not recommended).
+# elasticsearch.hostScheme.https.hostNameVerifier=default
+
 # Optional.
 # Basic auth username to access elasticsearch.
 # Ignore elasticsearch.user and elasticsearch.password to not be using 
authentication (default behaviour).
diff --git 
a/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/elasticsearch.properties
 
b/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/elasticsearch.properties
index eecf449..16ea216 100644
--- 
a/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/elasticsearch.properties
+++ 
b/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/elasticsearch.properties
@@ -44,6 +44,12 @@ elasticsearch.port=9200
 # You need to specify both trustStorePath and trustStorePassword
 # elasticsearch.hostScheme.https.trustStorePassword=myJKSPassword
 
+# Optional. default is `default`
+# Configure Elasticsearch rest client to use host name verifier during SSL 
handshake
+# default: using the default hostname verifier provided by apache http client.
+# accept_any_hostname: accept any host (not recommended).
+# elasticsearch.hostScheme.https.hostNameVerifier=default
+
 # Optional.
 # Basic auth username to access elasticsearch.
 # Ignore elasticsearch.user and elasticsearch.password to not be using 
authentication (default behaviour).
diff --git 
a/dockerfiles/run/guice/cassandra/destination/conf/elasticsearch.properties 
b/dockerfiles/run/guice/cassandra/destination/conf/elasticsearch.properties
index b2eefc5..74e5a3d 100644
--- a/dockerfiles/run/guice/cassandra/destination/conf/elasticsearch.properties
+++ b/dockerfiles/run/guice/cassandra/destination/conf/elasticsearch.properties
@@ -45,6 +45,12 @@ elasticsearch.port=9200
 # You need to specify both trustStorePath and trustStorePassword
 # elasticsearch.hostScheme.https.trustStorePassword=myJKSPassword
 
+# Optional. default is `default`
+# Configure Elasticsearch rest client to use host name verifier during SSL 
handshake
+# default: using the default hostname verifier provided by apache http client.
+# accept_any_hostname: accept any hostname (not recommended).
+# elasticsearch.hostScheme.https.hostNameVerifier=default
+
 # Optional.
 # Basic auth username to access elasticsearch.
 # Ignore elasticsearch.user and elasticsearch.password to not be using 
authentication (default behaviour).
diff --git a/src/site/xdoc/server/config-elasticsearch.xml 
b/src/site/xdoc/server/config-elasticsearch.xml
index f763272..789f044 100644
--- a/src/site/xdoc/server/config-elasticsearch.xml
+++ b/src/site/xdoc/server/config-elasticsearch.xml
@@ -252,6 +252,21 @@
               Once you chose <strong>override</strong>, you need to specify 
both trustStorePath and trustStorePassword.
             </dd>
         </dl>
+
+        <p>
+            During SSL handshaking, the client can determine whether accept or 
reject connecting to a remote server by its hostname.
+            You can configure to use which HostNameVerifier in the client.
+        </p>
+        <dl>
+            
<dt><strong>elasticsearch.hostScheme.https.hostNameVerifier</strong></dt>
+            <dd>
+              Optional. Default is <strong>default</strong>.
+            </dd>
+            <dd>
+              default: using the default hostname verifier provided by apache 
http client.
+              accept_any_hostname: accept any host (not recommended).
+            </dd>
+        </dl>
     </section>
 </body>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to