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 870798f43e11be79bbcfdce8ed4e7ccc40f16cf0 Author: Tran Tien Duc <[email protected]> AuthorDate: Tue Nov 12 16:35:47 2019 +0700 JAMES-2905 DockerElasticSearch now has two types - No authentication - Has authentication --- .../james/backends/es/DockerElasticSearch.java | 309 +++++++++++++++++---- .../backends/es/DockerElasticSearchSingleton.java | 2 +- .../backends/es/ElasticSearchClusterExtension.java | 115 ++++++++ .../src/test/resources/auth-es/NginxDockerfile | 5 + .../src/test/resources/auth-es/README.md | 30 ++ .../src/test/resources/auth-es/default.crt | 19 ++ .../src/test/resources/auth-es/default.key | 27 ++ .../src/test/resources/auth-es/nginx-conf/passwd | 2 + .../auth-es/nginx-conf/reverse_elasticsearch.conf | 12 + .../src/test/resources/auth-es/server.jks | Bin 0 -> 1074 bytes ...esWithNonCompatibleElasticSearchServerTest.java | 2 +- .../apache/james/metric/es/ES2ReporterTest.java | 2 +- .../apache/james/metric/es/ES6ReporterTest.java | 2 +- .../apache/james/util/docker/DockerContainer.java | 11 + 14 files changed, 487 insertions(+), 51 deletions(-) diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java index e3365b2..2424477 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java @@ -19,33 +19,98 @@ package org.apache.james.backends.es; +import static org.apache.james.backends.es.DockerElasticSearch.Fixture.ES_HTTP_PORT; + +import java.net.MalformedURLException; +import java.net.URL; +import java.security.cert.X509Certificate; import java.time.Duration; import java.util.Optional; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + import org.apache.http.HttpStatus; +import org.apache.james.backends.es.ElasticSearchConfiguration.Credential; +import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme; import org.apache.james.util.Host; import org.apache.james.util.docker.DockerContainer; import org.apache.james.util.docker.Images; import org.apache.james.util.docker.RateLimiters; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; +import org.testcontainers.images.builder.ImageFromDockerfile; import com.google.common.collect.ImmutableMap; +import feign.Client; import feign.Feign; import feign.Logger; import feign.RequestLine; import feign.Response; +import feign.auth.BasicAuthRequestInterceptor; import feign.slf4j.Slf4jLogger; -public class DockerElasticSearch { +public interface DockerElasticSearch { interface ElasticSearchAPI { - static ElasticSearchAPI from(Host esHttpHost) { - return Feign.builder() - .logger(new Slf4jLogger(ElasticSearchAPI.class)) - .logLevel(Logger.Level.FULL) - .target(ElasticSearchAPI.class, "http://" + esHttpHost.getHostName() + ":" + esHttpHost.getPort()); + class Builder { + private static final HostnameVerifier ACCEPT_ANY_HOST = (hostname1, sslSession) -> true; + private static final TrustManager[] TRUST_ALL = new TrustManager[] { + new X509TrustManager() { + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + } + }; + + private final Feign.Builder requestBuilder; + private final URL esURL; + + public Builder(URL esURL) { + this.esURL = esURL; + this.requestBuilder = Feign.builder() + .logger(new Slf4jLogger(ElasticSearchAPI.class)) + .logLevel(Logger.Level.FULL); + } + + public Builder credential(Credential credential) { + requestBuilder.requestInterceptor( + new BasicAuthRequestInterceptor(credential.getUsername(), credential.getPassword())); + return this; + } + + public Builder disableSSLValidation() throws Exception { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, TRUST_ALL, new java.security.SecureRandom()); + SSLSocketFactory factory = sc.getSocketFactory(); + HttpsURLConnection.setDefaultSSLSocketFactory(factory); + Client ignoredSSLClient = new Client.Default(factory, ACCEPT_ANY_HOST); + + requestBuilder.client(ignoredSSLClient); + + return this; + } + + public ElasticSearchAPI build() { + return requestBuilder.target(ElasticSearchAPI.class, esURL.toString()); + } + } + + static Builder builder(URL esURL) { + return new Builder(esURL); } @RequestLine("DELETE /_all") @@ -55,85 +120,235 @@ public class DockerElasticSearch { Response flush(); } - private static final int ES_HTTP_PORT = 9200; + interface Fixture { + int ES_HTTP_PORT = 9200; + } - private final DockerContainer eSContainer; + class NoAuth implements DockerElasticSearch { - public DockerElasticSearch() { - this(Images.ELASTICSEARCH_6); - } + static DockerContainer defaultContainer(String imageName) { + return DockerContainer.fromName(imageName) + .withTmpFs(ImmutableMap.of("/usr/share/elasticsearch/data", "rw,size=200m")) + .withExposedPorts(ES_HTTP_PORT) + .withEnv("discovery.type", "single-node") + .withAffinityToContainer() + .waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND)); + } - public DockerElasticSearch(String imageName) { - this.eSContainer = DockerContainer.fromName(imageName) - .withTmpFs(ImmutableMap.of("/usr/share/elasticsearch/data", "rw,size=200m")) - .withExposedPorts(ES_HTTP_PORT) - .withEnv("discovery.type", "single-node") - .withAffinityToContainer() - .waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND)); - } + private final DockerContainer eSContainer; - public void start() { - if (!eSContainer.isRunning()) { - eSContainer.start(); + public NoAuth() { + this(Images.ELASTICSEARCH_6); } - } - public void stop() { - eSContainer.stop(); - } + public NoAuth(String imageName) { + this.eSContainer = defaultContainer(imageName); + } - public int getHttpPort() { - return eSContainer.getMappedPort(ES_HTTP_PORT); - } + public NoAuth(DockerContainer eSContainer) { + this.eSContainer = eSContainer; + } + + public void start() { + if (!isRunning()) { + eSContainer.start(); + } + } + + public void stop() { + eSContainer.stop(); + } + + public int getHttpPort() { + return eSContainer.getMappedPort(ES_HTTP_PORT); + } + + public String getIp() { + return eSContainer.getHostIp(); + } + + public Host getHttpHost() { + return Host.from(getIp(), getHttpPort()); + } + + public void pause() { + eSContainer.pause(); + } + + public void unpause() { + eSContainer.unpause(); + } - public String getIp() { - return eSContainer.getHostIp(); + @Override + public boolean isRunning() { + return eSContainer.isRunning(); + } } - public Host getHttpHost() { - return Host.from(getIp(), getHttpPort()); + class WithAuth implements DockerElasticSearch { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WithAuth.class); + + private static final String DEFAULT_USERNAME = "elasticsearch"; + private static final String DEFAULT_PASSWORD = "secret"; + public static final Credential DEFAULT_CREDENTIAL = + Credential.of(DEFAULT_USERNAME, DEFAULT_PASSWORD); + + private final DockerElasticSearch.NoAuth elasticSearch; + private final DockerContainer nginx; + private final Network network; + + public WithAuth() { + this(Images.ELASTICSEARCH_6); + } + + WithAuth(String imageName) { + this.network = Network.newNetwork(); + this.elasticSearch = new DockerElasticSearch.NoAuth( + DockerElasticSearch.NoAuth + .defaultContainer(imageName) + .withLogConsumer(frame -> LOGGER.debug("[ElasticSearch] " + frame.getUtf8String())) + .withNetwork(network) + .withNetworkAliases("elasticsearch")); + + this.nginx = new DockerContainer( + new GenericContainer<>( + new ImageFromDockerfile() + .withFileFromClasspath("conf/nginx-conf/", "auth-es/nginx-conf/") + .withFileFromClasspath("conf/default.crt", "auth-es/default.crt") + .withFileFromClasspath("conf/default.key", "auth-es/default.key") + .withFileFromClasspath("Dockerfile", "auth-es/NginxDockerfile"))) + .withExposedPorts(ES_HTTP_PORT) + .withLogConsumer(frame -> LOGGER.debug("[NGINX] " + frame.getUtf8String())) + .withNetwork(network); + } + + + public void start() { + elasticSearch.start(); + nginx.start(); + } + + public void stop() { + nginx.stop(); + elasticSearch.stop(); + } + + public int getHttpPort() { + return nginx.getMappedPort(ES_HTTP_PORT); + } + + public String getIp() { + return nginx.getHostIp(); + } + + @Override + public ElasticSearchAPI esAPI() { + try { + return ElasticSearchAPI.builder(getUrl()) + .credential(DEFAULT_CREDENTIAL) + .disableSSLValidation() + .build(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public URL getUrl() { + try { + return new URL("https://" + getIp() + ":" + getHttpPort()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + @Override + public ElasticSearchConfiguration configuration(Optional<Duration> requestTimeout) { + return configurationBuilder(requestTimeout) + .hostScheme(Optional.of(HostScheme.HTTPS)) + .build(); + } + + public void pause() { + nginx.pause(); + elasticSearch.pause(); + } + + public void unpause() { + elasticSearch.unpause(); + nginx.unpause(); + } + + @Override + public boolean isRunning() { + return nginx.isRunning() && elasticSearch.isRunning(); + } } - public void pause() { - eSContainer.pause(); + void start(); + + void stop(); + + int getHttpPort(); + + String getIp(); + + void pause(); + + void unpause(); + + boolean isRunning(); + + default URL getUrl() { + try { + return new URL("http://" + getIp() + ":" + getHttpPort()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } } - public void unpause() { - eSContainer.unpause(); + default Host getHttpHost() { + return Host.from(getIp(), getHttpPort()); } - public void cleanUpData() { + default void cleanUpData() { if (esAPI().deleteAllIndexes().status() != HttpStatus.SC_OK) { throw new IllegalStateException("Failed to delete all data from ElasticSearch"); } } - public void flushIndices() { + default void flushIndices() { if (esAPI().flush().status() != HttpStatus.SC_OK) { throw new IllegalStateException("Failed to flush ElasticSearch"); } } - public ElasticSearchConfiguration configuration(Optional<Duration> requestTimeout) { + default ElasticSearchConfiguration configuration(Optional<Duration> requestTimeout) { + return configurationBuilder(requestTimeout) + .build(); + } + + default ElasticSearchConfiguration.Builder configurationBuilder(Optional<Duration> requestTimeout) { return ElasticSearchConfiguration.builder() .addHost(getHttpHost()) - .requestTimeout(requestTimeout) - .build(); + .requestTimeout(requestTimeout); } - public ElasticSearchConfiguration configuration() { + default ElasticSearchConfiguration configuration() { return configuration(Optional.empty()); } - public ClientProvider clientProvider() { + default ClientProvider clientProvider() { return new ClientProvider(configuration(Optional.empty())); } - public ClientProvider clientProvider(Duration requestTimeout) { + default ClientProvider clientProvider(Duration requestTimeout) { return new ClientProvider(configuration(Optional.of(requestTimeout))); } - private ElasticSearchAPI esAPI() { - return ElasticSearchAPI.from(getHttpHost()); + default ElasticSearchAPI esAPI() { + return ElasticSearchAPI.builder(getUrl()) + .build(); } } diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java index e3d409a..2175b34 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java @@ -20,7 +20,7 @@ package org.apache.james.backends.es; public class DockerElasticSearchSingleton { - public static DockerElasticSearch INSTANCE = new DockerElasticSearch(); + public static DockerElasticSearch INSTANCE = new DockerElasticSearch.NoAuth(); static { INSTANCE.start(); diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java new file mode 100644 index 0000000..3e73fe0 --- /dev/null +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java @@ -0,0 +1,115 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.backends.es; + +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.apache.james.util.Host; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.testcontainers.shaded.com.google.common.collect.ImmutableList; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +class ElasticSearchClusterExtension implements AfterAllCallback, BeforeAllCallback, AfterEachCallback, ParameterResolver { + + static class ElasticSearchCluster { + DockerElasticSearch es1; + DockerElasticSearch es2; + + ElasticSearchCluster(DockerElasticSearch es1, DockerElasticSearch es2) { + this.es1 = es1; + this.es2 = es2; + } + + void start() { + doInParallel(es1::start, es2::start); + } + + void cleanUp() { + doInParallel(() -> { + if (es1.isRunning()) { + es1.cleanUpData(); + }}, + () -> { + if (es1.isRunning()) { + es1.cleanUpData(); + }}); + } + + void stop() { + doInParallel(es2::stop); + } + + List<Host> getHosts() { + return ImmutableList.of(es1.getHttpHost(), es2.getHttpHost()); + } + + private void doInParallel(Runnable...runnables) { + Flux.fromStream(Stream.of(runnables) + .map(Mono::fromRunnable)) + .parallel(runnables.length) + .runOn(Schedulers.boundedElastic()) + .flatMap(Function.identity()) + .then() + .block(); + } + } + + private final ElasticSearchCluster esCluster; + + ElasticSearchClusterExtension(ElasticSearchCluster esCluster) { + this.esCluster = esCluster; + } + + @Override + public void beforeAll(ExtensionContext extensionContext) throws Exception { + esCluster.start(); + } + + @Override + public void afterEach(ExtensionContext extensionContext) throws Exception { + esCluster.cleanUp(); + } + + @Override + public void afterAll(ExtensionContext extensionContext) throws Exception { + esCluster.stop(); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return parameterContext.getParameter().getType() == ElasticSearchCluster.class; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return esCluster; + } +} \ No newline at end of file diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile b/backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile new file mode 100644 index 0000000..5a0f976 --- /dev/null +++ b/backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile @@ -0,0 +1,5 @@ +FROM nginx:1.15.1 + +COPY conf/nginx-conf/ /etc/nginx/conf.d/ +COPY conf/default.crt /etc/ssl/certs/default.crt +COPY conf/default.key /etc/ssl/private/default.key \ No newline at end of file diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/README.md b/backends-common/elasticsearch/src/test/resources/auth-es/README.md new file mode 100644 index 0000000..b7d945e --- /dev/null +++ b/backends-common/elasticsearch/src/test/resources/auth-es/README.md @@ -0,0 +1,30 @@ +## Resources explanation + +### nginx-conf + +Contains nginx configuration files: + - reverse_elasticsearch.conf: allow nginx to be the proxy connecting to ElasticSearch + - passwd: Nginx credentials file store, each record follow the format: `username:encrypted-password` + +### default.crt & default.key + +public (.crt) and private (.key) of the self signed SSL certification. It will be loaded by nginx + +### server.jks + +Once you use a http client connect to nginx by `https` protocol, +the default behavior of the client is rejecting the connection because +self signed SSL certification provided by nginx is not recognized by the +client. To deal with this problem, there are two ways to configure the client: + + - Not recommended in production, ignore SSL Validation + - Configure the client to use local TrustStore file containing the .crt, + then it should trust nginx. + +The `server.jks` is generated by the command +``` +keytool -import -v -trustcacerts -file default.crt -keystore server.jks -keypass mypass -storepass mypass +``` + +With: + - password: `mypass` \ No newline at end of file diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/default.crt b/backends-common/elasticsearch/src/test/resources/auth-es/default.crt new file mode 100644 index 0000000..d9aa6ca --- /dev/null +++ b/backends-common/elasticsearch/src/test/resources/auth-es/default.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBjCCAe4CCQDbp5K1cKRJgjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE4MDcwMjEyNDkxMloXDTE5MDcwMjEyNDkxMlowRTELMAkG +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AMMgzSF3uTnjSPwX9i1FEhdpKCDWAfWdg/arMWI1wdNjaz5jwA0Y4hPXN14ArIkH +ZCb9NPJZbUzcryeTvwEbZ8zqQ5+ghiGfGh9PFcz+RArOY2pPnIHOXVZaBIWxkzlF +atdJodNhbkxt+gmPi5xFlwDqPMijnAOI4gLcxQPG7mWyRpoD8YUzmMNFTJr1xFAV +XcJU+FJPP9zhOFRkGXnDupp8z9RYew+b39VGga6zHFGIP+iIMVJnEmW2/TQ1KE52 +b5B45bfGxlF7k003kIeaZsHbaIshdNMIz+w4bzywXNXyAfZccRGfraNXuSv0jAPS +O+nF9yyAocnz3QXOsmSGz28CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAFRDXedF9 +hjuEmLjETBwhh5Zgg102GDJp58ZBkLE1IaT4mrbK90mhpzxsaxbuqOdu3PXJV4tc +SEocxj5hk5ivVZiWk/j8YJmB8ZOUKdeOxc1tfratlonJ85AY+6m02+FhjUnWobmg +HVBepFTJt1iaTgOpVf8YpbYW+L6+kWV9C2CtT3WUhxtllKjokbF+YVN7LnDlbynM +80+aGm+rdg+TUusg+T/2FeVlDyBgbqagBcCQCQacWD2+zzL28XB3PwRE6oU/tKuu +rbCsGZE0WH8Pc7p6J/alRr+foQiu7KKJKJ8pO1qdy716DlmPIDN23iZROIu1GKKl +ZIKfyefPUcwHyw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/default.key b/backends-common/elasticsearch/src/test/resources/auth-es/default.key new file mode 100644 index 0000000..ebc29bb --- /dev/null +++ b/backends-common/elasticsearch/src/test/resources/auth-es/default.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAwyDNIXe5OeNI/Bf2LUUSF2koINYB9Z2D9qsxYjXB02NrPmPA +DRjiE9c3XgCsiQdkJv008lltTNyvJ5O/ARtnzOpDn6CGIZ8aH08VzP5ECs5jak+c +gc5dVloEhbGTOUVq10mh02FuTG36CY+LnEWXAOo8yKOcA4jiAtzFA8buZbJGmgPx +hTOYw0VMmvXEUBVdwlT4Uk8/3OE4VGQZecO6mnzP1Fh7D5vf1UaBrrMcUYg/6Igx +UmcSZbb9NDUoTnZvkHjlt8bGUXuTTTeQh5pmwdtoiyF00wjP7DhvPLBc1fIB9lxx +EZ+to1e5K/SMA9I76cX3LIChyfPdBc6yZIbPbwIDAQABAoIBAQC+DHmeyjQPDK8u +UcxE5UwsnxAlgysfZY59Ntn/dKpW0DNI7fDFEOJJPsm/ddqWECvcyavDC5SoUx0J +6B4V3vJnpBe/JqLdpk/UBLwQD+qHt+MeTXH6/9rq2vwilwT0uAbKrv29mtzJ9ied +HkF1MFZV3s7bAHdY/f5bmVkOR7g0NQ6QLuXYiLDSHpu/7dMVBNS9qMNL292cZbpi +KJZUvyrK6jSOh9Dt3fmWVdjRp5nGd/Z0r32A8UdoWiQ3cXe9uwXVxz8+ZGkP4t44 +Ob+YcgHUEz6iI2o7nqWpNtPI+hBWH1YK/Szlay3rTZSKvkNG1Sdwm1UhoJqNFucC +7ZWkH8GxAoGBAOSpP9lrB0sXCGwhD3xbAYCZsTgomSQ13X6/daKdN9fxpegK7v5r +baojBoSvIKiKezHzMiL5IiEhESXEvXQigFNORdf9mFs9Z9ec4I/96dQNYM4d1QtM +nz3dABt62po8ROCA4Y26ar+OmcJ2kv0RPuJCDGkrY1Is7SNTtGi+HW55AoGBANp1 +MJi3VHS9oEF8dslgLkZMZWPgcwJK2Y3wYIkatmxuVkWYdRFPqWWwlXUU17KH7eqm +iEONLNyI7g/duFFTbz52MkeMpX6xarXddYkS2HMDUqSTgt3T+ULHVhTtlEEBXg6m +5cx/eg8niJ6VH+vFtRcYrActLg751mjNgz8fmBMnAoGBAMwj4fHsIIXEWWuXlGi0 +IsI59EKr1BTE1isLKS11aN6sSS7BXB7dr/k97drVMrXldBjjArbAbtze1Z0/aNhe +2OwGrEopiDSkvKl8z+sdh/0duHgroADHdj9Xp3nhE3qxJdi8lyHd9OFxoQpAq/es +xtRenQ/jgXdizo9EcoM0f7gZAoGARw6ZSQNQyEwpxUM7zBKp2pnc3NjT7+nyy7Vl +YRM8RRa6nxaQ9ZmIyxfd9WBbLKoEHDAg4IAaGH29mZGP83wFEjcV8anw5r3ErPUk +1vo3R2nMRtXoWkkpqav29wW0FFTiiDeHRbYtOKKuUI7G/ESpu6J9yjPK6HohYKOA +Tlbzez8CgYAFhpoeHO2X06pEsFeI6rMtc0rS0EHuVuqfjjyEMOyQZ8BsCWzDZBDW +N9rxd0yz80H1Q33dwzrkiVu15e+JMNb5I80Ou0t+LQVYpvhtM89yKoLFk2HqL+eH +wQJ/Fszj8fwdwx+k2DEve8MVHSx/w9CpwM7B2yGxcUFKi/JSM1rQEw== +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd b/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd new file mode 100644 index 0000000..c489f73 --- /dev/null +++ b/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd @@ -0,0 +1,2 @@ +# the default credential: elasticsearch:secret +elasticsearch:$apr1$m5FvKpw7$EZ9UEUCilHyKTIqQ57nWG1 diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf b/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf new file mode 100644 index 0000000..77573cf --- /dev/null +++ b/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf @@ -0,0 +1,12 @@ +server { + listen 9200 ssl; + ssl_certificate /etc/ssl/certs/default.crt; + ssl_certificate_key /etc/ssl/private/default.key; + server_name reverse_elasticsearch; + auth_basic "Restricted Area"; + auth_basic_user_file /etc/nginx/conf.d/passwd; + + location / { + proxy_pass http://elasticsearch:9200; + } +} diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/server.jks b/backends-common/elasticsearch/src/test/resources/auth-es/server.jks new file mode 100644 index 0000000..10ef996 Binary files /dev/null and b/backends-common/elasticsearch/src/test/resources/auth-es/server.jks differ diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java index 3e16305..ebe9150 100644 --- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java @@ -39,7 +39,7 @@ class JamesWithNonCompatibleElasticSearchServerTest { private static final int LIMIT_MAX_MESSAGES = 10; - static DockerElasticSearch dockerES2 = new DockerElasticSearch(Images.ELASTICSEARCH_2); + static DockerElasticSearch dockerES2 = new DockerElasticSearch.NoAuth(Images.ELASTICSEARCH_2); @RegisterExtension static JamesServerExtension testExtension = new JamesServerBuilder() diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java index eb23804..1e09cf5 100644 --- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java +++ b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java @@ -27,5 +27,5 @@ class ES2ReporterTest extends ESReporterContract { @RegisterExtension static DockerElasticSearchExtension testExtension = new DockerElasticSearchExtension( - new DockerElasticSearch(Images.ELASTICSEARCH_2)); + new DockerElasticSearch.NoAuth(Images.ELASTICSEARCH_2)); } diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java index 0c201a4..ab7a9d4 100644 --- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java +++ b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java @@ -25,5 +25,5 @@ import org.junit.jupiter.api.extension.RegisterExtension; class ES6ReporterTest extends ESReporterContract { @RegisterExtension - static DockerElasticSearchExtension testExtension = new DockerElasticSearchExtension(new DockerElasticSearch()); + static DockerElasticSearchExtension testExtension = new DockerElasticSearchExtension(new DockerElasticSearch.NoAuth()); } diff --git a/server/testing/src/main/java/org/apache/james/util/docker/DockerContainer.java b/server/testing/src/main/java/org/apache/james/util/docker/DockerContainer.java index 07904a1..73b9162 100644 --- a/server/testing/src/main/java/org/apache/james/util/docker/DockerContainer.java +++ b/server/testing/src/main/java/org/apache/james/util/docker/DockerContainer.java @@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory; import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.images.builder.ImageFromDockerfile; @@ -81,6 +82,16 @@ public class DockerContainer implements TestRule { return this; } + public DockerContainer withNetwork(Network network) { + container.withNetwork(network); + return this; + } + + public DockerContainer withNetworkAliases(String... aliases) { + container.withNetworkAliases(aliases); + return this; + } + public DockerContainer withLogConsumer(Consumer<OutputFrame> consumer) { container.withLogConsumer(consumer); return this; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
