You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/05/20 09:39:57 UTC

[james-project] branch master updated (8ca9339 -> 48e0e83)

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

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


    from 8ca9339  Merge remote-tracking branch 'remk/JAMES-2772'
     new 4f8dc22  JAMES-2709 Rely on linagora/linshare-init for LinShare LDAP init
     new 323762f  JAMES-2765 Duplicate apache-james-mailbox-quota-search-elasticsearch
     new e77a6b8  JAMES-2765 Backend-ES v6 should still include ScrollIterable
     new 0ad1f0d  JAMES-2765 Type naming is no more supported in ES 6
     new 230b519  JAMES-2765 Migrate quota-search-elasticsearch to ES 6 REST client
     new 0430ef2  JAMES-2765 DeleteByQueryActionListener can be replaced by ListenerToFuture
     new b463bd3  JAMES-2765 User parameter is not required
     new 2d4c2c3  JAMES-2765 Solve some IntelliJ warnings
     new 48e0e83  JAMES-2765 TimeOut values was implicit

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../james/backends/es/v6/ElasticSearchIndexer.java |  27 ++-
 .../james/backends/es/v6/IndexCreationFactory.java |   2 +-
 ...ryActionListener.java => ListenerToFuture.java} |  24 ++-
 .../james/backends/es/v6/NodeMappingFactory.java   |  12 +-
 .../org/apache/james/backends/es/v6/TypeName.java  |  32 ----
 .../backends/es/v6}/search/ScrollIterable.java     |  51 ++++--
 .../backends/es/v6/DockerElasticSearchRule.java    |   4 +
 .../backends/es/v6/ElasticSearchIndexerTest.java   |  10 +-
 .../backends/es/v6/NodeMappingFactoryTest.java     |  14 +-
 .../backends/es/v6/search/ScrollIterableTest.java  | 203 +++++++++++++++++++++
 .../pom.xml                                        |  10 +-
 .../ElasticSearchQuotaConfiguration.java           |   9 +-
 .../elasticsearch/ElasticSearchQuotaSearcher.java  |  45 +++--
 .../search/elasticsearch/QuotaQueryConverter.java  |   6 +-
 .../QuotaRatioElasticSearchConstants.java          |   8 +-
 .../elasticsearch/QuotaRatioMappingFactory.java    |  37 ++--
 .../QuotaSearchIndexCreationUtil.java              |  21 ++-
 .../events/ElasticSearchQuotaMailboxListener.java  |  17 +-
 .../elasticsearch/json/JsonMessageConstants.java   |   0
 .../elasticsearch/json/QuotaRatioAsJson.java       |   0
 .../json/QuotaRatioToElasticSearchJson.java        |   4 +-
 .../ElasticSearchQuotaConfigurationTest.java       |  23 ++-
 ...lasticSearchQuotaSearchTestSystemExtension.java |  28 ++-
 .../ElasticSearchQuotaSearcherTest.java            |   2 +-
 .../elasticsearch/QuotaQueryConverterTest.java     |   0
 .../ElasticSearchQuotaMailboxListenerTest.java     |  50 +++--
 .../elasticsearch/json/QuotaRatioAsJsonTest.java   |  16 +-
 .../json/QuotaRatioToElasticSearchJsonTest.java    |   5 +-
 .../src/test/resources/quotaRatio.json             |   0
 .../src/test/resources/quotaRatioNoDomain.json     |   0
 mailbox/pom.xml                                    |   1 +
 pom.xml                                            |  11 ++
 .../james/linshare/LDAPConfigurationPerformer.java | 122 -------------
 .../java/org/apache/james/linshare/Linshare.java   |  27 ++-
 34 files changed, 447 insertions(+), 374 deletions(-)
 rename backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/{DeleteByQueryActionListener.java => ListenerToFuture.java} (73%)
 delete mode 100644 backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/TypeName.java
 copy backends-common/{elasticsearch/src/main/java/org/apache/james/backends/es => elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6}/search/ScrollIterable.java (55%)
 create mode 100644 backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/pom.xml (93%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java (95%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java (69%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java (97%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java (83%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java (63%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java (77%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java (83%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java (100%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java (100%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java (93%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java (81%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java (82%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java (94%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java (100%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java (71%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java (89%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java (98%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/resources/quotaRatio.json (100%)
 copy mailbox/plugin/{quota-search-elasticsearch => quota-search-elasticsearch-v6}/src/test/resources/quotaRatioNoDomain.json (100%)
 delete mode 100644 third-party/linshare/src/test/java/org/apache/james/linshare/LDAPConfigurationPerformer.java


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 01/09: JAMES-2709 Rely on linagora/linshare-init for LinShare LDAP init

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4f8dc2284b385a6f3938f41642afa4eaa277918e
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu May 16 10:18:04 2019 +0700

    JAMES-2709 Rely on linagora/linshare-init for LinShare LDAP init
---
 .../james/linshare/LDAPConfigurationPerformer.java | 122 ---------------------
 .../java/org/apache/james/linshare/Linshare.java   |  27 ++++-
 2 files changed, 25 insertions(+), 124 deletions(-)

diff --git a/third-party/linshare/src/test/java/org/apache/james/linshare/LDAPConfigurationPerformer.java b/third-party/linshare/src/test/java/org/apache/james/linshare/LDAPConfigurationPerformer.java
deleted file mode 100644
index d74d445..0000000
--- a/third-party/linshare/src/test/java/org/apache/james/linshare/LDAPConfigurationPerformer.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************
- * 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.linshare;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.config.EncoderConfig.encoderConfig;
-import static io.restassured.config.RestAssuredConfig.newConfig;
-
-import java.nio.charset.StandardCharsets;
-
-import io.restassured.authentication.BasicAuthScheme;
-import io.restassured.builder.RequestSpecBuilder;
-import io.restassured.http.ContentType;
-import io.restassured.specification.RequestSpecification;
-
-class LDAPConfigurationPerformer {
-    static void configureLdap(Linshare linshare) {
-        BasicAuthScheme basicAuthScheme = new BasicAuthScheme();
-        basicAuthScheme.setUserName("root@localhost.localdomain");
-        basicAuthScheme.setPassword("adminlinshare");
-
-        RequestSpecification specification = new RequestSpecBuilder()
-            .setContentType(ContentType.JSON)
-            .setAccept(ContentType.JSON)
-            .setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(StandardCharsets.UTF_8)))
-            .setBaseUri("http://" + linshare.getIp())
-            .setPort(linshare.getPort())
-            .setAuth(basicAuthScheme)
-            .build();
-
-        String ldapId = given(specification)
-            .body("{" +
-                "  \"label\":\"ldap-local\"," +
-                "  \"providerUrl\":\"ldap://ldap:389\"," +
-                "  \"securityPrincipal\":\"cn=linshare,dc=linshare,dc=org\"," +
-                "  \"securityCredentials\":\"linshare\"" +
-                "}")
-            .post("/linshare/webservice/rest/admin/ldap_connections")
-            .jsonPath()
-            .getString("uuid");
-
-        given(specification)
-            .body("{" +
-                "  \"uuid\":\"868400c0-c12e-456a-8c3c-19e985290586\"," +
-                "  \"label\":\"openldap-local\"," +
-                "  \"description\":\"This is pattern the default pattern for the OpenLdap structure.\"," +
-                "  \"authCommand\":\"ldap.search(domain, \\\"(&(objectClass=inetOrgPerson)(mail=*)(givenName=*)(sn=*)(|(mail=\\\"+login+\\\")(uid=\\\"+login+\\\")))\\\");\"," +
-                "  \"searchUserCommand\":\"ldap.search(domain, \\\"(&(objectClass=inetOrgPerson)(mail=\\\"+mail+\\\")(givenName=\\\"+first_name+\\\")(sn=\\\"+last_name+\\\"))\\\");\"," +
-                "  \"userMail\":\"mail\"," +
-                "  \"userFirstName\":\"givenName\"," +
-                "  \"userLastName\":\"sn\"," +
-                "  \"ldapUid\":\"uid\"," +
-                "  \"autoCompleteCommandOnAllAttributes\":\"ldap.search(domain, \\\"(&(objectClass=inetOrgPerson)(mail=*)(givenName=*)(sn=*)(|(mail=\\\" + pattern + \\\")(sn=\\\" + pattern + \\\")(givenName=\\\" + pattern + \\\")))\\\");\"," +
-                "  \"autoCompleteCommandOnFirstAndLastName\":\"ldap.search(domain, \\\"(&(objectClass=inetOrgPerson)(mail=*)(givenName=*)(sn=*)(|(&(sn=\\\" + first_name + \\\")(givenName=\\\" + last_name + \\\"))(&(sn=\\\" + last_name + \\\")(givenName=\\\" + first_name + \\\"))))\\\");\"," +
-                "  \"searchPageSize\":100," +
-                "  \"searchSizeLimit\":100," +
-                "  \"completionPageSize\":10," +
-                "  \"completionSizeLimit\":10" +
-                "}")
-            .post("/linshare/webservice/rest/admin/domain_patterns");
-
-        String ldapPatternId = given(specification)
-            .get("/linshare/webservice/rest/admin/domain_patterns")
-            .getBody()
-            .jsonPath()
-            .getString("[0].uuid");
-
-        String mimePolicyId = given(specification)
-            .get("/linshare/webservice/rest/admin/mime_policies?domainId=LinShareRootDomain&onlyCurrentDomain=false")
-            .jsonPath()
-            .getString("[0].uuid");
-
-        String welcomeMessageId = given(specification)
-            .get("/linshare/webservice/rest/admin/welcome_messages?domainId=LinShareRootDomain&parent=true")
-            .jsonPath()
-            .getString("[0].uuid");
-
-        String mailConfigId = given(specification)
-            .get("/linshare/webservice/rest/admin/mail_configs?domainId=LinShareRootDomain&onlyCurrentDomain=false")
-            .jsonPath()
-            .getString("[0].uuid");
-
-        given(specification)
-            .body("{" +
-                "  \"parent\":\"LinShareRootDomain\"," +
-                "  \"type\":\"TOPDOMAIN\"," +
-                "  \"providers\":[" +
-                "    {" +
-                "      \"ldapConnectionUuid\":\"" + ldapId + "\"," +
-                "      \"userLdapPatternUuid\":\"" + ldapPatternId + "\"," +
-                "      \"baseDn\":\"ou=People,dc=linshare,dc=org\"" +
-                "     }]," +
-                "  \"externalMailLocale\":\"ENGLISH\"," +
-                "  \"language\":\"ENGLISH\"," +
-                "  \"mailConfigUuid\":\"" + mailConfigId + "\"," +
-                "  \"currentWelcomeMessage\":{\"uuid\":\"" + welcomeMessageId + "\"}," +
-                "  \"mimePolicyUuid\":\"" + mimePolicyId + "\"," +
-                "  \"userRole\":\"SIMPLE\"," +
-                "  \"policy\":{\"identifier\":\"DefaultDomainPolicy\"}," +
-                "  \"label\":\"linshare.org\"," +
-                "  \"description\":\"linshare.org domain\"" +
-                "}")
-            .post("/linshare/webservice/rest/admin/domains");
-    }
-}
diff --git a/third-party/linshare/src/test/java/org/apache/james/linshare/Linshare.java b/third-party/linshare/src/test/java/org/apache/james/linshare/Linshare.java
index 9986bd7..6f33518 100644
--- a/third-party/linshare/src/test/java/org/apache/james/linshare/Linshare.java
+++ b/third-party/linshare/src/test/java/org/apache/james/linshare/Linshare.java
@@ -37,6 +37,7 @@ import io.restassured.specification.RequestSpecification;
 
 public class Linshare {
     private static final String WAIT_FOR_BACKEND_INIT_LOG = ".*Server startup.*";
+    private static final String WAIT_FOR_LDAP_INIT_LOG = ".*The following user provider for domain '.*' was successfully created.*";
     private static final int LINSHARE_BACKEND_PORT = 8080;
 
     private final GenericContainer<?> linshareBackend;
@@ -44,6 +45,7 @@ public class Linshare {
     private final GenericContainer<?> linshareSmtp;
     private final GenericContainer<?> linshareLdap;
     private final GenericContainer<?> linshareMongodb;
+    private final GenericContainer<?> linshareDBInit;
 
     private Network network;
 
@@ -55,6 +57,7 @@ public class Linshare {
         linshareLdap = createDockerLdap();
         linshareSmtp = createDockerSmtp();
         linshareBackend = createDockerBackend();
+        linshareDBInit = createLinshareBackendInit();
     }
 
     public void start() {
@@ -63,11 +66,11 @@ public class Linshare {
         linshareLdap.start();
         linshareSmtp.start();
         linshareBackend.start();
-
-        LDAPConfigurationPerformer.configureLdap(this);
+        linshareDBInit.start();
     }
 
     public void stop() {
+        linshareDBInit.stop();
         linshareDatabase.stop();
         linshareMongodb.stop();
         linshareLdap.stop();
@@ -139,6 +142,26 @@ public class Linshare {
             .withNetwork(network);
     }
 
+    private GenericContainer createLinshareBackendInit() {
+        return new GenericContainer<>("linagora/linshare-init:2.2")
+            .withNetworkAliases("init")
+            .withEnv("LS_HOST", "backend")
+            .withEnv("LS_PORT", "8080")
+            .withEnv("LS_LDAP_NAME", "ldap-local")
+            .withEnv("LS_LDAP_URL", "ldap://ldap:389")
+            .withEnv("LS_LDAP_BASE_DN", "ou=People,dc=linshare,dc=org")
+            .withEnv("LS_LDAP_DN", "cn=linshare,dc=linshare,dc=org")
+            .withEnv("LS_LDAP_PW", "linshare")
+            .withEnv("LS_DOMAIN_PATTERN_NAME", "openldap-local")
+            .withEnv("LS_DOMAIN_PATTERN_MODEL", "868400c0-c12e-456a-8c3c-19e985290586")
+            .withEnv("NO_REPLY_ADDRESS", "linshare-noreply@linshare.org")
+            .withEnv("DEBUG", "1")
+            .withEnv("FORCE_INIT", "1")
+            .waitingFor(Wait.forLogMessage(WAIT_FOR_LDAP_INIT_LOG, 1)
+                .withStartupTimeout(Duration.ofMinutes(10)))
+            .withNetwork(network);
+    }
+
     public RequestSpecification fakeSmtpRequestSpecification() {
         return new RequestSpecBuilder()
             .setContentType(ContentType.JSON)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 05/09: JAMES-2765 Migrate quota-search-elasticsearch to ES 6 REST client

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 230b51979ce4d2221fec86c9794e8d51ab96e3be
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu May 16 17:43:34 2019 +0700

    JAMES-2765 Migrate quota-search-elasticsearch to ES 6 REST client
---
 .../plugin/quota-search-elasticsearch-v6/pom.xml   |  4 +-
 .../ElasticSearchQuotaConfiguration.java           |  6 +--
 .../elasticsearch/ElasticSearchQuotaSearcher.java  | 43 +++++++++----------
 .../search/elasticsearch/QuotaQueryConverter.java  |  6 +--
 .../QuotaRatioElasticSearchConstants.java          |  8 ++--
 .../elasticsearch/QuotaRatioMappingFactory.java    | 37 +++++++---------
 .../QuotaSearchIndexCreationUtil.java              | 21 ++++-----
 .../events/ElasticSearchQuotaMailboxListener.java  | 10 ++---
 .../ElasticSearchQuotaConfigurationTest.java       |  6 +--
 ...lasticSearchQuotaSearchTestSystemExtension.java | 26 +++++------
 .../ElasticSearchQuotaSearcherTest.java            |  2 +-
 .../ElasticSearchQuotaMailboxListenerTest.java     | 50 +++++++++++-----------
 pom.xml                                            | 11 +++++
 13 files changed, 112 insertions(+), 118 deletions(-)

diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml b/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml
index c1eeca6..7135337 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml
@@ -34,11 +34,11 @@
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-backends-es</artifactId>
+            <artifactId>apache-james-backends-es-v6</artifactId>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>apache-james-backends-es</artifactId>
+            <artifactId>apache-james-backends-es-v6</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
index c14f339..53e6d9b 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
@@ -24,9 +24,9 @@ import java.util.Optional;
 
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.ConfigurationException;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
+import org.apache.james.backends.es.v6.IndexName;
+import org.apache.james.backends.es.v6.ReadAliasName;
+import org.apache.james.backends.es.v6.WriteAliasName;
 
 public class ElasticSearchQuotaConfiguration {
 
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
index 21d55a8..55ce6c9 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
@@ -19,22 +19,24 @@
 
 package org.apache.james.quota.search.elasticsearch;
 
-import static org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE;
 import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Stream;
 
-import org.apache.james.backends.es.AliasName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.search.ScrollIterable;
+import org.apache.james.backends.es.v6.AliasName;
+import org.apache.james.backends.es.v6.NodeMappingFactory;
+import org.apache.james.backends.es.v6.ReadAliasName;
+import org.apache.james.backends.es.v6.search.ScrollIterable;
 import org.apache.james.core.User;
 import org.apache.james.quota.search.QuotaQuery;
 import org.apache.james.quota.search.QuotaSearcher;
-import org.elasticsearch.action.search.SearchRequestBuilder;
-import org.elasticsearch.client.Client;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.client.RestHighLevelClient;
 import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.elasticsearch.search.sort.SortBuilders;
 import org.elasticsearch.search.sort.SortOrder;
 
@@ -43,11 +45,11 @@ import com.github.steveash.guavate.Guavate;
 public class ElasticSearchQuotaSearcher implements QuotaSearcher {
     private static final TimeValue TIMEOUT = new TimeValue(60000);
 
-    private final Client client;
+    private final RestHighLevelClient client;
     private final AliasName readAlias;
     private final QuotaQueryConverter quotaQueryConverter;
 
-    public ElasticSearchQuotaSearcher(Client client, ReadAliasName readAlias) {
+    public ElasticSearchQuotaSearcher(RestHighLevelClient client, ReadAliasName readAlias) {
         this.client = client;
         this.readAlias = readAlias;
         this.quotaQueryConverter = new QuotaQueryConverter();
@@ -59,8 +61,7 @@ public class ElasticSearchQuotaSearcher implements QuotaSearcher {
             .stream()
             .flatMap(searchResponse -> Arrays.stream(searchResponse.getHits()
                 .getHits()))
-            .map(hit -> hit.field(USER))
-            .map(field -> (String) field.getValue())
+            .map(SearchHit::getId)
             .map(User::fromUsername)
             .skip(query.getOffset().getValue());
 
@@ -70,22 +71,20 @@ public class ElasticSearchQuotaSearcher implements QuotaSearcher {
             .collect(Guavate.toImmutableList());
     }
 
-    public SearchRequestBuilder prepareSearch(QuotaQuery query) {
-        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(readAlias.getValue())
-            .setTypes(QUOTA_RATIO_TYPE.getValue())
-            .setScroll(TIMEOUT)
-            .addFields(USER)
-            .setQuery(quotaQueryConverter.from(query));
+    public SearchRequest prepareSearch(QuotaQuery query) {
+        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
+            .query(quotaQueryConverter.from(query))
+            .sort(SortBuilders.fieldSort(USER)
+                .order(SortOrder.ASC));
 
         query.getLimit()
             .getValue()
-            .ifPresent(searchRequestBuilder::setSize);
-
-        searchRequestBuilder.addSort(
-            SortBuilders.fieldSort(USER)
-                .order(SortOrder.ASC));
+            .ifPresent(sourceBuilder::size);
 
-        return searchRequestBuilder;
+        return new SearchRequest(readAlias.getValue())
+            .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+            .scroll(TIMEOUT)
+            .source(sourceBuilder);
     }
 
 }
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
index b02d8ac..a67d063 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
@@ -43,10 +43,10 @@ import org.elasticsearch.index.query.TermQueryBuilder;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 
-public class QuotaQueryConverter {
+class QuotaQueryConverter {
     private final Map<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> clauseConverter;
 
-    public QuotaQueryConverter() {
+    QuotaQueryConverter() {
         Builder<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> builder = ImmutableMap.builder();
         
         builder.put(HasDomain.class, this::convertHasDomain);
@@ -57,7 +57,7 @@ public class QuotaQueryConverter {
         clauseConverter = builder.build();
     }
 
-    public QueryBuilder from(QuotaQuery query) {
+    QueryBuilder from(QuotaQuery query) {
         List<QuotaClause> clauses = query.getClause().getClauses();
         if (clauses.isEmpty()) {
             return matchAllQuery();
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
index e3ceadd..43cb89e 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
@@ -19,10 +19,9 @@
 
 package org.apache.james.quota.search.elasticsearch;
 
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.TypeName;
-import org.apache.james.backends.es.WriteAliasName;
+import org.apache.james.backends.es.v6.IndexName;
+import org.apache.james.backends.es.v6.ReadAliasName;
+import org.apache.james.backends.es.v6.WriteAliasName;
 
 public interface QuotaRatioElasticSearchConstants {
 
@@ -33,5 +32,4 @@ public interface QuotaRatioElasticSearchConstants {
     WriteAliasName DEFAULT_QUOTA_RATIO_WRITE_ALIAS = new WriteAliasName("quota_ratio_write_alias");
     ReadAliasName DEFAULT_QUOTA_RATIO_READ_ALIAS = new ReadAliasName("quota_ratio_read_alias");
     IndexName DEFAULT_QUOTA_RATIO_INDEX = new IndexName("quota_ratio_v1");
-    TypeName QUOTA_RATIO_TYPE = new TypeName("quota_ratio");
 }
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
index 128f1d1..78d7aa3 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
@@ -19,12 +19,10 @@
 
 package org.apache.james.quota.search.elasticsearch;
 
-import static org.apache.james.backends.es.NodeMappingFactory.DOUBLE;
-import static org.apache.james.backends.es.NodeMappingFactory.INDEX;
-import static org.apache.james.backends.es.NodeMappingFactory.NOT_ANALYZED;
-import static org.apache.james.backends.es.NodeMappingFactory.PROPERTIES;
-import static org.apache.james.backends.es.NodeMappingFactory.STRING;
-import static org.apache.james.backends.es.NodeMappingFactory.TYPE;
+import static org.apache.james.backends.es.v6.NodeMappingFactory.DOUBLE;
+import static org.apache.james.backends.es.v6.NodeMappingFactory.KEYWORD;
+import static org.apache.james.backends.es.v6.NodeMappingFactory.PROPERTIES;
+import static org.apache.james.backends.es.v6.NodeMappingFactory.TYPE;
 import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.DOMAIN;
 import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
 import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER;
@@ -34,29 +32,24 @@ import java.io.IOException;
 
 import org.elasticsearch.common.xcontent.XContentBuilder;
 
-public class QuotaRatioMappingFactory {
+class QuotaRatioMappingFactory {
 
     public static XContentBuilder getMappingContent() {
         try {
             return jsonBuilder()
                 .startObject()
+                    .startObject(PROPERTIES)
 
-                    .startObject(QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE.getValue())
-                        .startObject(PROPERTIES)
-
-                            .startObject(USER)
-                                .field(TYPE, STRING)
-                                .field(INDEX, NOT_ANALYZED)
-                            .endObject()
+                        .startObject(USER)
+                            .field(TYPE, KEYWORD)
+                        .endObject()
 
-                            .startObject(DOMAIN)
-                                .field(TYPE, STRING)
-                                .field(INDEX, NOT_ANALYZED)
-                            .endObject()
+                        .startObject(DOMAIN)
+                            .field(TYPE, KEYWORD)
+                        .endObject()
 
-                            .startObject(QUOTA_RATIO)
-                                .field(TYPE, DOUBLE)
-                            .endObject()
+                        .startObject(QUOTA_RATIO)
+                            .field(TYPE, DOUBLE)
                         .endObject()
                     .endObject()
                 .endObject();
@@ -64,4 +57,4 @@ public class QuotaRatioMappingFactory {
             throw new RuntimeException(e);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
index f546230..3555b28 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
@@ -19,20 +19,22 @@
 
 package org.apache.james.quota.search.elasticsearch;
 
-import org.apache.james.backends.es.AliasName;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.IndexCreationFactory;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.elasticsearch.client.Client;
+import java.io.IOException;
+
+import org.apache.james.backends.es.v6.AliasName;
+import org.apache.james.backends.es.v6.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v6.IndexCreationFactory;
+import org.apache.james.backends.es.v6.IndexName;
+import org.apache.james.backends.es.v6.NodeMappingFactory;
+import org.elasticsearch.client.RestHighLevelClient;
 
 public class QuotaSearchIndexCreationUtil {
 
-    public static Client prepareClient(Client client,
+    public static RestHighLevelClient prepareClient(RestHighLevelClient client,
                                        AliasName readAlias,
                                        AliasName writeAlias,
                                        IndexName indexName,
-                                       ElasticSearchConfiguration configuration) {
+                                       ElasticSearchConfiguration configuration) throws IOException {
 
         return NodeMappingFactory.applyMapping(
             new IndexCreationFactory(configuration)
@@ -41,11 +43,10 @@ public class QuotaSearchIndexCreationUtil {
                 .addAlias(writeAlias)
                 .createIndexAndAliases(client),
             indexName,
-            QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE,
             QuotaRatioMappingFactory.getMappingContent());
     }
 
-    public static Client prepareDefaultClient(Client client, ElasticSearchConfiguration configuration) {
+    public static RestHighLevelClient prepareDefaultClient(RestHighLevelClient client, ElasticSearchConfiguration configuration) throws IOException {
         return prepareClient(client,
             QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS,
             QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
index 2b828f2..1a14c0c 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
@@ -18,10 +18,12 @@
  ****************************************************************/
 package org.apache.james.quota.search.elasticsearch.events;
 
+import java.io.IOException;
+
 import javax.inject.Inject;
 import javax.inject.Named;
 
-import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.backends.es.v6.ElasticSearchIndexer;
 import org.apache.james.core.User;
 import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.Group;
@@ -29,8 +31,6 @@ import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-
 public class ElasticSearchQuotaMailboxListener implements MailboxListener.GroupMailboxListener {
     public static class ElasticSearchQuotaMailboxListenerGroup extends Group {
     }
@@ -59,11 +59,11 @@ public class ElasticSearchQuotaMailboxListener implements MailboxListener.GroupM
     }
 
     @Override
-    public void event(Event event) throws JsonProcessingException {
+    public void event(Event event) throws IOException {
         handleEvent(event.getUser(), (QuotaUsageUpdatedEvent) event);
     }
 
-    private void handleEvent(User user, QuotaUsageUpdatedEvent event) throws JsonProcessingException {
+    private void handleEvent(User user, QuotaUsageUpdatedEvent event) throws IOException {
         indexer.index(user.asString(),
             quotaRatioToElasticSearchJson.convertToJson(user.asString(), event));
     }
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
index a57a10e..2027436 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
@@ -23,9 +23,9 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
+import org.apache.james.backends.es.v6.IndexName;
+import org.apache.james.backends.es.v6.ReadAliasName;
+import org.apache.james.backends.es.v6.WriteAliasName;
 import org.junit.Test;
 
 public class ElasticSearchQuotaConfigurationTest {
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
index 5e63c46..a4194ca 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
@@ -21,13 +21,10 @@ package org.apache.james.quota.search.elasticsearch;
 
 import static org.mockito.Mockito.mock;
 
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.DockerElasticSearchSingleton;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.backends.es.v6.DockerElasticSearch;
+import org.apache.james.backends.es.v6.DockerElasticSearchSingleton;
+import org.apache.james.backends.es.v6.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v6.ElasticSearchIndexer;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
@@ -36,8 +33,7 @@ import org.apache.james.quota.search.QuotaSearchTestSystem;
 import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
 import org.apache.james.user.memory.MemoryUsersRepository;
-import org.apache.james.util.concurrent.NamedThreadFactory;
-import org.elasticsearch.client.Client;
+import org.elasticsearch.client.RestHighLevelClient;
 import org.junit.jupiter.api.extension.AfterEachCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
@@ -57,10 +53,10 @@ public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterRes
     @Override
     public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
         try {
-            Client client = QuotaSearchIndexCreationUtil.prepareDefaultClient(
+            RestHighLevelClient client = QuotaSearchIndexCreationUtil.prepareDefaultClient(
                 elasticSearch.clientProvider().get(),
                 ElasticSearchConfiguration.builder()
-                    .addHost(elasticSearch.getTcpHost())
+                    .addHost(elasticSearch.getHttpHost())
                     .build());
 
             InMemoryIntegrationResources resources = InMemoryIntegrationResources.defaultResources();
@@ -71,11 +67,9 @@ public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterRes
             MemoryDomainList domainList = new MemoryDomainList(dnsService);
             usersRepository.setDomainList(domainList);
 
-            ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
             ElasticSearchQuotaMailboxListener listener = new ElasticSearchQuotaMailboxListener(
-                new ElasticSearchIndexer(client, Executors.newSingleThreadExecutor(threadFactory),
-                    QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
-                    QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE),
+                new ElasticSearchIndexer(client,
+                    QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS),
                 new QuotaRatioToElasticSearchJson());
 
             resources.getMailboxManager().getEventBus().register(listener);
@@ -92,7 +86,7 @@ public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterRes
                 usersRepository,
                 domainList,
                 resources.getCurrentQuotaManager(),
-                () -> elasticSearch.awaitForElasticSearch());
+                elasticSearch::awaitForElasticSearch);
         } catch (Exception e) {
             throw new ParameterResolutionException("Error while resolving parameter", e);
         }
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
index ad26532..2d4b79e 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
@@ -23,6 +23,6 @@ import org.apache.james.quota.search.QuotaSearcherContract;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 @ExtendWith(ElasticSearchQuotaSearchTestSystemExtension.class)
-public class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
+class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
 
 }
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
index d3f7811..bfead33 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
@@ -23,15 +23,13 @@ import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.BOB
 import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.NOW;
 import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.QUOTAROOT;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-import static org.mockito.Mockito.mock;
 
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
+import java.io.IOException;
 
-import org.apache.james.backends.es.DockerElasticSearchRule;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.backends.es.v6.DockerElasticSearchRule;
+import org.apache.james.backends.es.v6.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v6.ElasticSearchIndexer;
+import org.apache.james.backends.es.v6.NodeMappingFactory;
 import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.Group;
 import org.apache.james.mailbox.quota.QuotaFixture.Counts;
@@ -40,9 +38,12 @@ import org.apache.james.mailbox.store.event.EventFactory;
 import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
 import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
-import org.apache.james.util.concurrent.NamedThreadFactory;
+import org.elasticsearch.action.search.SearchRequest;
 import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.client.Client;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -51,27 +52,23 @@ public class ElasticSearchQuotaMailboxListenerTest {
     private static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
 
     private static final int BATCH_SIZE = 1;
-    private static final Event DUMB_EVENT = mock(Event.class);
 
     @Rule
     public DockerElasticSearchRule elasticSearch = new DockerElasticSearchRule();
     private ElasticSearchQuotaMailboxListener quotaMailboxListener;
-    private Client client;
+    private RestHighLevelClient client;
 
     @Before
-    public void setUp() {
-        client = QuotaSearchIndexCreationUtil.prepareDefaultClient(
-            elasticSearch.clientProvider().get(),
-            ElasticSearchConfiguration.builder()
-                .addHost(elasticSearch.getTcpHost())
-                .build());
+    public void setUp() throws IOException {
+        client = elasticSearch.clientProvider().get();
+
+        QuotaSearchIndexCreationUtil.prepareDefaultClient(client, ElasticSearchConfiguration.builder()
+            .addHost(elasticSearch.getDockerElasticSearch().getHttpHost())
+            .build());
 
-        ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
         quotaMailboxListener = new ElasticSearchQuotaMailboxListener(
             new ElasticSearchIndexer(client,
-                Executors.newSingleThreadExecutor(threadFactory),
                 QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
-                QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE,
                 BATCH_SIZE),
             new QuotaRatioToElasticSearchJson());
     }
@@ -95,11 +92,12 @@ public class ElasticSearchQuotaMailboxListenerTest {
 
         elasticSearch.awaitForElasticSearch();
 
-        SearchResponse searchResponse = client.prepareSearch(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS.getValue())
-            .setTypes(QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE.getValue())
-            .setQuery(matchAllQuery())
-            .execute()
-            .get();
-        assertThat(searchResponse.getHits().totalHits()).isEqualTo(1);
+        SearchResponse searchResponse = client.search(new SearchRequest(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS.getValue())
+                .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                .source(new SearchSourceBuilder()
+                    .query(QueryBuilders.matchAllQuery())),
+            RequestOptions.DEFAULT);
+
+        assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
     }
 }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 7100134..933c8f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -698,6 +698,17 @@
             </dependency>
             <dependency>
                 <groupId>${james.groupId}</groupId>
+                <artifactId>apache-james-backends-es-v6</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${james.groupId}</groupId>
+                <artifactId>apache-james-backends-es-v6</artifactId>
+                <version>${project.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>${james.groupId}</groupId>
                 <artifactId>apache-james-backends-jpa</artifactId>
                 <version>${project.version}</version>
             </dependency>


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 07/09: JAMES-2765 User parameter is not required

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b463bd3165f6703b5054b13d8b460b1d9706aafd
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sat May 18 16:37:34 2019 +0700

    JAMES-2765 User parameter is not required
    
    User can very easily be retrieved from the event
---
 .../elasticsearch/events/ElasticSearchQuotaMailboxListener.java  | 9 ++++-----
 .../search/elasticsearch/json/QuotaRatioToElasticSearchJson.java | 4 ++--
 .../elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java    | 5 ++---
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
index 1a14c0c..1b48778 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
@@ -24,7 +24,6 @@ import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.apache.james.backends.es.v6.ElasticSearchIndexer;
-import org.apache.james.core.User;
 import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.Group;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -60,11 +59,11 @@ public class ElasticSearchQuotaMailboxListener implements MailboxListener.GroupM
 
     @Override
     public void event(Event event) throws IOException {
-        handleEvent(event.getUser(), (QuotaUsageUpdatedEvent) event);
+        handleEvent((QuotaUsageUpdatedEvent) event);
     }
 
-    private void handleEvent(User user, QuotaUsageUpdatedEvent event) throws IOException {
-        indexer.index(user.asString(),
-            quotaRatioToElasticSearchJson.convertToJson(user.asString(), event));
+    private void handleEvent(QuotaUsageUpdatedEvent event) throws IOException {
+        indexer.index(event.getUser().asString(),
+            quotaRatioToElasticSearchJson.convertToJson(event));
     }
 }
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
index 12f9629..b9b0937 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
@@ -39,9 +39,9 @@ public class QuotaRatioToElasticSearchJson {
         this.mapper.registerModule(new Jdk8Module());
     }
 
-    public String convertToJson(String user, QuotaUsageUpdatedEvent event) throws JsonProcessingException {
+    public String convertToJson(QuotaUsageUpdatedEvent event) throws JsonProcessingException {
         return mapper.writeValueAsString(QuotaRatioAsJson.builder()
-                .user(user)
+                .user(event.getUser().asString())
                 .domain(event.getQuotaRoot().getDomain().map(Domain::asString))
                 .quotaRatio(QuotaRatio.from(event.getSizeQuota(), event.getCountQuota()))
                 .build());
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
index 4f42c92..83e7b28 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
@@ -50,7 +50,7 @@ class QuotaRatioToElasticSearchJsonTest {
             .instant(Instant.now())
             .build();
         QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson = new QuotaRatioToElasticSearchJson();
-        String convertToJson = quotaRatioToElasticSearchJson.convertToJson(user, event);
+        String convertToJson = quotaRatioToElasticSearchJson.convertToJson(event);
 
         assertThatJson(convertToJson)
             .when(IGNORING_ARRAY_ORDER)
@@ -69,9 +69,8 @@ class QuotaRatioToElasticSearchJsonTest {
             .instant(Instant.now())
             .build();
 
-
         QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson = new QuotaRatioToElasticSearchJson();
-        String convertToJson = quotaRatioToElasticSearchJson.convertToJson(user, event);
+        String convertToJson = quotaRatioToElasticSearchJson.convertToJson( event);
 
         assertThatJson(convertToJson)
             .when(IGNORING_ARRAY_ORDER)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 03/09: JAMES-2765 Backend-ES v6 should still include ScrollIterable

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e77a6b87c3e7ac469ddbb081863d6b110c555dcb
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu May 16 17:27:33 2019 +0700

    JAMES-2765 Backend-ES v6 should still include ScrollIterable
---
 .../james/backends/es/v6/IndexCreationFactory.java |   2 +-
 .../backends/es/v6/search/ListenerToFuture.java    |  51 ++++++
 .../backends/es/v6/search/ScrollIterable.java      |  91 ++++++++++
 .../backends/es/v6/search/ScrollIterableTest.java  | 197 +++++++++++++++++++++
 4 files changed, 340 insertions(+), 1 deletion(-)

diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/IndexCreationFactory.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/IndexCreationFactory.java
index 2cba4ad..111bbcf 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/IndexCreationFactory.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/IndexCreationFactory.java
@@ -42,7 +42,7 @@ import com.google.common.collect.ImmutableList;
 
 public class IndexCreationFactory {
 
-    static class AliasSpecificationStep {
+    public static class AliasSpecificationStep {
         private final int nbShards;
         private final int nbReplica;
         private final IndexName indexName;
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ListenerToFuture.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ListenerToFuture.java
new file mode 100644
index 0000000..1ae43b5
--- /dev/null
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ListenerToFuture.java
@@ -0,0 +1,51 @@
+/****************************************************************
+ * 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.v6.search;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.elasticsearch.action.ActionListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ListenerToFuture<T> implements ActionListener<T> {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ListenerToFuture.class);
+
+    private CompletableFuture<T> future;
+
+    public ListenerToFuture() {
+        this.future = new CompletableFuture<>();
+    }
+
+    @Override
+    public void onResponse(T t) {
+        future.complete(t);
+    }
+
+    @Override
+    public void onFailure(Exception e) {
+        LOGGER.warn("Error while waiting ElasticSearch query execution: ", e);
+        future.completeExceptionally(e);
+    }
+
+    public CompletableFuture<T> getFuture() {
+        return future;
+    }
+}
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
new file mode 100644
index 0000000..a5e4a70
--- /dev/null
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
@@ -0,0 +1,91 @@
+/****************************************************************
+ * 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.v6.search;
+
+import java.util.Iterator;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import org.apache.james.util.streams.Iterators;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.action.search.SearchScrollRequest;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.unit.TimeValue;
+
+public class ScrollIterable implements Iterable<SearchResponse> {
+    private static final TimeValue TIMEOUT = new TimeValue(60000);
+
+    private final RestHighLevelClient client;
+    private final SearchRequest searchRequest;
+
+    public ScrollIterable(RestHighLevelClient client, SearchRequest searchRequest) {
+        this.client = client;
+        this.searchRequest = searchRequest;
+    }
+
+    @Override
+    public Iterator<SearchResponse> iterator() {
+        return new ScrollIterator(client, searchRequest);
+    }
+
+    public Stream<SearchResponse> stream() {
+        return Iterators.toStream(iterator());
+    }
+
+    public static class ScrollIterator implements Iterator<SearchResponse> {
+        private final RestHighLevelClient client;
+        private CompletableFuture<SearchResponse> searchResponseFuture;
+
+        ScrollIterator(RestHighLevelClient client, SearchRequest searchRequest) {
+            this.client = client;
+            ListenerToFuture<SearchResponse> listener = new ListenerToFuture<>();
+            client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);
+
+            this.searchResponseFuture = listener.getFuture();
+        }
+
+        @Override
+        public boolean hasNext() {
+            SearchResponse join = searchResponseFuture.join();
+            return !allSearchResponsesConsumed(join);
+        }
+
+        @Override
+        public SearchResponse next() {
+            SearchResponse result = searchResponseFuture.join();
+            ListenerToFuture<SearchResponse> listener = new ListenerToFuture<>();
+            client.scrollAsync(
+                new SearchScrollRequest()
+                    .scrollId(result.getScrollId())
+                    .scroll(TIMEOUT),
+                RequestOptions.DEFAULT,
+                listener);
+            searchResponseFuture = listener.getFuture();
+            return result;
+        }
+
+        private boolean allSearchResponsesConsumed(SearchResponse searchResponse) {
+            return searchResponse.getHits().getHits().length == 0;
+        }
+    }
+
+}
diff --git a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
new file mode 100644
index 0000000..c9709b1
--- /dev/null
+++ b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
@@ -0,0 +1,197 @@
+/****************************************************************
+ * 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.v6.search;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.james.backends.es.v6.ClientProvider;
+import org.apache.james.backends.es.v6.DockerElasticSearchRule;
+import org.apache.james.backends.es.v6.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v6.IndexCreationFactory;
+import org.apache.james.backends.es.v6.IndexName;
+import org.apache.james.backends.es.v6.ReadAliasName;
+import org.apache.james.backends.es.v6.TypeName;
+import org.awaitility.Duration;
+import org.awaitility.core.ConditionFactory;
+import org.elasticsearch.action.index.IndexRequest;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ScrollIterableTest {
+
+    private static final TimeValue TIMEOUT = new TimeValue(6000);
+    private static final int SIZE = 2;
+    private static final String MESSAGE = "message";
+    private static final IndexName INDEX_NAME = new IndexName("index");
+    private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
+    private static final TypeName TYPE_NAME = new TypeName("messages");
+
+    private static final ConditionFactory WAIT_CONDITION = await().timeout(Duration.FIVE_SECONDS);
+
+    @Rule
+    public DockerElasticSearchRule elasticSearch = new DockerElasticSearchRule();
+    private ClientProvider clientProvider;
+
+    @Before
+    public void setUp() {
+        clientProvider = elasticSearch.clientProvider();
+        new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
+            .useIndex(INDEX_NAME)
+            .addAlias(ALIAS_NAME)
+            .createIndexAndAliases(clientProvider.get());
+        elasticSearch.awaitForElasticSearch();
+    }
+
+    @Test
+    public void scrollIterableShouldWorkWhenEmpty() throws Exception {
+        try (RestHighLevelClient client = clientProvider.get()) {
+            SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
+                .types(TYPE_NAME.getValue())
+                .scroll(TIMEOUT)
+                .source(new SearchSourceBuilder()
+                    .query(QueryBuilders.matchAllQuery())
+                    .size(SIZE));
+
+            assertThat(new ScrollIterable(client, searchRequest))
+                .isEmpty();
+        }
+    }
+
+    @Test
+    public void scrollIterableShouldWorkWhenOneElement() throws Exception {
+        try (RestHighLevelClient client = clientProvider.get()) {
+            String id = "1";
+            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id)
+                    .source(MESSAGE, "Sample message"),
+                RequestOptions.DEFAULT);
+
+            elasticSearch.awaitForElasticSearch();
+            WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id));
+
+            SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
+                .types(TYPE_NAME.getValue())
+                .scroll(TIMEOUT)
+                .source(new SearchSourceBuilder()
+                    .query(QueryBuilders.matchAllQuery())
+                    .size(SIZE));
+
+            assertThat(convertToIdList(new ScrollIterable(client, searchRequest)))
+                .containsOnly(id);
+        }
+    }
+
+    @Test
+    public void scrollIterableShouldWorkWhenSizeElement() throws Exception {
+        try (RestHighLevelClient client = clientProvider.get()) {
+            String id1 = "1";
+            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id1)
+                    .source(MESSAGE, "Sample message"),
+                RequestOptions.DEFAULT);
+
+            String id2 = "2";
+            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id2)
+                    .source(MESSAGE, "Sample message"),
+                RequestOptions.DEFAULT);
+
+            elasticSearch.awaitForElasticSearch();
+            WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id1, id2));
+
+            SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
+                .types(TYPE_NAME.getValue())
+                .scroll(TIMEOUT)
+                .source(new SearchSourceBuilder()
+                    .query(QueryBuilders.matchAllQuery())
+                    .size(SIZE));
+
+            assertThat(convertToIdList(new ScrollIterable(client, searchRequest)))
+                .containsOnly(id1, id2);
+        }
+    }
+
+    @Test
+    public void scrollIterableShouldWorkWhenMoreThanSizeElement() throws Exception {
+        try (RestHighLevelClient client = clientProvider.get()) {
+            String id1 = "1";
+            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id1)
+                    .source(MESSAGE, "Sample message"),
+                RequestOptions.DEFAULT);
+
+            String id2 = "2";
+            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id2)
+                    .source(MESSAGE, "Sample message"),
+                RequestOptions.DEFAULT);
+
+            String id3 = "3";
+            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id3)
+                    .source(MESSAGE, "Sample message"),
+                RequestOptions.DEFAULT);
+
+            elasticSearch.awaitForElasticSearch();
+            WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id1, id2, id3));
+
+            SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
+                .types(TYPE_NAME.getValue())
+                .scroll(TIMEOUT)
+                .source(new SearchSourceBuilder()
+                    .query(QueryBuilders.matchAllQuery())
+                    .size(SIZE));
+
+            assertThat(convertToIdList(new ScrollIterable(client, searchRequest)))
+                .containsOnly(id1, id2, id3);
+        }
+    }
+
+    private List<String> convertToIdList(ScrollIterable scrollIterable) {
+        return scrollIterable.stream()
+            .flatMap(searchResponse -> Arrays.stream(searchResponse.getHits().getHits()))
+            .map(SearchHit::getId)
+            .collect(Collectors.toList());
+    }
+
+    private void hasIdsInIndex(RestHighLevelClient client, String... ids) throws IOException {
+        SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
+            .types(TYPE_NAME.getValue())
+            .scroll(TIMEOUT)
+            .source(new SearchSourceBuilder()
+                .query(QueryBuilders.matchAllQuery()));
+
+        SearchHit[] hits = client.search(searchRequest, RequestOptions.DEFAULT)
+            .getHits()
+            .getHits();
+
+        assertThat(hits)
+            .extracting(SearchHit::getId)
+            .contains(ids);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 09/09: JAMES-2765 TimeOut values was implicit

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 48e0e838e8b3ed33cdc605b2f59abe959dd415bc
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sat May 18 16:44:56 2019 +0700

    JAMES-2765 TimeOut values was implicit
---
 .../main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java | 2 +-
 .../java/org/apache/james/backends/es/v6/search/ScrollIterable.java     | 2 +-
 .../java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java | 2 +-
 .../james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java    | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
index 6cf3d4a..c2e5a7d 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
@@ -45,7 +45,7 @@ import com.google.common.base.Preconditions;
 public class ElasticSearchIndexer {
     private static final int DEBUG_MAX_LENGTH_CONTENT = 1000;
     private static final int DEFAULT_BATCH_SIZE = 100;
-    private static final TimeValue TIMEOUT = new TimeValue(60000);
+    private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchIndexer.class);
 
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
index 78ed814..475343a 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
@@ -33,7 +33,7 @@ import org.elasticsearch.client.RestHighLevelClient;
 import org.elasticsearch.common.unit.TimeValue;
 
 public class ScrollIterable implements Iterable<SearchResponse> {
-    private static final TimeValue TIMEOUT = new TimeValue(60000);
+    private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
 
     private final RestHighLevelClient client;
     private final SearchRequest searchRequest;
diff --git a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
index 3840181..2d239aa 100644
--- a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
+++ b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
@@ -50,7 +50,7 @@ import org.junit.Test;
 
 public class ScrollIterableTest {
 
-    private static final TimeValue TIMEOUT = new TimeValue(6000);
+    private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
     private static final int SIZE = 2;
     private static final String MESSAGE = "message";
     private static final IndexName INDEX_NAME = new IndexName("index");
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
index 80d2342..19cefef 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
@@ -43,7 +43,7 @@ import org.elasticsearch.search.sort.SortOrder;
 import com.github.steveash.guavate.Guavate;
 
 public class ElasticSearchQuotaSearcher implements QuotaSearcher {
-    private static final TimeValue TIMEOUT = new TimeValue(60000);
+    private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
 
     private final RestHighLevelClient client;
     private final AliasName readAlias;


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 02/09: JAMES-2765 Duplicate apache-james-mailbox-quota-search-elasticsearch

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 323762fcf1df8495dec6f60622050d98f3b501ac
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu May 16 16:26:13 2019 +0700

    JAMES-2765 Duplicate apache-james-mailbox-quota-search-elasticsearch
    
    Duplicated project will be migrated to ES-6
---
 .../plugin/quota-search-elasticsearch-v6/pom.xml   | 142 +++++++++++++++++++
 .../ElasticSearchQuotaConfiguration.java           | 152 +++++++++++++++++++++
 .../elasticsearch/ElasticSearchQuotaSearcher.java  |  91 ++++++++++++
 .../search/elasticsearch/QuotaQueryConverter.java  | 103 ++++++++++++++
 .../QuotaRatioElasticSearchConstants.java          |  37 +++++
 .../elasticsearch/QuotaRatioMappingFactory.java    |  67 +++++++++
 .../QuotaSearchIndexCreationUtil.java              |  55 ++++++++
 .../events/ElasticSearchQuotaMailboxListener.java  |  70 ++++++++++
 .../elasticsearch/json/JsonMessageConstants.java   |  28 ++++
 .../elasticsearch/json/QuotaRatioAsJson.java       | 120 ++++++++++++++++
 .../json/QuotaRatioToElasticSearchJson.java        |  49 +++++++
 .../ElasticSearchQuotaConfigurationTest.java       | 104 ++++++++++++++
 ...lasticSearchQuotaSearchTestSystemExtension.java | 110 +++++++++++++++
 .../ElasticSearchQuotaSearcherTest.java            |  28 ++++
 .../elasticsearch/QuotaQueryConverterTest.java     |  83 +++++++++++
 .../ElasticSearchQuotaMailboxListenerTest.java     | 105 ++++++++++++++
 .../elasticsearch/json/QuotaRatioAsJsonTest.java   | 107 +++++++++++++++
 .../json/QuotaRatioToElasticSearchJsonTest.java    |  80 +++++++++++
 .../src/test/resources/quotaRatio.json             |   1 +
 .../src/test/resources/quotaRatioNoDomain.json     |   1 +
 mailbox/pom.xml                                    |   1 +
 21 files changed, 1534 insertions(+)

diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml b/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml
new file mode 100644
index 0000000..c1eeca6
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-james-mailbox</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.4.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>apache-james-mailbox-quota-search-elasticsearch-v6</artifactId>
+    <name>Apache James :: Mailbox :: Plugin :: Quota Search :: ElasticSearch :: v6</name>
+    <description>Apache James Mailbox ElasticSearch v6 implementation for quota search</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-backends-es</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-backends-es</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-quota-search</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>apache-james-mailbox-quota-search</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jdk8</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-migrationsupport</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-assertj</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
new file mode 100644
index 0000000..c14f339
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
@@ -0,0 +1,152 @@
+/*
+ * 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.quota.search.elasticsearch;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.backends.es.IndexName;
+import org.apache.james.backends.es.ReadAliasName;
+import org.apache.james.backends.es.WriteAliasName;
+
+public class ElasticSearchQuotaConfiguration {
+
+    public static class Builder {
+
+        private Optional<IndexName> indexQuotaRatioName;
+        private Optional<ReadAliasName> readAliasQuotaRatioName;
+        private Optional<WriteAliasName> writeAliasQuotaRatioName;
+
+        public Builder() {
+            indexQuotaRatioName = Optional.empty();
+            readAliasQuotaRatioName = Optional.empty();
+            writeAliasQuotaRatioName = Optional.empty();
+        }
+
+        public Builder indexQuotaRatioName(IndexName indexQuotaRatioName) {
+            return indexQuotaRatioName(Optional.of(indexQuotaRatioName));
+        }
+
+        public Builder indexQuotaRatioName(Optional<IndexName> indexQuotaRatioName) {
+            this.indexQuotaRatioName = indexQuotaRatioName;
+            return this;
+        }
+
+        public Builder readAliasQuotaRatioName(ReadAliasName readAliasQuotaRatioName) {
+            return readAliasQuotaRatioName(Optional.of(readAliasQuotaRatioName));
+        }
+
+        public Builder readAliasQuotaRatioName(Optional<ReadAliasName> readAliasQuotaRatioName) {
+            this.readAliasQuotaRatioName = readAliasQuotaRatioName;
+            return this;
+        }
+
+        public Builder writeAliasQuotaRatioName(WriteAliasName writeAliasQuotaRatioName) {
+            return writeAliasQuotaRatioName(Optional.of(writeAliasQuotaRatioName));
+        }
+
+        public Builder writeAliasQuotaRatioName(Optional<WriteAliasName> writeAliasQuotaRatioName) {
+            this.writeAliasQuotaRatioName = writeAliasQuotaRatioName;
+            return this;
+        }
+
+
+        public ElasticSearchQuotaConfiguration build() {
+            return new ElasticSearchQuotaConfiguration(
+                indexQuotaRatioName.orElse(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_INDEX),
+                readAliasQuotaRatioName.orElse(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS),
+                writeAliasQuotaRatioName.orElse(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS));
+        }
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final String ELASTICSEARCH_INDEX_QUOTA_RATIO_NAME = "elasticsearch.index.quota.ratio.name";
+    public static final String ELASTICSEARCH_ALIAS_READ_QUOTA_RATIO_NAME = "elasticsearch.alias.read.quota.ratio.name";
+    public static final String ELASTICSEARCH_ALIAS_WRITE_QUOTA_RATIO_NAME = "elasticsearch.alias.write.quota.ratio.name";
+
+    public static final ElasticSearchQuotaConfiguration DEFAULT_CONFIGURATION = builder().build();
+
+    public static ElasticSearchQuotaConfiguration fromProperties(Configuration configuration) throws ConfigurationException {
+        return builder()
+            .indexQuotaRatioName(computeQuotaSearchIndexName(configuration))
+            .readAliasQuotaRatioName(computeQuotaSearchReadAlias(configuration))
+            .writeAliasQuotaRatioName(computeQuotaSearchWriteAlias(configuration))
+            .build();
+    }
+
+    public static Optional<IndexName> computeQuotaSearchIndexName(Configuration configuration) {
+        return Optional.ofNullable(configuration.getString(ELASTICSEARCH_INDEX_QUOTA_RATIO_NAME))
+            .map(IndexName::new);
+    }
+
+    public static Optional<WriteAliasName> computeQuotaSearchWriteAlias(Configuration configuration) {
+        return Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_WRITE_QUOTA_RATIO_NAME))
+            .map(WriteAliasName::new);
+    }
+
+    public static Optional<ReadAliasName> computeQuotaSearchReadAlias(Configuration configuration) {
+        return Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_READ_QUOTA_RATIO_NAME))
+                .map(ReadAliasName::new);
+    }
+
+    private final IndexName indexQuotaRatioName;
+    private final ReadAliasName readAliasQuotaRatioName;
+    private final WriteAliasName writeAliasQuotaRatioName;
+
+    private ElasticSearchQuotaConfiguration(IndexName indexQuotaRatioName, ReadAliasName readAliasQuotaRatioName, WriteAliasName writeAliasQuotaRatioName) {
+        this.indexQuotaRatioName = indexQuotaRatioName;
+        this.readAliasQuotaRatioName = readAliasQuotaRatioName;
+        this.writeAliasQuotaRatioName = writeAliasQuotaRatioName;
+    }
+
+    public IndexName getIndexQuotaRatioName() {
+        return indexQuotaRatioName;
+    }
+
+    public ReadAliasName getReadAliasQuotaRatioName() {
+        return readAliasQuotaRatioName;
+    }
+
+    public WriteAliasName getWriteAliasQuotaRatioName() {
+        return writeAliasQuotaRatioName;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof ElasticSearchQuotaConfiguration) {
+            ElasticSearchQuotaConfiguration that = (ElasticSearchQuotaConfiguration) o;
+
+            return Objects.equals(this.indexQuotaRatioName, that.indexQuotaRatioName)
+                && Objects.equals(this.readAliasQuotaRatioName, that.readAliasQuotaRatioName)
+                && Objects.equals(this.writeAliasQuotaRatioName, that.writeAliasQuotaRatioName);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(indexQuotaRatioName, readAliasQuotaRatioName);
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
new file mode 100644
index 0000000..21d55a8
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
@@ -0,0 +1,91 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import static org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE;
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.apache.james.backends.es.AliasName;
+import org.apache.james.backends.es.ReadAliasName;
+import org.apache.james.backends.es.search.ScrollIterable;
+import org.apache.james.core.User;
+import org.apache.james.quota.search.QuotaQuery;
+import org.apache.james.quota.search.QuotaSearcher;
+import org.elasticsearch.action.search.SearchRequestBuilder;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.search.sort.SortBuilders;
+import org.elasticsearch.search.sort.SortOrder;
+
+import com.github.steveash.guavate.Guavate;
+
+public class ElasticSearchQuotaSearcher implements QuotaSearcher {
+    private static final TimeValue TIMEOUT = new TimeValue(60000);
+
+    private final Client client;
+    private final AliasName readAlias;
+    private final QuotaQueryConverter quotaQueryConverter;
+
+    public ElasticSearchQuotaSearcher(Client client, ReadAliasName readAlias) {
+        this.client = client;
+        this.readAlias = readAlias;
+        this.quotaQueryConverter = new QuotaQueryConverter();
+    }
+
+    @Override
+    public List<User> search(QuotaQuery query) {
+        Stream<User> results = new ScrollIterable(client, prepareSearch(query))
+            .stream()
+            .flatMap(searchResponse -> Arrays.stream(searchResponse.getHits()
+                .getHits()))
+            .map(hit -> hit.field(USER))
+            .map(field -> (String) field.getValue())
+            .map(User::fromUsername)
+            .skip(query.getOffset().getValue());
+
+        return query.getLimit().getValue()
+            .map(results::limit)
+            .orElse(results)
+            .collect(Guavate.toImmutableList());
+    }
+
+    public SearchRequestBuilder prepareSearch(QuotaQuery query) {
+        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(readAlias.getValue())
+            .setTypes(QUOTA_RATIO_TYPE.getValue())
+            .setScroll(TIMEOUT)
+            .addFields(USER)
+            .setQuery(quotaQueryConverter.from(query));
+
+        query.getLimit()
+            .getValue()
+            .ifPresent(searchRequestBuilder::setSize);
+
+        searchRequestBuilder.addSort(
+            SortBuilders.fieldSort(USER)
+                .order(SortOrder.ASC));
+
+        return searchRequestBuilder;
+    }
+
+}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
new file mode 100644
index 0000000..b02d8ac
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
@@ -0,0 +1,103 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.DOMAIN;
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
+import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.apache.james.quota.search.QuotaClause;
+import org.apache.james.quota.search.QuotaClause.And;
+import org.apache.james.quota.search.QuotaClause.HasDomain;
+import org.apache.james.quota.search.QuotaClause.LessThan;
+import org.apache.james.quota.search.QuotaClause.MoreThan;
+import org.apache.james.quota.search.QuotaQuery;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.RangeQueryBuilder;
+import org.elasticsearch.index.query.TermQueryBuilder;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+
+public class QuotaQueryConverter {
+    private final Map<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> clauseConverter;
+
+    public QuotaQueryConverter() {
+        Builder<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> builder = ImmutableMap.builder();
+        
+        builder.put(HasDomain.class, this::convertHasDomain);
+        builder.put(And.class, this::disableNestedAnd);
+        builder.put(MoreThan.class, this::convertMoreThan);
+        builder.put(LessThan.class, this::convertLessThan);
+
+        clauseConverter = builder.build();
+    }
+
+    public QueryBuilder from(QuotaQuery query) {
+        List<QuotaClause> clauses = query.getClause().getClauses();
+        if (clauses.isEmpty()) {
+            return matchAllQuery();
+        }
+        if (clauses.size() == 1) {
+            return singleClauseAsESQuery(clauses.get(0));
+        }
+        
+        return clausesAsAndESQuery(clauses);
+    }
+
+    private BoolQueryBuilder clausesAsAndESQuery(List<QuotaClause> clauses) {
+        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
+        clauses.stream()
+            .map(this::singleClauseAsESQuery)
+            .forEach(boolQueryBuilder::must);
+        return boolQueryBuilder;
+    }
+
+    private QueryBuilder disableNestedAnd(QuotaClause clause) {
+        throw new IllegalArgumentException("Nested \"And\" clauses are not supported");
+    }
+
+    private TermQueryBuilder convertHasDomain(QuotaClause clause) {
+        HasDomain hasDomain = (HasDomain) clause;
+        return termQuery(DOMAIN, hasDomain.getDomain().asString());
+    }
+
+    private RangeQueryBuilder convertMoreThan(QuotaClause clause) {
+        MoreThan moreThan = (MoreThan) clause;
+        return rangeQuery(QUOTA_RATIO).gte(moreThan.getQuotaBoundary().getRatio());
+    }
+
+    private RangeQueryBuilder convertLessThan(QuotaClause clause) {
+        LessThan lessThan = (LessThan) clause;
+        return rangeQuery(QUOTA_RATIO).lte(lessThan.getQuotaBoundary().getRatio());
+    }
+
+    private QueryBuilder singleClauseAsESQuery(QuotaClause clause) {
+        return clauseConverter.get(clause.getClass()).apply(clause);
+    }
+
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
new file mode 100644
index 0000000..e3ceadd
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
@@ -0,0 +1,37 @@
+/*
+ * 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.quota.search.elasticsearch;
+
+import org.apache.james.backends.es.IndexName;
+import org.apache.james.backends.es.ReadAliasName;
+import org.apache.james.backends.es.TypeName;
+import org.apache.james.backends.es.WriteAliasName;
+
+public interface QuotaRatioElasticSearchConstants {
+
+    interface InjectionNames {
+        String QUOTA_RATIO = "quotaRatio";
+    }
+
+    WriteAliasName DEFAULT_QUOTA_RATIO_WRITE_ALIAS = new WriteAliasName("quota_ratio_write_alias");
+    ReadAliasName DEFAULT_QUOTA_RATIO_READ_ALIAS = new ReadAliasName("quota_ratio_read_alias");
+    IndexName DEFAULT_QUOTA_RATIO_INDEX = new IndexName("quota_ratio_v1");
+    TypeName QUOTA_RATIO_TYPE = new TypeName("quota_ratio");
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
new file mode 100644
index 0000000..128f1d1
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
@@ -0,0 +1,67 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import static org.apache.james.backends.es.NodeMappingFactory.DOUBLE;
+import static org.apache.james.backends.es.NodeMappingFactory.INDEX;
+import static org.apache.james.backends.es.NodeMappingFactory.NOT_ANALYZED;
+import static org.apache.james.backends.es.NodeMappingFactory.PROPERTIES;
+import static org.apache.james.backends.es.NodeMappingFactory.STRING;
+import static org.apache.james.backends.es.NodeMappingFactory.TYPE;
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.DOMAIN;
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER;
+import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
+
+import java.io.IOException;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+
+public class QuotaRatioMappingFactory {
+
+    public static XContentBuilder getMappingContent() {
+        try {
+            return jsonBuilder()
+                .startObject()
+
+                    .startObject(QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE.getValue())
+                        .startObject(PROPERTIES)
+
+                            .startObject(USER)
+                                .field(TYPE, STRING)
+                                .field(INDEX, NOT_ANALYZED)
+                            .endObject()
+
+                            .startObject(DOMAIN)
+                                .field(TYPE, STRING)
+                                .field(INDEX, NOT_ANALYZED)
+                            .endObject()
+
+                            .startObject(QUOTA_RATIO)
+                                .field(TYPE, DOUBLE)
+                            .endObject()
+                        .endObject()
+                    .endObject()
+                .endObject();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
new file mode 100644
index 0000000..f546230
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import org.apache.james.backends.es.AliasName;
+import org.apache.james.backends.es.ElasticSearchConfiguration;
+import org.apache.james.backends.es.IndexCreationFactory;
+import org.apache.james.backends.es.IndexName;
+import org.apache.james.backends.es.NodeMappingFactory;
+import org.elasticsearch.client.Client;
+
+public class QuotaSearchIndexCreationUtil {
+
+    public static Client prepareClient(Client client,
+                                       AliasName readAlias,
+                                       AliasName writeAlias,
+                                       IndexName indexName,
+                                       ElasticSearchConfiguration configuration) {
+
+        return NodeMappingFactory.applyMapping(
+            new IndexCreationFactory(configuration)
+                .useIndex(indexName)
+                .addAlias(readAlias)
+                .addAlias(writeAlias)
+                .createIndexAndAliases(client),
+            indexName,
+            QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE,
+            QuotaRatioMappingFactory.getMappingContent());
+    }
+
+    public static Client prepareDefaultClient(Client client, ElasticSearchConfiguration configuration) {
+        return prepareClient(client,
+            QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS,
+            QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
+            QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_INDEX,
+            configuration);
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
new file mode 100644
index 0000000..2b828f2
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
@@ -0,0 +1,70 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.events;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.core.User;
+import org.apache.james.mailbox.events.Event;
+import org.apache.james.mailbox.events.Group;
+import org.apache.james.mailbox.events.MailboxListener;
+import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
+import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public class ElasticSearchQuotaMailboxListener implements MailboxListener.GroupMailboxListener {
+    public static class ElasticSearchQuotaMailboxListenerGroup extends Group {
+    }
+
+    private static final Group GROUP = new ElasticSearchQuotaMailboxListenerGroup();
+
+    private final ElasticSearchIndexer indexer;
+    private final QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson;
+
+    @Inject
+    public ElasticSearchQuotaMailboxListener(
+        @Named(QuotaRatioElasticSearchConstants.InjectionNames.QUOTA_RATIO) ElasticSearchIndexer indexer,
+        QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson) {
+        this.indexer = indexer;
+        this.quotaRatioToElasticSearchJson = quotaRatioToElasticSearchJson;
+    }
+
+    @Override
+    public Group getDefaultGroup() {
+        return GROUP;
+    }
+
+    @Override
+    public boolean isHandling(Event event) {
+        return event instanceof QuotaUsageUpdatedEvent;
+    }
+
+    @Override
+    public void event(Event event) throws JsonProcessingException {
+        handleEvent(event.getUser(), (QuotaUsageUpdatedEvent) event);
+    }
+
+    private void handleEvent(User user, QuotaUsageUpdatedEvent event) throws JsonProcessingException {
+        indexer.index(user.asString(),
+            quotaRatioToElasticSearchJson.convertToJson(user.asString(), event));
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java
new file mode 100644
index 0000000..8f930ff
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.json;
+
+public interface JsonMessageConstants {
+
+    String USER = "user";
+    String DOMAIN = "domain";
+    String QUOTA_RATIO = "quotaRatio";
+
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java
new file mode 100644
index 0000000..4084727
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java
@@ -0,0 +1,120 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.json;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.james.mailbox.model.QuotaRatio;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public class QuotaRatioAsJson {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+
+        private String user;
+        private Optional<String> domain;
+        private QuotaRatio quotaRatio;
+
+        private Builder() {
+            domain = Optional.empty();
+        }
+
+        public Builder user(String user) {
+            this.user = user;
+            return this;
+        }
+
+        public Builder domain(Optional<String> domain) {
+            this.domain = domain;
+            return this;
+        }
+
+        public Builder quotaRatio(QuotaRatio quotaRatio) {
+            this.quotaRatio = quotaRatio;
+            return this;
+        }
+
+        public QuotaRatioAsJson build() {
+            Preconditions.checkState(!Strings.isNullOrEmpty(user), "'user' is mandatory");
+            Preconditions.checkNotNull(quotaRatio, "'quotaRatio' is mandatory");
+
+            return new QuotaRatioAsJson(user, domain, quotaRatio);
+        }
+    }
+
+    private final String user;
+    private final Optional<String> domain;
+    private final QuotaRatio quotaRatio;
+
+    private QuotaRatioAsJson(String user, Optional<String> domain, QuotaRatio quotaRatio) {
+        this.user = user;
+        this.domain = domain;
+        this.quotaRatio = quotaRatio;
+    }
+
+    @JsonProperty(JsonMessageConstants.USER)
+    public String getUser() {
+        return user;
+    }
+
+    @JsonProperty(JsonMessageConstants.DOMAIN)
+    public Optional<String> getDomain() {
+        return domain;
+    }
+
+    @JsonProperty(JsonMessageConstants.QUOTA_RATIO)
+    public double getMaxQuotaRatio() {
+        return quotaRatio.max();
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof QuotaRatioAsJson) {
+            QuotaRatioAsJson that = (QuotaRatioAsJson) o;
+
+            return Objects.equals(this.quotaRatio, that.quotaRatio)
+                && Objects.equals(this.user, that.user)
+                && Objects.equals(this.domain, that.domain);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(user, domain, quotaRatio);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("quotaRatio", quotaRatio)
+            .add("user", user)
+            .add("domain", domain)
+            .toString();
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
new file mode 100644
index 0000000..12f9629
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
@@ -0,0 +1,49 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.json;
+
+import javax.inject.Inject;
+
+import org.apache.james.core.Domain;
+import org.apache.james.mailbox.events.MailboxListener.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.model.QuotaRatio;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+
+public class QuotaRatioToElasticSearchJson {
+
+    private final ObjectMapper mapper;
+
+    @Inject
+    public QuotaRatioToElasticSearchJson() {
+        this.mapper = new ObjectMapper();
+        this.mapper.registerModule(new Jdk8Module());
+    }
+
+    public String convertToJson(String user, QuotaUsageUpdatedEvent event) throws JsonProcessingException {
+        return mapper.writeValueAsString(QuotaRatioAsJson.builder()
+                .user(user)
+                .domain(event.getQuotaRoot().getDomain().map(Domain::asString))
+                .quotaRatio(QuotaRatio.from(event.getSizeQuota(), event.getCountQuota()))
+                .build());
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
new file mode 100644
index 0000000..a57a10e
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.quota.search.elasticsearch;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.james.backends.es.IndexName;
+import org.apache.james.backends.es.ReadAliasName;
+import org.apache.james.backends.es.WriteAliasName;
+import org.junit.Test;
+
+public class ElasticSearchQuotaConfigurationTest {
+
+    @Test
+    public void getReadAliasQuotaRatioNameShouldReturnConfiguredValue() throws ConfigurationException {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        String name = "name";
+        configuration.addProperty("elasticsearch.alias.read.quota.ratio.name", name);
+        configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+        ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
+
+        assertThat(elasticSearchConfiguration.getReadAliasQuotaRatioName())
+            .isEqualTo(new ReadAliasName(name));
+    }
+
+    @Test
+    public void getReadAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+        ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
+
+        assertThat(elasticSearchConfiguration.getReadAliasQuotaRatioName())
+            .isEqualTo(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS);
+    }
+
+    @Test
+    public void getWriteAliasQuotaRatioNameShouldReturnConfiguredValue() throws ConfigurationException {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        String name = "name";
+        configuration.addProperty("elasticsearch.alias.write.quota.ratio.name", name);
+        configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+        ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
+
+        assertThat(elasticSearchConfiguration.getWriteAliasQuotaRatioName())
+            .isEqualTo(new WriteAliasName(name));
+    }
+
+    @Test
+    public void getWriteAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+        ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
+
+        assertThat(elasticSearchConfiguration.getWriteAliasQuotaRatioName())
+            .isEqualTo(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS);
+    }
+
+    @Test
+    public void getIndexQuotaRatioNameShouldReturnConfiguredValue() throws ConfigurationException {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        String name = "name";
+        configuration.addProperty("elasticsearch.index.quota.ratio.name", name);
+        configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+        ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
+
+        assertThat(elasticSearchConfiguration.getIndexQuotaRatioName())
+            .isEqualTo(new IndexName(name));
+    }
+
+    @Test
+    public void getIndexQuotaRatioNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+        configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
+
+        ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
+
+        assertThat(elasticSearchConfiguration.getIndexQuotaRatioName())
+            .isEqualTo(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_INDEX);
+    }
+}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
new file mode 100644
index 0000000..5e63c46
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
@@ -0,0 +1,110 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import org.apache.james.backends.es.DockerElasticSearch;
+import org.apache.james.backends.es.DockerElasticSearchSingleton;
+import org.apache.james.backends.es.ElasticSearchConfiguration;
+import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.store.quota.QuotaComponents;
+import org.apache.james.quota.search.QuotaSearchTestSystem;
+import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
+import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
+import org.apache.james.user.memory.MemoryUsersRepository;
+import org.apache.james.util.concurrent.NamedThreadFactory;
+import org.elasticsearch.client.Client;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+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;
+
+public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterResolver, BeforeEachCallback, AfterEachCallback {
+
+    private final DockerElasticSearch elasticSearch = DockerElasticSearchSingleton.INSTANCE;
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return (parameterContext.getParameter().getType() == QuotaSearchTestSystem.class);
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        try {
+            Client client = QuotaSearchIndexCreationUtil.prepareDefaultClient(
+                elasticSearch.clientProvider().get(),
+                ElasticSearchConfiguration.builder()
+                    .addHost(elasticSearch.getTcpHost())
+                    .build());
+
+            InMemoryIntegrationResources resources = InMemoryIntegrationResources.defaultResources();
+
+            MemoryUsersRepository usersRepository = MemoryUsersRepository.withVirtualHosting();
+
+            DNSService dnsService = mock(DNSService.class);
+            MemoryDomainList domainList = new MemoryDomainList(dnsService);
+            usersRepository.setDomainList(domainList);
+
+            ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
+            ElasticSearchQuotaMailboxListener listener = new ElasticSearchQuotaMailboxListener(
+                new ElasticSearchIndexer(client, Executors.newSingleThreadExecutor(threadFactory),
+                    QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
+                    QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE),
+                new QuotaRatioToElasticSearchJson());
+
+            resources.getMailboxManager().getEventBus().register(listener);
+
+            QuotaComponents quotaComponents = resources.getMailboxManager().getQuotaComponents();
+
+            return new QuotaSearchTestSystem(
+                quotaComponents.getMaxQuotaManager(),
+                resources.getMailboxManager(),
+                quotaComponents.getQuotaManager(),
+                resources.getDefaultUserQuotaRootResolver(),
+                new ElasticSearchQuotaSearcher(client,
+                    QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS),
+                usersRepository,
+                domainList,
+                resources.getCurrentQuotaManager(),
+                () -> elasticSearch.awaitForElasticSearch());
+        } catch (Exception e) {
+            throw new ParameterResolutionException("Error while resolving parameter", e);
+        }
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext context) throws Exception {
+        elasticSearch.start();
+    }
+
+    @Override
+    public void afterEach(ExtensionContext context) {
+        elasticSearch.cleanUpData();
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
new file mode 100644
index 0000000..ad26532
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import org.apache.james.quota.search.QuotaSearcherContract;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(ElasticSearchQuotaSearchTestSystemExtension.class)
+public class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
+
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java
new file mode 100644
index 0000000..86daa88
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java
@@ -0,0 +1,83 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch;
+
+import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
+import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+
+import org.apache.james.core.Domain;
+import org.apache.james.quota.search.QuotaBoundary;
+import org.apache.james.quota.search.QuotaQuery;
+import org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class QuotaQueryConverterTest {
+    private QuotaQueryConverter testee;
+
+    @BeforeEach
+    void setup() {
+        testee = new QuotaQueryConverter();
+    }
+
+    @Test
+    void fromShouldReturnMatchAllWhenEmptyClauses() {
+        QuotaQuery query = QuotaQuery.builder().build();
+        QueryBuilder expected = matchAllQuery();
+
+        QueryBuilder actual = testee.from(query);
+
+        assertThat(actual).isEqualToComparingFieldByField(expected);
+    }
+
+    @Test
+    void fromShouldReturnDomainMatchWhenOnlyDomain() {
+        QuotaQuery query = QuotaQuery.builder().hasDomain(Domain.of("my.tld")).build();
+        QueryBuilder expected = termQuery(JsonMessageConstants.DOMAIN, "my.tld");
+
+        QueryBuilder actual = testee.from(query);
+
+        assertThat(actual).isEqualToComparingFieldByField(expected);
+    }
+
+    @Test
+    void fromShouldReturnQuotaRatioMatchWhenLessThan() {
+        QuotaQuery query = QuotaQuery.builder().lessThan(new QuotaBoundary(0.1)).build();
+        QueryBuilder expected = rangeQuery(QUOTA_RATIO).lte(0.1);
+
+        QueryBuilder actual = testee.from(query);
+
+        assertThat(actual).isEqualToComparingFieldByField(expected);
+    }
+
+    @Test
+    void fromShouldReturnQuotaRatioMatchWhenMoreThan() {
+        QuotaQuery query = QuotaQuery.builder().moreThan(new QuotaBoundary(0.1)).build();
+        QueryBuilder expected = rangeQuery(QUOTA_RATIO).gte(0.1);
+
+        QueryBuilder actual = testee.from(query);
+
+        assertThat(actual).isEqualToComparingFieldByField(expected);
+    }
+
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
new file mode 100644
index 0000000..d3f7811
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
@@ -0,0 +1,105 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.events;
+
+import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.BOB_USER;
+import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.NOW;
+import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.QUOTAROOT;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
+import static org.mockito.Mockito.mock;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import org.apache.james.backends.es.DockerElasticSearchRule;
+import org.apache.james.backends.es.ElasticSearchConfiguration;
+import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.mailbox.events.Event;
+import org.apache.james.mailbox.events.Group;
+import org.apache.james.mailbox.quota.QuotaFixture.Counts;
+import org.apache.james.mailbox.quota.QuotaFixture.Sizes;
+import org.apache.james.mailbox.store.event.EventFactory;
+import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
+import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
+import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
+import org.apache.james.util.concurrent.NamedThreadFactory;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.client.Client;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ElasticSearchQuotaMailboxListenerTest {
+    private static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
+
+    private static final int BATCH_SIZE = 1;
+    private static final Event DUMB_EVENT = mock(Event.class);
+
+    @Rule
+    public DockerElasticSearchRule elasticSearch = new DockerElasticSearchRule();
+    private ElasticSearchQuotaMailboxListener quotaMailboxListener;
+    private Client client;
+
+    @Before
+    public void setUp() {
+        client = QuotaSearchIndexCreationUtil.prepareDefaultClient(
+            elasticSearch.clientProvider().get(),
+            ElasticSearchConfiguration.builder()
+                .addHost(elasticSearch.getTcpHost())
+                .build());
+
+        ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
+        quotaMailboxListener = new ElasticSearchQuotaMailboxListener(
+            new ElasticSearchIndexer(client,
+                Executors.newSingleThreadExecutor(threadFactory),
+                QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
+                QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE,
+                BATCH_SIZE),
+            new QuotaRatioToElasticSearchJson());
+    }
+
+    @Test
+    public void deserializeElasticSearchQuotaMailboxListenerGroup() throws Exception {
+        assertThat(Group.deserialize("org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener$ElasticSearchQuotaMailboxListenerGroup"))
+            .isEqualTo(new ElasticSearchQuotaMailboxListener.ElasticSearchQuotaMailboxListenerGroup());
+    }
+
+    @Test
+    public void eventShouldIndexEventWhenQuotaEvent() throws Exception {
+        quotaMailboxListener.event(EventFactory.quotaUpdated()
+            .eventId(EVENT_ID)
+            .user(BOB_USER)
+            .quotaRoot(QUOTAROOT)
+            .quotaCount(Counts._52_PERCENT)
+            .quotaSize(Sizes._55_PERCENT)
+            .instant(NOW)
+            .build());
+
+        elasticSearch.awaitForElasticSearch();
+
+        SearchResponse searchResponse = client.prepareSearch(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS.getValue())
+            .setTypes(QuotaRatioElasticSearchConstants.QUOTA_RATIO_TYPE.getValue())
+            .setQuery(matchAllQuery())
+            .execute()
+            .get();
+        assertThat(searchResponse.getHits().totalHits()).isEqualTo(1);
+    }
+}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
new file mode 100644
index 0000000..b2c6411
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
@@ -0,0 +1,107 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.json;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.apache.james.core.quota.QuotaCount;
+import org.apache.james.core.quota.QuotaSize;
+import org.apache.james.mailbox.model.Quota;
+import org.apache.james.mailbox.model.QuotaRatio;
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class QuotaRatioAsJsonTest {
+
+    private static final Quota<QuotaSize> QUOTA_SIZE = Quota.<QuotaSize>builder()
+            .used(QuotaSize.size(15))
+            .computedLimit(QuotaSize.size(60))
+            .build();
+    private static final Quota<QuotaCount> QUOTA_COUNT = Quota.<QuotaCount>builder()
+            .used(QuotaCount.count(1))
+            .computedLimit(QuotaCount.count(2))
+            .build();
+
+    @Test
+    public void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(QuotaRatioAsJson.class)
+            .verify();
+    }
+
+    @Test
+    public void buildShouldThrownWhenUserIsNull() {
+        assertThatThrownBy(() -> QuotaRatioAsJson.builder()
+                .build())
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void buildShouldThrownWhenUserIsEmpty() {
+        assertThatThrownBy(() -> QuotaRatioAsJson.builder()
+                .user("")
+                .build())
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void buildShouldThrownWhenQuotaRatioIsNull() {
+        assertThatThrownBy(() -> QuotaRatioAsJson.builder()
+                .user("user")
+                .build())
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void getDomainShouldReturnEmptyWhenNone() {
+        QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
+            .user("user")
+            .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
+            .build();
+
+        assertThat(quotaRatioAsJson.getDomain()).isEmpty();
+    }
+
+    @Test
+    public void getDomainShouldReturnTheDomainWhenGiven() {
+        String domain = "domain";
+        QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
+            .user("user")
+            .domain(Optional.of(domain))
+            .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
+            .build();
+
+        assertThat(quotaRatioAsJson.getDomain()).contains(domain);
+    }
+
+    @Test
+    public void getMaxQuotaRatioShouldReturnTheMaxQuotaRatio() {
+        String domain = "domain";
+        QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
+            .user("user")
+            .domain(Optional.of(domain))
+            .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
+            .build();
+
+        assertThat(quotaRatioAsJson.getMaxQuotaRatio()).isEqualTo(0.5);
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
new file mode 100644
index 0000000..4f42c92
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
@@ -0,0 +1,80 @@
+/****************************************************************
+ * 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.quota.search.elasticsearch.json;
+
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Optional;
+
+import org.apache.james.core.Domain;
+import org.apache.james.core.User;
+import org.apache.james.mailbox.events.Event;
+import org.apache.james.mailbox.events.MailboxListener.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.QuotaFixture;
+import org.apache.james.mailbox.store.event.EventFactory;
+import org.apache.james.util.ClassLoaderUtils;
+import org.junit.jupiter.api.Test;
+
+class QuotaRatioToElasticSearchJsonTest {
+    private static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
+
+    @Test
+    void quotaRatioShouldBeWellConvertedToJson() throws IOException {
+        String user = "user@domain.org";
+        QuotaUsageUpdatedEvent event = EventFactory.quotaUpdated()
+            .eventId(EVENT_ID)
+            .user(User.fromUsername(user))
+            .quotaRoot(QuotaRoot.quotaRoot(user, Optional.of(Domain.of("domain.org"))))
+            .quotaCount(QuotaFixture.Counts._52_PERCENT)
+            .quotaSize(QuotaFixture.Sizes._55_PERCENT)
+            .instant(Instant.now())
+            .build();
+        QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson = new QuotaRatioToElasticSearchJson();
+        String convertToJson = quotaRatioToElasticSearchJson.convertToJson(user, event);
+
+        assertThatJson(convertToJson)
+            .when(IGNORING_ARRAY_ORDER)
+            .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("quotaRatio.json"));
+    }
+
+    @Test
+    void quotaRatioShouldBeWellConvertedToJsonWhenNoDomain() throws IOException {
+        String user = "user";
+        QuotaUsageUpdatedEvent event = EventFactory.quotaUpdated()
+            .eventId(EVENT_ID)
+            .user(User.fromUsername(user))
+            .quotaRoot(QuotaRoot.quotaRoot(user, Optional.empty()))
+            .quotaCount(QuotaFixture.Counts._52_PERCENT)
+            .quotaSize(QuotaFixture.Sizes._55_PERCENT)
+            .instant(Instant.now())
+            .build();
+
+
+        QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson = new QuotaRatioToElasticSearchJson();
+        String convertToJson = quotaRatioToElasticSearchJson.convertToJson(user, event);
+
+        assertThatJson(convertToJson)
+            .when(IGNORING_ARRAY_ORDER)
+            .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("quotaRatioNoDomain.json"));
+    }
+}
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatio.json b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatio.json
new file mode 100644
index 0000000..8b39489
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatio.json
@@ -0,0 +1 @@
+{"user":"user@domain.org","domain":"domain.org","quotaRatio":0.55}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatioNoDomain.json b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatioNoDomain.json
new file mode 100644
index 0000000..b3e2f2e
--- /dev/null
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatioNoDomain.json
@@ -0,0 +1 @@
+{"user":"user","domain":null,"quotaRatio":0.55}
\ No newline at end of file
diff --git a/mailbox/pom.xml b/mailbox/pom.xml
index 7e3dcd2..449bb35 100644
--- a/mailbox/pom.xml
+++ b/mailbox/pom.xml
@@ -57,6 +57,7 @@
         <module>plugin/quota-mailing-memory</module>
         <module>plugin/quota-search</module>
         <module>plugin/quota-search-elasticsearch</module>
+        <module>plugin/quota-search-elasticsearch-v6</module>
         <module>plugin/quota-search-scanning</module>
         <module>plugin/spamassassin</module>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 04/09: JAMES-2765 Type naming is no more supported in ES 6

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0ad1f0d061b73c584f73f65bc84847af49109e18
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri May 17 11:58:02 2019 +0700

    JAMES-2765 Type naming is no more supported in ES 6
---
 .../james/backends/es/v6/ElasticSearchIndexer.java | 23 +++++++---------
 .../james/backends/es/v6/NodeMappingFactory.java   | 12 ++++----
 .../org/apache/james/backends/es/v6/TypeName.java  | 32 ----------------------
 .../backends/es/v6/DockerElasticSearchRule.java    |  4 +++
 .../backends/es/v6/ElasticSearchIndexerTest.java   | 10 +------
 .../backends/es/v6/NodeMappingFactoryTest.java     | 14 +++-------
 .../backends/es/v6/search/ScrollIterableTest.java  | 32 +++++++++++++---------
 7 files changed, 44 insertions(+), 83 deletions(-)

diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
index 79adb69..9689c1a 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
@@ -51,23 +51,19 @@ public class ElasticSearchIndexer {
 
     private final RestHighLevelClient client;
     private final AliasName aliasName;
-    private final TypeName typeName;
     private final int batchSize;
 
     public ElasticSearchIndexer(RestHighLevelClient client,
-                                WriteAliasName aliasName,
-                                TypeName typeName) {
-        this(client, aliasName, typeName, DEFAULT_BATCH_SIZE);
+                                WriteAliasName aliasName) {
+        this(client, aliasName, DEFAULT_BATCH_SIZE);
     }
 
     @VisibleForTesting
     public ElasticSearchIndexer(RestHighLevelClient client,
                                 WriteAliasName aliasName,
-                                TypeName typeName,
                                 int batchSize) {
         this.client = client;
         this.aliasName = aliasName;
-        this.typeName = typeName;
         this.batchSize = batchSize;
     }
 
@@ -77,7 +73,9 @@ public class ElasticSearchIndexer {
             LOGGER.debug("Indexing {}: {}", id, StringUtils.left(content, DEBUG_MAX_LENGTH_CONTENT));
         }
         return client.index(
-            new IndexRequest(aliasName.getValue(), typeName.getValue(), id)
+            new IndexRequest(aliasName.getValue())
+                .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                .id(id)
                 .source(content, XContentType.JSON),
             RequestOptions.DEFAULT);
     }
@@ -88,7 +86,7 @@ public class ElasticSearchIndexer {
             BulkRequest request = new BulkRequest();
             updatedDocumentParts.forEach(updatedDocumentPart -> request.add(
                 new UpdateRequest(aliasName.getValue(),
-                    typeName.getValue(),
+                    NodeMappingFactory.DEFAULT_MAPPING_NAME,
                     updatedDocumentPart.getId())
                 .doc(updatedDocumentPart.getUpdatedDocumentPart(), XContentType.JSON)));
             return Optional.of(client.bulk(request, RequestOptions.DEFAULT));
@@ -102,10 +100,9 @@ public class ElasticSearchIndexer {
         try {
             BulkRequest request = new BulkRequest();
             ids.forEach(id -> request.add(
-                new DeleteRequest(
-                    aliasName.getValue(),
-                    typeName.getValue(),
-                    id)));
+                new DeleteRequest(aliasName.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id)));
             return Optional.of(client.bulk(request, RequestOptions.DEFAULT));
         } catch (ValidationException e) {
             LOGGER.warn("Error while deleting index", e);
@@ -115,7 +112,7 @@ public class ElasticSearchIndexer {
 
     public void deleteAllMatchingQuery(QueryBuilder queryBuilder) {
         DeleteByQueryRequest request = new DeleteByQueryRequest(aliasName.getValue())
-            .setDocTypes(typeName.getValue())
+            .setDocTypes(NodeMappingFactory.DEFAULT_MAPPING_NAME)
             .setScroll(TIMEOUT)
             .setQuery(queryBuilder)
             .setBatchSize(batchSize);
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/NodeMappingFactory.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/NodeMappingFactory.java
index eda3c50..237f7fa 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/NodeMappingFactory.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/NodeMappingFactory.java
@@ -30,6 +30,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 
 public class NodeMappingFactory {
 
+    public static final String DEFAULT_MAPPING_NAME = "_doc";
     public static final String BOOLEAN = "boolean";
     public static final String TYPE = "type";
     public static final String LONG = "long";
@@ -38,6 +39,7 @@ public class NodeMappingFactory {
     public static final String NOT_ANALYZED = "not_analyzed";
     public static final String STRING = "string";
     public static final String TEXT = "text";
+    public static final String KEYWORD = "keyword";
     public static final String PROPERTIES = "properties";
     public static final String DATE = "date";
     public static final String FORMAT = "format";
@@ -50,14 +52,14 @@ public class NodeMappingFactory {
     public static final String SNOWBALL = "snowball";
     public static final String IGNORE_ABOVE = "ignore_above";
 
-    public static RestHighLevelClient applyMapping(RestHighLevelClient client, IndexName indexName, TypeName typeName, XContentBuilder mappingsSources) throws IOException {
-        if (!mappingAlreadyExist(client, indexName, typeName)) {
+    public static RestHighLevelClient applyMapping(RestHighLevelClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
+        if (!mappingAlreadyExist(client, indexName)) {
             createMapping(client, indexName, mappingsSources);
         }
         return client;
     }
 
-    public static boolean mappingAlreadyExist(RestHighLevelClient client, IndexName indexName, TypeName typeName) throws IOException {
+    public static boolean mappingAlreadyExist(RestHighLevelClient client, IndexName indexName) throws IOException {
         return Iterators.toStream(client.indices()
             .getMapping(
                 new GetMappingsRequest()
@@ -66,12 +68,10 @@ public class NodeMappingFactory {
             .mappings()
             .values()
             .iterator())
-            .anyMatch(mapping -> mapping.type().contains(typeName.getValue()));
+            .anyMatch(mappingMetaData -> !mappingMetaData.getSourceAsMap().isEmpty());
     }
 
     public static void createMapping(RestHighLevelClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
-        PutMappingRequest request = new PutMappingRequest(indexName.getValue())
-            .source(mappingsSources);
         client.indices().putMapping(
             new PutMappingRequest(indexName.getValue())
                 .source(mappingsSources),
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/TypeName.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/TypeName.java
deleted file mode 100644
index 7f3dbf7..0000000
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/TypeName.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
- * 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.v6;
-
-public class TypeName {
-    private final String value;
-
-    public TypeName(String value) {
-        this.value = value;
-    }
-
-    public String getValue() {
-        return value;
-    }
-}
diff --git a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/DockerElasticSearchRule.java b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/DockerElasticSearchRule.java
index e945e31..08d891b 100644
--- a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/DockerElasticSearchRule.java
+++ b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/DockerElasticSearchRule.java
@@ -42,4 +42,8 @@ public class DockerElasticSearchRule extends ExternalResource {
     public void awaitForElasticSearch() {
         dockerElasticSearch.awaitForElasticSearch();
     }
+
+    public DockerElasticSearch getDockerElasticSearch() {
+        return dockerElasticSearch;
+    }
 }
diff --git a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/ElasticSearchIndexerTest.java b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/ElasticSearchIndexerTest.java
index 08f02a2..3ca61c1 100644
--- a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/ElasticSearchIndexerTest.java
+++ b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/ElasticSearchIndexerTest.java
@@ -42,7 +42,6 @@ public class ElasticSearchIndexerTest {
     private static final int MINIMUM_BATCH_SIZE = 1;
     private static final IndexName INDEX_NAME = new IndexName("index_name");
     private static final WriteAliasName ALIAS_NAME = new WriteAliasName("alias_name");
-    private static final TypeName TYPE_NAME = new TypeName("type_name");
 
     @Rule
     public DockerElasticSearchRule elasticSearch = new DockerElasticSearchRule();
@@ -54,7 +53,7 @@ public class ElasticSearchIndexerTest {
             .useIndex(INDEX_NAME)
             .addAlias(ALIAS_NAME)
             .createIndexAndAliases(getESClient());
-        testee = new ElasticSearchIndexer(getESClient(), ALIAS_NAME, TYPE_NAME, MINIMUM_BATCH_SIZE);
+        testee = new ElasticSearchIndexer(getESClient(), ALIAS_NAME, MINIMUM_BATCH_SIZE);
     }
 
     private RestHighLevelClient getESClient() {
@@ -72,7 +71,6 @@ public class ElasticSearchIndexerTest {
         try (RestHighLevelClient client = getESClient()) {
             SearchResponse searchResponse = client.search(
                 new SearchRequest(INDEX_NAME.getValue())
-                    .types(TYPE_NAME.getValue())
                     .source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("message", "trying"))),
                 RequestOptions.DEFAULT);
             assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
@@ -99,7 +97,6 @@ public class ElasticSearchIndexerTest {
         try (RestHighLevelClient client = getESClient()) {
             SearchResponse searchResponse = client.search(
                 new SearchRequest(INDEX_NAME.getValue())
-                    .types(TYPE_NAME.getValue())
                     .source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("message", "mastering"))),
                 RequestOptions.DEFAULT);
             assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
@@ -108,7 +105,6 @@ public class ElasticSearchIndexerTest {
         try (RestHighLevelClient client = getESClient()) {
             SearchResponse searchResponse = client.search(
                 new SearchRequest(INDEX_NAME.getValue())
-                    .types(TYPE_NAME.getValue())
                     .source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("field", "unchanged"))),
                 RequestOptions.DEFAULT);
             assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
@@ -154,7 +150,6 @@ public class ElasticSearchIndexerTest {
             await().atMost(Duration.TEN_SECONDS)
                 .until(() -> client.search(
                         new SearchRequest(INDEX_NAME.getValue())
-                            .types(TYPE_NAME.getValue())
                             .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
                         RequestOptions.DEFAULT)
                     .getHits().getTotalHits() == 0);
@@ -186,7 +181,6 @@ public class ElasticSearchIndexerTest {
             await().atMost(Duration.TEN_SECONDS)
                 .until(() -> client.search(
                     new SearchRequest(INDEX_NAME.getValue())
-                        .types(TYPE_NAME.getValue())
                         .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
                     RequestOptions.DEFAULT)
                     .getHits().getTotalHits() == 1);
@@ -207,7 +201,6 @@ public class ElasticSearchIndexerTest {
         try (RestHighLevelClient client = getESClient()) {
             SearchResponse searchResponse = client.search(
                 new SearchRequest(INDEX_NAME.getValue())
-                    .types(TYPE_NAME.getValue())
                     .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
                 RequestOptions.DEFAULT);
             assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(0);
@@ -238,7 +231,6 @@ public class ElasticSearchIndexerTest {
         try (RestHighLevelClient client = getESClient()) {
             SearchResponse searchResponse = client.search(
                 new SearchRequest(INDEX_NAME.getValue())
-                    .types(TYPE_NAME.getValue())
                     .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
                 RequestOptions.DEFAULT);
             assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
diff --git a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/NodeMappingFactoryTest.java b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/NodeMappingFactoryTest.java
index 95207ff..86fad09 100644
--- a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/NodeMappingFactoryTest.java
+++ b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/NodeMappingFactoryTest.java
@@ -19,10 +19,9 @@
 
 package org.apache.james.backends.es.v6;
 
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 
-import org.elasticsearch.ElasticsearchStatusException;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.junit.Before;
 import org.junit.Rule;
@@ -32,7 +31,6 @@ public class NodeMappingFactoryTest {
     private static final String MESSAGE = "message";
     private static final IndexName INDEX_NAME = new IndexName("index");
     private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-    private static final TypeName TYPE_NAME = new TypeName("type");
 
     @Rule
     public DockerElasticSearchRule elasticSearch = new DockerElasticSearchRule();
@@ -47,7 +45,6 @@ public class NodeMappingFactoryTest {
             .createIndexAndAliases(clientProvider.get());
         NodeMappingFactory.applyMapping(clientProvider.get(),
             INDEX_NAME,
-            TYPE_NAME,
             getMappingsSources());
     }
 
@@ -55,24 +52,21 @@ public class NodeMappingFactoryTest {
     public void applyMappingShouldNotThrowWhenCalledSeveralTime() throws Exception {
         NodeMappingFactory.applyMapping(clientProvider.get(),
             INDEX_NAME,
-            TYPE_NAME,
             getMappingsSources());
     }
 
     @Test
-    public void applyMappingShouldThrowWhenTryingIndexerChanges() throws Exception {
+    public void applyMappingShouldNotThrowWhenIncrementalChanges() throws Exception {
         NodeMappingFactory.applyMapping(clientProvider.get(),
             INDEX_NAME,
-            TYPE_NAME,
             getMappingsSources());
 
         elasticSearch.awaitForElasticSearch();
 
-        assertThatThrownBy(() ->NodeMappingFactory.applyMapping(clientProvider.get(),
+        assertThatCode(() ->NodeMappingFactory.applyMapping(clientProvider.get(),
             INDEX_NAME,
-            TYPE_NAME,
             getOtherMappingsSources()))
-        .isInstanceOf(ElasticsearchStatusException.class);
+        .doesNotThrowAnyException();
     }
 
     private XContentBuilder getMappingsSources() throws Exception {
diff --git a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
index c9709b1..3840181 100644
--- a/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
+++ b/backends-common/elasticsearch-v6/src/test/java/org/apache/james/backends/es/v6/search/ScrollIterableTest.java
@@ -32,8 +32,8 @@ import org.apache.james.backends.es.v6.DockerElasticSearchRule;
 import org.apache.james.backends.es.v6.ElasticSearchConfiguration;
 import org.apache.james.backends.es.v6.IndexCreationFactory;
 import org.apache.james.backends.es.v6.IndexName;
+import org.apache.james.backends.es.v6.NodeMappingFactory;
 import org.apache.james.backends.es.v6.ReadAliasName;
-import org.apache.james.backends.es.v6.TypeName;
 import org.awaitility.Duration;
 import org.awaitility.core.ConditionFactory;
 import org.elasticsearch.action.index.IndexRequest;
@@ -55,7 +55,6 @@ public class ScrollIterableTest {
     private static final String MESSAGE = "message";
     private static final IndexName INDEX_NAME = new IndexName("index");
     private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-    private static final TypeName TYPE_NAME = new TypeName("messages");
 
     private static final ConditionFactory WAIT_CONDITION = await().timeout(Duration.FIVE_SECONDS);
 
@@ -77,7 +76,6 @@ public class ScrollIterableTest {
     public void scrollIterableShouldWorkWhenEmpty() throws Exception {
         try (RestHighLevelClient client = clientProvider.get()) {
             SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
-                .types(TYPE_NAME.getValue())
                 .scroll(TIMEOUT)
                 .source(new SearchSourceBuilder()
                     .query(QueryBuilders.matchAllQuery())
@@ -92,7 +90,9 @@ public class ScrollIterableTest {
     public void scrollIterableShouldWorkWhenOneElement() throws Exception {
         try (RestHighLevelClient client = clientProvider.get()) {
             String id = "1";
-            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id)
+            client.index(new IndexRequest(INDEX_NAME.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id)
                     .source(MESSAGE, "Sample message"),
                 RequestOptions.DEFAULT);
 
@@ -100,7 +100,6 @@ public class ScrollIterableTest {
             WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id));
 
             SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
-                .types(TYPE_NAME.getValue())
                 .scroll(TIMEOUT)
                 .source(new SearchSourceBuilder()
                     .query(QueryBuilders.matchAllQuery())
@@ -115,12 +114,16 @@ public class ScrollIterableTest {
     public void scrollIterableShouldWorkWhenSizeElement() throws Exception {
         try (RestHighLevelClient client = clientProvider.get()) {
             String id1 = "1";
-            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id1)
+            client.index(new IndexRequest(INDEX_NAME.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id1)
                     .source(MESSAGE, "Sample message"),
                 RequestOptions.DEFAULT);
 
             String id2 = "2";
-            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id2)
+            client.index(new IndexRequest(INDEX_NAME.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id2)
                     .source(MESSAGE, "Sample message"),
                 RequestOptions.DEFAULT);
 
@@ -128,7 +131,6 @@ public class ScrollIterableTest {
             WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id1, id2));
 
             SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
-                .types(TYPE_NAME.getValue())
                 .scroll(TIMEOUT)
                 .source(new SearchSourceBuilder()
                     .query(QueryBuilders.matchAllQuery())
@@ -143,17 +145,23 @@ public class ScrollIterableTest {
     public void scrollIterableShouldWorkWhenMoreThanSizeElement() throws Exception {
         try (RestHighLevelClient client = clientProvider.get()) {
             String id1 = "1";
-            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id1)
+            client.index(new IndexRequest(INDEX_NAME.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id1)
                     .source(MESSAGE, "Sample message"),
                 RequestOptions.DEFAULT);
 
             String id2 = "2";
-            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id2)
+            client.index(new IndexRequest(INDEX_NAME.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id2)
                     .source(MESSAGE, "Sample message"),
                 RequestOptions.DEFAULT);
 
             String id3 = "3";
-            client.index(new IndexRequest(INDEX_NAME.getValue(), TYPE_NAME.getValue(), id3)
+            client.index(new IndexRequest(INDEX_NAME.getValue())
+                    .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
+                    .id(id3)
                     .source(MESSAGE, "Sample message"),
                 RequestOptions.DEFAULT);
 
@@ -161,7 +169,6 @@ public class ScrollIterableTest {
             WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id1, id2, id3));
 
             SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
-                .types(TYPE_NAME.getValue())
                 .scroll(TIMEOUT)
                 .source(new SearchSourceBuilder()
                     .query(QueryBuilders.matchAllQuery())
@@ -181,7 +188,6 @@ public class ScrollIterableTest {
 
     private void hasIdsInIndex(RestHighLevelClient client, String... ids) throws IOException {
         SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
-            .types(TYPE_NAME.getValue())
             .scroll(TIMEOUT)
             .source(new SearchSourceBuilder()
                 .query(QueryBuilders.matchAllQuery()));


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 06/09: JAMES-2765 DeleteByQueryActionListener can be replaced by ListenerToFuture

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0430ef2a0a3ad70d6d2c89768d61eb5fa14c00a7
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sat May 18 12:33:17 2019 +0700

    JAMES-2765 DeleteByQueryActionListener can be replaced by ListenerToFuture
---
 .../es/v6/DeleteByQueryActionListener.java         | 39 ----------------------
 .../james/backends/es/v6/ElasticSearchIndexer.java |  2 +-
 .../es/v6/{search => }/ListenerToFuture.java       |  2 +-
 .../backends/es/v6/search/ScrollIterable.java      |  1 +
 4 files changed, 3 insertions(+), 41 deletions(-)

diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/DeleteByQueryActionListener.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/DeleteByQueryActionListener.java
deleted file mode 100644
index d89a9ec..0000000
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/DeleteByQueryActionListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************
- * 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.v6;
-
-import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.index.reindex.BulkByScrollResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteByQueryActionListener implements ActionListener<BulkByScrollResponse> {
-    private static final Logger LOGGER = LoggerFactory.getLogger(DeleteByQueryActionListener.class);
-
-    @Override
-    public void onResponse(BulkByScrollResponse bulkByScrollResponse) {
-
-    }
-
-    @Override
-    public void onFailure(Exception e) {
-        LOGGER.warn("Error during the ES delete by query operation: ", e);
-    }
-}
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
index 9689c1a..6cf3d4a 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ElasticSearchIndexer.java
@@ -117,7 +117,7 @@ public class ElasticSearchIndexer {
             .setQuery(queryBuilder)
             .setBatchSize(batchSize);
 
-        client.deleteByQueryAsync(request, RequestOptions.DEFAULT, new DeleteByQueryActionListener());
+        client.deleteByQueryAsync(request, RequestOptions.DEFAULT, new ListenerToFuture<>());
     }
 
     private void checkArgument(String content) {
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ListenerToFuture.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ListenerToFuture.java
similarity index 97%
rename from backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ListenerToFuture.java
rename to backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ListenerToFuture.java
index 1ae43b5..11f751e 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ListenerToFuture.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/ListenerToFuture.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.backends.es.v6.search;
+package org.apache.james.backends.es.v6;
 
 import java.util.concurrent.CompletableFuture;
 
diff --git a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
index a5e4a70..78ed814 100644
--- a/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
+++ b/backends-common/elasticsearch-v6/src/main/java/org/apache/james/backends/es/v6/search/ScrollIterable.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Stream;
 
+import org.apache.james.backends.es.v6.ListenerToFuture;
 import org.apache.james.util.streams.Iterators;
 import org.elasticsearch.action.search.SearchRequest;
 import org.elasticsearch.action.search.SearchResponse;


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 08/09: JAMES-2765 Solve some IntelliJ warnings

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2d4c2c3830b5955523c2e1a7b627dc8855eb4f7f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sat May 18 16:42:04 2019 +0700

    JAMES-2765 Solve some IntelliJ warnings
---
 .../elasticsearch/ElasticSearchQuotaConfiguration.java  |  3 +--
 .../elasticsearch/ElasticSearchQuotaSearcher.java       |  2 +-
 .../ElasticSearchQuotaConfigurationTest.java            | 17 ++++++++---------
 .../ElasticSearchQuotaSearchTestSystemExtension.java    |  2 +-
 .../search/elasticsearch/json/QuotaRatioAsJsonTest.java | 16 ++++++++--------
 5 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
index 53e6d9b..2c0e6a1 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
@@ -23,7 +23,6 @@ import java.util.Objects;
 import java.util.Optional;
 
 import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
 import org.apache.james.backends.es.v6.IndexName;
 import org.apache.james.backends.es.v6.ReadAliasName;
 import org.apache.james.backends.es.v6.WriteAliasName;
@@ -88,7 +87,7 @@ public class ElasticSearchQuotaConfiguration {
 
     public static final ElasticSearchQuotaConfiguration DEFAULT_CONFIGURATION = builder().build();
 
-    public static ElasticSearchQuotaConfiguration fromProperties(Configuration configuration) throws ConfigurationException {
+    public static ElasticSearchQuotaConfiguration fromProperties(Configuration configuration) {
         return builder()
             .indexQuotaRatioName(computeQuotaSearchIndexName(configuration))
             .readAliasQuotaRatioName(computeQuotaSearchReadAlias(configuration))
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
index 55ce6c9..80d2342 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
@@ -71,7 +71,7 @@ public class ElasticSearchQuotaSearcher implements QuotaSearcher {
             .collect(Guavate.toImmutableList());
     }
 
-    public SearchRequest prepareSearch(QuotaQuery query) {
+    private SearchRequest prepareSearch(QuotaQuery query) {
         SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
             .query(quotaQueryConverter.from(query))
             .sort(SortBuilders.fieldSort(USER)
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
index 2027436..7966d8d 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
@@ -21,17 +21,16 @@ package org.apache.james.quota.search.elasticsearch;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.james.backends.es.v6.IndexName;
 import org.apache.james.backends.es.v6.ReadAliasName;
 import org.apache.james.backends.es.v6.WriteAliasName;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class ElasticSearchQuotaConfigurationTest {
+class ElasticSearchQuotaConfigurationTest {
 
     @Test
-    public void getReadAliasQuotaRatioNameShouldReturnConfiguredValue() throws ConfigurationException {
+    void getReadAliasQuotaRatioNameShouldReturnConfiguredValue() {
         PropertiesConfiguration configuration = new PropertiesConfiguration();
         String name = "name";
         configuration.addProperty("elasticsearch.alias.read.quota.ratio.name", name);
@@ -44,7 +43,7 @@ public class ElasticSearchQuotaConfigurationTest {
     }
 
     @Test
-    public void getReadAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
+    void getReadAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() {
         PropertiesConfiguration configuration = new PropertiesConfiguration();
         configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
@@ -55,7 +54,7 @@ public class ElasticSearchQuotaConfigurationTest {
     }
 
     @Test
-    public void getWriteAliasQuotaRatioNameShouldReturnConfiguredValue() throws ConfigurationException {
+    void getWriteAliasQuotaRatioNameShouldReturnConfiguredValue() {
         PropertiesConfiguration configuration = new PropertiesConfiguration();
         String name = "name";
         configuration.addProperty("elasticsearch.alias.write.quota.ratio.name", name);
@@ -68,7 +67,7 @@ public class ElasticSearchQuotaConfigurationTest {
     }
 
     @Test
-    public void getWriteAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
+    void getWriteAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() {
         PropertiesConfiguration configuration = new PropertiesConfiguration();
         configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
@@ -79,7 +78,7 @@ public class ElasticSearchQuotaConfigurationTest {
     }
 
     @Test
-    public void getIndexQuotaRatioNameShouldReturnConfiguredValue() throws ConfigurationException {
+    void getIndexQuotaRatioNameShouldReturnConfiguredValue() {
         PropertiesConfiguration configuration = new PropertiesConfiguration();
         String name = "name";
         configuration.addProperty("elasticsearch.index.quota.ratio.name", name);
@@ -92,7 +91,7 @@ public class ElasticSearchQuotaConfigurationTest {
     }
 
     @Test
-    public void getIndexQuotaRatioNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
+    void getIndexQuotaRatioNameShouldReturnDefaultValueWhenMissing() {
         PropertiesConfiguration configuration = new PropertiesConfiguration();
         configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
 
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
index a4194ca..054b845 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
@@ -93,7 +93,7 @@ public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterRes
     }
 
     @Override
-    public void beforeEach(ExtensionContext context) throws Exception {
+    public void beforeEach(ExtensionContext context) {
         elasticSearch.start();
     }
 
diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
index b2c6411..68ff7d9 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
@@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-public class QuotaRatioAsJsonTest {
+class QuotaRatioAsJsonTest {
 
     private static final Quota<QuotaSize> QUOTA_SIZE = Quota.<QuotaSize>builder()
             .used(QuotaSize.size(15))
@@ -43,20 +43,20 @@ public class QuotaRatioAsJsonTest {
             .build();
 
     @Test
-    public void shouldMatchBeanContract() {
+    void shouldMatchBeanContract() {
         EqualsVerifier.forClass(QuotaRatioAsJson.class)
             .verify();
     }
 
     @Test
-    public void buildShouldThrownWhenUserIsNull() {
+    void buildShouldThrownWhenUserIsNull() {
         assertThatThrownBy(() -> QuotaRatioAsJson.builder()
                 .build())
             .isInstanceOf(IllegalStateException.class);
     }
 
     @Test
-    public void buildShouldThrownWhenUserIsEmpty() {
+    void buildShouldThrownWhenUserIsEmpty() {
         assertThatThrownBy(() -> QuotaRatioAsJson.builder()
                 .user("")
                 .build())
@@ -64,7 +64,7 @@ public class QuotaRatioAsJsonTest {
     }
 
     @Test
-    public void buildShouldThrownWhenQuotaRatioIsNull() {
+    void buildShouldThrownWhenQuotaRatioIsNull() {
         assertThatThrownBy(() -> QuotaRatioAsJson.builder()
                 .user("user")
                 .build())
@@ -72,7 +72,7 @@ public class QuotaRatioAsJsonTest {
     }
 
     @Test
-    public void getDomainShouldReturnEmptyWhenNone() {
+    void getDomainShouldReturnEmptyWhenNone() {
         QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
             .user("user")
             .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
@@ -82,7 +82,7 @@ public class QuotaRatioAsJsonTest {
     }
 
     @Test
-    public void getDomainShouldReturnTheDomainWhenGiven() {
+    void getDomainShouldReturnTheDomainWhenGiven() {
         String domain = "domain";
         QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
             .user("user")
@@ -94,7 +94,7 @@ public class QuotaRatioAsJsonTest {
     }
 
     @Test
-    public void getMaxQuotaRatioShouldReturnTheMaxQuotaRatio() {
+    void getMaxQuotaRatioShouldReturnTheMaxQuotaRatio() {
         String domain = "domain";
         QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
             .user("user")


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org