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 bd16e73ea33dba86cb7a2a6f004218ee757652a2 Author: Tran Tien Duc <[email protected]> AuthorDate: Thu May 23 11:10:54 2019 +0700 JAMES-2767 replace old mailbox-quota-es module by the new one --- .../plugin/quota-search-elasticsearch-v6/pom.xml | 142 ------------------- .../ElasticSearchQuotaConfiguration.java | 151 --------------------- .../elasticsearch/ElasticSearchQuotaSearcher.java | 111 --------------- .../search/elasticsearch/QuotaQueryConverter.java | 103 -------------- .../QuotaRatioElasticSearchConstants.java | 35 ----- .../elasticsearch/QuotaRatioMappingFactory.java | 60 -------- .../QuotaSearchIndexCreationUtil.java | 56 -------- .../events/ElasticSearchQuotaMailboxListener.java | 69 ---------- .../elasticsearch/json/JsonMessageConstants.java | 28 ---- .../elasticsearch/json/QuotaRatioAsJson.java | 120 ---------------- .../json/QuotaRatioToElasticSearchJson.java | 49 ------- .../ElasticSearchQuotaConfigurationTest.java | 103 -------------- ...lasticSearchQuotaSearchTestSystemExtension.java | 104 -------------- .../ElasticSearchQuotaSearcherTest.java | 88 ------------ .../elasticsearch/QuotaQueryConverterTest.java | 83 ----------- .../ElasticSearchQuotaMailboxListenerTest.java | 103 -------------- .../elasticsearch/json/QuotaRatioAsJsonTest.java | 107 --------------- .../json/QuotaRatioToElasticSearchJsonTest.java | 79 ----------- .../src/test/resources/quotaRatio.json | 1 - .../src/test/resources/quotaRatioNoDomain.json | 1 - .../ElasticSearchQuotaConfiguration.java | 3 +- .../elasticsearch/ElasticSearchQuotaSearcher.java | 82 ++++++----- .../search/elasticsearch/QuotaQueryConverter.java | 6 +- .../QuotaRatioElasticSearchConstants.java | 2 - .../elasticsearch/QuotaRatioMappingFactory.java | 31 ++--- .../QuotaSearchIndexCreationUtil.java | 11 +- .../events/ElasticSearchQuotaMailboxListener.java | 15 +- .../json/QuotaRatioToElasticSearchJson.java | 4 +- .../ElasticSearchQuotaConfigurationTest.java | 17 ++- ...lasticSearchQuotaSearchTestSystemExtension.java | 20 +-- .../ElasticSearchQuotaSearcherTest.java | 62 ++++++++- .../ElasticSearchQuotaMailboxListenerTest.java | 44 +++--- .../elasticsearch/json/QuotaRatioAsJsonTest.java | 16 +-- .../json/QuotaRatioToElasticSearchJsonTest.java | 5 +- mailbox/pom.xml | 1 - 35 files changed, 189 insertions(+), 1723 deletions(-) diff --git a/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml b/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml deleted file mode 100644 index 7135337..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/pom.xml +++ /dev/null @@ -1,142 +0,0 @@ -<?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-v6</artifactId> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>apache-james-backends-es-v6</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 deleted file mode 100644 index 2c0e6a1..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java +++ /dev/null @@ -1,151 +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.quota.search.elasticsearch; - -import java.util.Objects; -import java.util.Optional; - -import org.apache.commons.configuration.Configuration; -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 { - - 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) { - 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 deleted file mode 100644 index e3f6ab5..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java +++ /dev/null @@ -1,111 +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.quota.search.elasticsearch; - -import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Stream; - -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.SearchRequest; -import org.elasticsearch.client.RequestOptions; -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; - -import com.github.steveash.guavate.Guavate; - -public class ElasticSearchQuotaSearcher implements QuotaSearcher { - private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1); - - private final RestHighLevelClient client; - private final AliasName readAlias; - private final QuotaQueryConverter quotaQueryConverter; - - public ElasticSearchQuotaSearcher(RestHighLevelClient client, ReadAliasName readAlias) { - this.client = client; - this.readAlias = readAlias; - this.quotaQueryConverter = new QuotaQueryConverter(); - } - - @Override - public List<User> search(QuotaQuery query) { - try { - return searchHits(query) - .map(SearchHit::getId) - .map(User::fromUsername) - .collect(Guavate.toImmutableList()); - } catch (IOException e) { - throw new RuntimeException("Unexpected exception while executing " + query, e); - } - } - - private Stream<SearchHit> searchHits(QuotaQuery query) throws IOException { - if (query.getLimit().isLimited()) { - return executeSingleSearch(query); - } else { - return executeScrolledSearch(query); - } - } - - private Stream<SearchHit> executeSingleSearch(QuotaQuery query) throws IOException { - SearchSourceBuilder searchSourceBuilder = searchSourceBuilder(query) - .from(query.getOffset().getValue()); - query.getLimit().getValue() - .ifPresent(searchSourceBuilder::size); - - SearchRequest searchRequest = new SearchRequest(readAlias.getValue()) - .types(NodeMappingFactory.DEFAULT_MAPPING_NAME) - .source(searchSourceBuilder); - - return Arrays.stream(client.search(searchRequest, RequestOptions.DEFAULT) - .getHits() - .getHits()); - } - - private Stream<SearchHit> executeScrolledSearch(QuotaQuery query) { - return new ScrollIterable(client, - new SearchRequest(readAlias.getValue()) - .types(NodeMappingFactory.DEFAULT_MAPPING_NAME) - .source(searchSourceBuilder(query)) - .scroll(TIMEOUT)) - .stream() - .flatMap(searchResponse -> Arrays.stream(searchResponse.getHits().getHits())) - .skip(query.getOffset().getValue()); - } - - private SearchSourceBuilder searchSourceBuilder(QuotaQuery query) { - return new SearchSourceBuilder() - .query(quotaQueryConverter.from(query)) - .sort(SortBuilders.fieldSort(USER).order(SortOrder.ASC)); - } -} \ 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 deleted file mode 100644 index a67d063..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java +++ /dev/null @@ -1,103 +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.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; - -class QuotaQueryConverter { - private final Map<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> clauseConverter; - - 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(); - } - - 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 deleted file mode 100644 index 43cb89e..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java +++ /dev/null @@ -1,35 +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.quota.search.elasticsearch; - -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 { - - 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"); -} 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 deleted file mode 100644 index 78d7aa3..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java +++ /dev/null @@ -1,60 +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.quota.search.elasticsearch; - -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; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; - -import java.io.IOException; - -import org.elasticsearch.common.xcontent.XContentBuilder; - -class QuotaRatioMappingFactory { - - public static XContentBuilder getMappingContent() { - try { - return jsonBuilder() - .startObject() - .startObject(PROPERTIES) - - .startObject(USER) - .field(TYPE, KEYWORD) - .endObject() - - .startObject(DOMAIN) - .field(TYPE, KEYWORD) - .endObject() - - .startObject(QUOTA_RATIO) - .field(TYPE, DOUBLE) - .endObject() - .endObject() - .endObject(); - } catch (IOException e) { - 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 deleted file mode 100644 index 3555b28..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java +++ /dev/null @@ -1,56 +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.quota.search.elasticsearch; - -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 RestHighLevelClient prepareClient(RestHighLevelClient client, - AliasName readAlias, - AliasName writeAlias, - IndexName indexName, - ElasticSearchConfiguration configuration) throws IOException { - - return NodeMappingFactory.applyMapping( - new IndexCreationFactory(configuration) - .useIndex(indexName) - .addAlias(readAlias) - .addAlias(writeAlias) - .createIndexAndAliases(client), - indexName, - QuotaRatioMappingFactory.getMappingContent()); - } - - 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, - 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 deleted file mode 100644 index 1b48778..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java +++ /dev/null @@ -1,69 +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.quota.search.elasticsearch.events; - -import java.io.IOException; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.apache.james.backends.es.v6.ElasticSearchIndexer; -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; - -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 IOException { - handleEvent((QuotaUsageUpdatedEvent) 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/JsonMessageConstants.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java deleted file mode 100644 index 8f930ff..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java +++ /dev/null @@ -1,28 +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.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 deleted file mode 100644 index 4084727..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java +++ /dev/null @@ -1,120 +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.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 deleted file mode 100644 index b9b0937..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java +++ /dev/null @@ -1,49 +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.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(QuotaUsageUpdatedEvent event) throws JsonProcessingException { - return mapper.writeValueAsString(QuotaRatioAsJson.builder() - .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/ElasticSearchQuotaConfigurationTest.java b/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java deleted file mode 100644 index 7966d8d..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java +++ /dev/null @@ -1,103 +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.quota.search.elasticsearch; - -import static org.assertj.core.api.Assertions.assertThat; - -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.jupiter.api.Test; - -class ElasticSearchQuotaConfigurationTest { - - @Test - void getReadAliasQuotaRatioNameShouldReturnConfiguredValue() { - 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 - void getReadAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() { - 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 - void getWriteAliasQuotaRatioNameShouldReturnConfiguredValue() { - 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 - void getWriteAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() { - 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 - void getIndexQuotaRatioNameShouldReturnConfiguredValue() { - 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 - void getIndexQuotaRatioNameShouldReturnDefaultValueWhenMissing() { - 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 deleted file mode 100644 index 054b845..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java +++ /dev/null @@ -1,104 +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.quota.search.elasticsearch; - -import static org.mockito.Mockito.mock; - -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; -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.elasticsearch.client.RestHighLevelClient; -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 { - RestHighLevelClient client = QuotaSearchIndexCreationUtil.prepareDefaultClient( - elasticSearch.clientProvider().get(), - ElasticSearchConfiguration.builder() - .addHost(elasticSearch.getHttpHost()) - .build()); - - InMemoryIntegrationResources resources = InMemoryIntegrationResources.defaultResources(); - - MemoryUsersRepository usersRepository = MemoryUsersRepository.withVirtualHosting(); - - DNSService dnsService = mock(DNSService.class); - MemoryDomainList domainList = new MemoryDomainList(dnsService); - usersRepository.setDomainList(domainList); - - ElasticSearchQuotaMailboxListener listener = new ElasticSearchQuotaMailboxListener( - new ElasticSearchIndexer(client, - QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS), - 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) { - 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 deleted file mode 100644 index 8c41989..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java +++ /dev/null @@ -1,88 +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.quota.search.elasticsearch; - -import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.stream.IntStream; - -import org.apache.james.core.User; -import org.apache.james.core.quota.QuotaSize; -import org.apache.james.quota.search.Limit; -import org.apache.james.quota.search.Offset; -import org.apache.james.quota.search.QuotaQuery; -import org.apache.james.quota.search.QuotaSearchTestSystem; -import org.apache.james.quota.search.QuotaSearcherContract; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -@ExtendWith(ElasticSearchQuotaSearchTestSystemExtension.class) -class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract { - @Test - void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimit(QuotaSearchTestSystem testSystem) throws Exception { - int userCount = 11; - testSystem.getDomainList().addDomain(SIMPSON_COM); - testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); - - IntStream.range(0, userCount) - .boxed() - .map(i -> User.fromLocalPartWithDomain("user" + i, SIMPSON_COM)) - .forEach(user -> provisionUser(testSystem, user)); - testSystem.await(); - - assertThat( - testSystem.getQuotaSearcher() - .search(QuotaQuery.builder() - .withLimit(Limit.unlimited()) - .build())) - .hasSize(userCount); - } - - @Test - void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimitWhenUsingOffset(QuotaSearchTestSystem testSystem) throws Exception { - int userCount = 12; - testSystem.getDomainList().addDomain(SIMPSON_COM); - testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); - - IntStream.range(0, userCount) - .boxed() - .map(i -> User.fromLocalPartWithDomain("user" + i, SIMPSON_COM)) - .forEach(user -> provisionUser(testSystem, user)); - testSystem.await(); - - assertThat( - testSystem.getQuotaSearcher() - .search(QuotaQuery.builder() - .withLimit(Limit.unlimited()) - .withOffset(Offset.of(1)) - .build())) - .hasSize(userCount - 1); - } - - private void provisionUser(QuotaSearchTestSystem testSystem, User user) { - try { - testSystem.getUsersRepository().addUser(user.asString(), PASSWORD); - appendMessage(testSystem, user, withSize(49)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} 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 deleted file mode 100644 index 86daa88..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java +++ /dev/null @@ -1,83 +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.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 deleted file mode 100644 index bfead33..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java +++ /dev/null @@ -1,103 +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.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 java.io.IOException; - -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; -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.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.search.SearchResponse; -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; - -public class ElasticSearchQuotaMailboxListenerTest { - private static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4"); - - private static final int BATCH_SIZE = 1; - - @Rule - public DockerElasticSearchRule elasticSearch = new DockerElasticSearchRule(); - private ElasticSearchQuotaMailboxListener quotaMailboxListener; - private RestHighLevelClient client; - - @Before - public void setUp() throws IOException { - client = elasticSearch.clientProvider().get(); - - QuotaSearchIndexCreationUtil.prepareDefaultClient(client, ElasticSearchConfiguration.builder() - .addHost(elasticSearch.getDockerElasticSearch().getHttpHost()) - .build()); - - quotaMailboxListener = new ElasticSearchQuotaMailboxListener( - new ElasticSearchIndexer(client, - QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS, - 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.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/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 deleted file mode 100644 index 68ff7d9..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java +++ /dev/null @@ -1,107 +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.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; - -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 - void shouldMatchBeanContract() { - EqualsVerifier.forClass(QuotaRatioAsJson.class) - .verify(); - } - - @Test - void buildShouldThrownWhenUserIsNull() { - assertThatThrownBy(() -> QuotaRatioAsJson.builder() - .build()) - .isInstanceOf(IllegalStateException.class); - } - - @Test - void buildShouldThrownWhenUserIsEmpty() { - assertThatThrownBy(() -> QuotaRatioAsJson.builder() - .user("") - .build()) - .isInstanceOf(IllegalStateException.class); - } - - @Test - void buildShouldThrownWhenQuotaRatioIsNull() { - assertThatThrownBy(() -> QuotaRatioAsJson.builder() - .user("user") - .build()) - .isInstanceOf(NullPointerException.class); - } - - @Test - void getDomainShouldReturnEmptyWhenNone() { - QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder() - .user("user") - .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT)) - .build(); - - assertThat(quotaRatioAsJson.getDomain()).isEmpty(); - } - - @Test - 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 - 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 deleted file mode 100644 index 83e7b28..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java +++ /dev/null @@ -1,79 +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.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 = "[email protected]"; - 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(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( 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 deleted file mode 100644 index 8b39489..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatio.json +++ /dev/null @@ -1 +0,0 @@ -{"user":"[email protected]","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 deleted file mode 100644 index b3e2f2e..0000000 --- a/mailbox/plugin/quota-search-elasticsearch-v6/src/test/resources/quotaRatioNoDomain.json +++ /dev/null @@ -1 +0,0 @@ -{"user":"user","domain":null,"quotaRatio":0.55} \ No newline at end of file diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java index c14f339..a34b351 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java +++ b/mailbox/plugin/quota-search-elasticsearch/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.IndexName; import org.apache.james.backends.es.ReadAliasName; import org.apache.james.backends.es.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/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java index 21d55a8..315b7ab 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java @@ -19,35 +19,39 @@ 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.io.IOException; 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.NodeMappingFactory; 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.action.search.SearchRequest; +import org.elasticsearch.client.RequestOptions; +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; 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 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(); @@ -55,37 +59,53 @@ public class ElasticSearchQuotaSearcher implements QuotaSearcher { @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()); + try { + return searchHits(query) + .map(SearchHit::getId) + .map(User::fromUsername) + .collect(Guavate.toImmutableList()); + } catch (IOException e) { + throw new RuntimeException("Unexpected exception while executing " + query, e); + } + } - return query.getLimit().getValue() - .map(results::limit) - .orElse(results) - .collect(Guavate.toImmutableList()); + private Stream<SearchHit> searchHits(QuotaQuery query) throws IOException { + if (query.getLimit().isLimited()) { + return executeSingleSearch(query); + } else { + return executeScrolledSearch(query); + } } - public SearchRequestBuilder prepareSearch(QuotaQuery query) { - SearchRequestBuilder searchRequestBuilder = client.prepareSearch(readAlias.getValue()) - .setTypes(QUOTA_RATIO_TYPE.getValue()) - .setScroll(TIMEOUT) - .addFields(USER) - .setQuery(quotaQueryConverter.from(query)); + private Stream<SearchHit> executeSingleSearch(QuotaQuery query) throws IOException { + SearchSourceBuilder searchSourceBuilder = searchSourceBuilder(query) + .from(query.getOffset().getValue()); + query.getLimit().getValue() + .ifPresent(searchSourceBuilder::size); - query.getLimit() - .getValue() - .ifPresent(searchRequestBuilder::setSize); + SearchRequest searchRequest = new SearchRequest(readAlias.getValue()) + .types(NodeMappingFactory.DEFAULT_MAPPING_NAME) + .source(searchSourceBuilder); - searchRequestBuilder.addSort( - SortBuilders.fieldSort(USER) - .order(SortOrder.ASC)); + return Arrays.stream(client.search(searchRequest, RequestOptions.DEFAULT) + .getHits() + .getHits()); + } - return searchRequestBuilder; + private Stream<SearchHit> executeScrolledSearch(QuotaQuery query) { + return new ScrollIterable(client, + new SearchRequest(readAlias.getValue()) + .types(NodeMappingFactory.DEFAULT_MAPPING_NAME) + .source(searchSourceBuilder(query)) + .scroll(TIMEOUT)) + .stream() + .flatMap(searchResponse -> Arrays.stream(searchResponse.getHits().getHits())) + .skip(query.getOffset().getValue()); } + private SearchSourceBuilder searchSourceBuilder(QuotaQuery query) { + return new SearchSourceBuilder() + .query(quotaQueryConverter.from(query)) + .sort(SortBuilders.fieldSort(USER).order(SortOrder.ASC)); + } } \ No newline at end of file diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java index b02d8ac..a67d063 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java +++ b/mailbox/plugin/quota-search-elasticsearch/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/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java index e3ceadd..e8e1904 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java @@ -21,7 +21,6 @@ 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 { @@ -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/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java index 128f1d1..41883f7 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java @@ -20,10 +20,8 @@ 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.KEYWORD; 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; @@ -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/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java index f546230..c1918a9 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java @@ -19,20 +19,22 @@ package org.apache.james.quota.search.elasticsearch; +import java.io.IOException; + 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 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/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java index 2b828f2..4e5f1ad 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java @@ -18,19 +18,18 @@ ****************************************************************/ 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.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 { } @@ -59,12 +58,12 @@ public class ElasticSearchQuotaMailboxListener implements MailboxListener.GroupM } @Override - public void event(Event event) throws JsonProcessingException { - handleEvent(event.getUser(), (QuotaUsageUpdatedEvent) event); + public void event(Event event) throws IOException { + handleEvent((QuotaUsageUpdatedEvent) event); } - private void handleEvent(User user, QuotaUsageUpdatedEvent event) throws JsonProcessingException { - 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/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java index 12f9629..b9b0937 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java +++ b/mailbox/plugin/quota-search-elasticsearch/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/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java index a57a10e..db513aa 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java +++ b/mailbox/plugin/quota-search-elasticsearch/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.IndexName; import org.apache.james.backends.es.ReadAliasName; import org.apache.james.backends.es.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/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java index 5e63c46..d4bc928 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java @@ -21,9 +21,6 @@ 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; @@ -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,14 +86,14 @@ public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterRes usersRepository, domainList, resources.getCurrentQuotaManager(), - () -> elasticSearch.awaitForElasticSearch()); + elasticSearch::awaitForElasticSearch); } catch (Exception e) { throw new ParameterResolutionException("Error while resolving parameter", e); } } @Override - public void beforeEach(ExtensionContext context) throws Exception { + public void beforeEach(ExtensionContext context) { elasticSearch.start(); } diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java index ad26532..8c41989 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java +++ b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java @@ -19,10 +19,70 @@ package org.apache.james.quota.search.elasticsearch; +import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.IntStream; + +import org.apache.james.core.User; +import org.apache.james.core.quota.QuotaSize; +import org.apache.james.quota.search.Limit; +import org.apache.james.quota.search.Offset; +import org.apache.james.quota.search.QuotaQuery; +import org.apache.james.quota.search.QuotaSearchTestSystem; import org.apache.james.quota.search.QuotaSearcherContract; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(ElasticSearchQuotaSearchTestSystemExtension.class) -public class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract { +class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract { + @Test + void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimit(QuotaSearchTestSystem testSystem) throws Exception { + int userCount = 11; + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + IntStream.range(0, userCount) + .boxed() + .map(i -> User.fromLocalPartWithDomain("user" + i, SIMPSON_COM)) + .forEach(user -> provisionUser(testSystem, user)); + testSystem.await(); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .withLimit(Limit.unlimited()) + .build())) + .hasSize(userCount); + } + + @Test + void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimitWhenUsingOffset(QuotaSearchTestSystem testSystem) throws Exception { + int userCount = 12; + testSystem.getDomainList().addDomain(SIMPSON_COM); + testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSize.size(100)); + + IntStream.range(0, userCount) + .boxed() + .map(i -> User.fromLocalPartWithDomain("user" + i, SIMPSON_COM)) + .forEach(user -> provisionUser(testSystem, user)); + testSystem.await(); + + assertThat( + testSystem.getQuotaSearcher() + .search(QuotaQuery.builder() + .withLimit(Limit.unlimited()) + .withOffset(Offset.of(1)) + .build())) + .hasSize(userCount - 1); + } + private void provisionUser(QuotaSearchTestSystem testSystem, User user) { + try { + testSystem.getUsersRepository().addUser(user.asString(), PASSWORD); + appendMessage(testSystem, user, withSize(49)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java index d3f7811..92dc9f5 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java +++ b/mailbox/plugin/quota-search-elasticsearch/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.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/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java index b2c6411..68ff7d9 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java +++ b/mailbox/plugin/quota-search-elasticsearch/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") diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java index 4f42c92..df9cd7a 100644 --- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java +++ b/mailbox/plugin/quota-search-elasticsearch/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) diff --git a/mailbox/pom.xml b/mailbox/pom.xml index 449bb35..7e3dcd2 100644 --- a/mailbox/pom.xml +++ b/mailbox/pom.xml @@ -57,7 +57,6 @@ <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: [email protected] For additional commands, e-mail: [email protected]
