JAMES-2202 Handle a read and a write alias Code was bloating due to index and alias creation. I thus decided to: - Separate concerns of configuration parsing and injection - Make IndexCreationFatory a real factory
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/f3b6ac5d Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/f3b6ac5d Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/f3b6ac5d Branch: refs/heads/master Commit: f3b6ac5db1f8fbbea401381a47651b9b0f1227cc Parents: e3e00e1 Author: benwa <btell...@linagora.com> Authored: Wed Oct 25 13:40:35 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Wed Nov 1 17:54:21 2017 +0700 ---------------------------------------------------------------------- .../james/backends/es/ClientProviderImpl.java | 5 + .../backends/es/DeleteByQueryPerformer.java | 2 +- .../backends/es/ElasticSearchConstants.java | 25 ++ .../james/backends/es/ElasticSearchIndexer.java | 5 +- .../james/backends/es/IndexCreationFactory.java | 65 +++- .../backends/es/ElasticSearchIndexerTest.java | 6 +- .../backends/es/IndexCreationFactoryTest.java | 10 +- .../backends/es/NodeMappingFactoryTest.java | 5 +- .../backends/es/search/ScrollIterableTest.java | 5 +- .../MailboxElasticsearchConstants.java | 3 +- .../search/ElasticSearchSearcher.java | 4 +- .../ElasticSearchIntegrationTest.java | 15 +- .../host/ElasticSearchHostSystem.java | 15 +- .../mailbox/ElasticSearchConfiguration.java | 185 +++++++++- .../mailbox/ElasticSearchMailboxModule.java | 141 +++----- .../apache/james/DockerElasticSearchRule.java | 14 +- .../james/modules/TestElasticSearchModule.java | 9 +- .../mailbox/ElasticSearchConfigurationTest.java | 347 +++++++++++++++++++ .../mailbox/ElasticSearchMailboxModuleTest.java | 215 ------------ .../main/java/org/apache/james/util/Host.java | 3 +- src/site/xdoc/server/config-elasticsearch.xml | 9 +- 21 files changed, 723 insertions(+), 365 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java index a56e056..6118739 100644 --- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java +++ b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java @@ -42,6 +42,11 @@ public class ClientProviderImpl implements ClientProvider { return new ClientProviderImpl(Host.parseHosts(hostsString)); } + public static ClientProviderImpl fromHosts(ImmutableList<Host> hosts) { + Preconditions.checkNotNull(hosts, "Hosts should not be null"); + return new ClientProviderImpl(hosts); + } + private static boolean isValidPort(Integer port) { return port > 0 && port <= 65535; } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java index 0ccea46..6c8c2e3 100644 --- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java +++ b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java @@ -47,7 +47,7 @@ public class DeleteByQueryPerformer { private final TypeName typeName; @Inject - public DeleteByQueryPerformer(Client client, @Named("AsyncExecutor") ExecutorService executor, AliasName aliasName, TypeName typeName) { + public DeleteByQueryPerformer(Client client, @Named("AsyncExecutor") ExecutorService executor, @Named(ElasticSearchConstants.WRITE_ALIAS) AliasName aliasName, TypeName typeName) { this(client, executor, DEFAULT_BATCH_SIZE, aliasName, typeName); } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConstants.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConstants.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConstants.java new file mode 100644 index 0000000..8830208 --- /dev/null +++ b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConstants.java @@ -0,0 +1,25 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.backends.es; + +public interface ElasticSearchConstants { + String WRITE_ALIAS = "injectWriteAlias"; + String READ_ALIAS = "injectReadAlias"; +} http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java index d162a0c..57dbc9e 100644 --- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java +++ b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java @@ -23,6 +23,7 @@ import java.util.Objects; import java.util.Optional; import javax.inject.Inject; +import javax.inject.Named; import org.apache.commons.lang3.StringUtils; import org.elasticsearch.action.bulk.BulkRequestBuilder; @@ -92,7 +93,9 @@ public class ElasticSearchIndexer { private final TypeName typeName; @Inject - public ElasticSearchIndexer(Client client, DeleteByQueryPerformer deleteByQueryPerformer, AliasName aliasName, TypeName typeName) { + public ElasticSearchIndexer(Client client, DeleteByQueryPerformer deleteByQueryPerformer, + @Named(ElasticSearchConstants.WRITE_ALIAS) AliasName aliasName, + TypeName typeName) { this.client = client; this.deleteByQueryPerformer = deleteByQueryPerformer; this.aliasName = aliasName; http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java index 2eb9e1b..a4bcc84 100644 --- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java +++ b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java @@ -22,6 +22,7 @@ package org.apache.james.backends.es; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import java.io.IOException; +import java.util.Optional; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; @@ -31,6 +32,9 @@ import org.elasticsearch.indices.IndexAlreadyExistsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + public class IndexCreationFactory { private static final Logger LOGGER = LoggerFactory.getLogger(IndexCreationFactory.class); @@ -38,26 +42,55 @@ public class IndexCreationFactory { private static final int DEFAULT_NB_REPLICA = 0; public static final String CASE_INSENSITIVE = "case_insensitive"; - public static Client createIndexAndAlias(Client client, IndexName indexName, AliasName aliasName, int nbShards, int nbReplica) { - try { - return createIndexAndAlias(client, indexName, aliasName, generateSetting(nbShards, nbReplica)); - } catch (IOException e) { - LOGGER.error("Error while creating index : ", e); - return client; - } + private IndexName indexName; + private ImmutableList.Builder<AliasName> aliases; + private Optional<Integer> nbShards; + private Optional<Integer> nbReplica; + + public IndexCreationFactory() { + indexName = null; + aliases = ImmutableList.builder(); + nbShards = Optional.empty(); + nbReplica = Optional.empty(); + } + + public IndexCreationFactory onIndex(IndexName indexName) { + Preconditions.checkNotNull(indexName); + this.indexName = indexName; + return this; } - public static Client createIndexAndAlias(Client client, IndexName indexName, AliasName aliasName) { - return createIndexAndAlias(client, indexName, aliasName, DEFAULT_NB_SHARDS, DEFAULT_NB_REPLICA); + public IndexCreationFactory addAlias(AliasName aliasName) { + Preconditions.checkNotNull(aliasName); + this.aliases.add(aliasName); + return this; } - private static Client createIndexAndAlias(Client client, IndexName indexName, AliasName aliasName, XContentBuilder settings) { - createIndexIfNeeded(client, indexName, settings); - createAliasIfNeeded(client, indexName, aliasName); + public IndexCreationFactory nbShards(int nbShards) { + this.nbShards = Optional.of(nbShards); + return this; + } + + public IndexCreationFactory nbReplica(int nbReplica) { + this.nbReplica = Optional.of(nbReplica); + return this; + } + + public Client createIndexAndAliases(Client client) { + Preconditions.checkNotNull(indexName); + try { + createIndexIfNeeded(client, indexName, generateSetting( + nbShards.orElse(DEFAULT_NB_SHARDS), + nbReplica.orElse(DEFAULT_NB_REPLICA))); + aliases.build() + .forEach(alias -> createAliasIfNeeded(client, indexName, alias)); + } catch (IOException e) { + LOGGER.error("Error while creating index : ", e); + } return client; } - private static void createAliasIfNeeded(Client client, IndexName indexName, AliasName aliasName) { + private void createAliasIfNeeded(Client client, IndexName indexName, AliasName aliasName) { if (!aliasExist(client, aliasName)) { client.admin() .indices() @@ -67,7 +100,7 @@ public class IndexCreationFactory { } } - private static boolean aliasExist(Client client, AliasName aliasName) { + private boolean aliasExist(Client client, AliasName aliasName) { return client.admin() .indices() .aliasesExist(new GetAliasesRequest() @@ -76,7 +109,7 @@ public class IndexCreationFactory { .exists(); } - private static void createIndexIfNeeded(Client client, IndexName indexName, XContentBuilder settings) { + private void createIndexIfNeeded(Client client, IndexName indexName, XContentBuilder settings) { try { client.admin() .indices() @@ -89,7 +122,7 @@ public class IndexCreationFactory { } } - private static XContentBuilder generateSetting(int nbShards, int nbReplica) throws IOException { + private XContentBuilder generateSetting(int nbShards, int nbReplica) throws IOException { return jsonBuilder() .startObject() .field("number_of_shards", nbShards) http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java index a4f9aca..a3a6d9c 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java @@ -58,8 +58,10 @@ public class ElasticSearchIndexerTest { public void setup() throws IOException { node = embeddedElasticSearch.getNode(); TestingClientProvider clientProvider = new TestingClientProvider(node); - IndexCreationFactory.createIndexAndAlias(clientProvider.get(), - INDEX_NAME, ALIAS_NAME); + new IndexCreationFactory() + .onIndex(INDEX_NAME) + .addAlias(ALIAS_NAME) + .createIndexAndAliases(clientProvider.get()); DeleteByQueryPerformer deleteByQueryPerformer = new DeleteByQueryPerformer(clientProvider.get(), Executors.newSingleThreadExecutor(), MINIMUM_BATCH_SIZE, http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java index dee1142..7735eb9 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java @@ -41,11 +41,17 @@ public class IndexCreationFactoryTest { @Before public void setUp() { clientProvider = new TestingClientProvider(embeddedElasticSearch.getNode()); - IndexCreationFactory.createIndexAndAlias(clientProvider.get(), INDEX_NAME, ALIAS_NAME); + new IndexCreationFactory() + .onIndex(INDEX_NAME) + .addAlias(ALIAS_NAME) + .createIndexAndAliases(clientProvider.get()); } @Test public void createIndexAndAliasShouldNotThrowWhenCalledSeveralTime() { - IndexCreationFactory.createIndexAndAlias(clientProvider.get(), INDEX_NAME, ALIAS_NAME); + new IndexCreationFactory() + .onIndex(INDEX_NAME) + .addAlias(ALIAS_NAME) + .createIndexAndAliases(clientProvider.get()); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java index 6aca8d7..1e0eb79 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java @@ -46,7 +46,10 @@ public class NodeMappingFactoryTest { @Before public void setUp() throws Exception { clientProvider = new TestingClientProvider(embeddedElasticSearch.getNode()); - IndexCreationFactory.createIndexAndAlias(clientProvider.get(), INDEX_NAME, ALIAS_NAME); + new IndexCreationFactory() + .onIndex(INDEX_NAME) + .addAlias(ALIAS_NAME) + .createIndexAndAliases(clientProvider.get()); NodeMappingFactory.applyMapping(clientProvider.get(), INDEX_NAME, TYPE_NAME, http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrollIterableTest.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrollIterableTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrollIterableTest.java index 4515f96..b296b8e 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrollIterableTest.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrollIterableTest.java @@ -67,7 +67,10 @@ public class ScrollIterableTest { @Before public void setUp() throws Exception { clientProvider = new TestingClientProvider(embeddedElasticSearch.getNode()); - IndexCreationFactory.createIndexAndAlias(clientProvider.get(), INDEX_NAME, ALIAS_NAME); + new IndexCreationFactory() + .onIndex(INDEX_NAME) + .addAlias(ALIAS_NAME) + .createIndexAndAliases(clientProvider.get()); embeddedElasticSearch.awaitForElasticSearch(); NodeMappingFactory.applyMapping(clientProvider.get(), INDEX_NAME, TYPE_NAME, getMappingsSources()); } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticsearchConstants.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticsearchConstants.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticsearchConstants.java index fb89b8e..e1d87c2 100644 --- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticsearchConstants.java +++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticsearchConstants.java @@ -24,7 +24,8 @@ import org.apache.james.backends.es.IndexName; import org.apache.james.backends.es.TypeName; public interface MailboxElasticsearchConstants { - AliasName DEFAULT_MAILBOX_ALIAS = new AliasName("mailboxAlias"); + AliasName DEFAULT_MAILBOX_WRITE_ALIAS = new AliasName("mailboxWriteAlias"); + AliasName DEFAULT_MAILBOX_READ_ALIAS = new AliasName("mailboxReadAlias"); IndexName DEFAULT_MAILBOX_INDEX = new IndexName("mailbox"); TypeName MESSAGE_TYPE = new TypeName("message"); } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java index cc330e8..acf7baf 100644 --- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java +++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java @@ -24,7 +24,9 @@ import java.util.Optional; import java.util.stream.Stream; import javax.inject.Inject; +import javax.inject.Named; +import org.apache.james.backends.es.ElasticSearchConstants; import org.apache.james.backends.es.AliasName; import org.apache.james.backends.es.TypeName; import org.apache.james.backends.es.search.ScrollIterable; @@ -64,7 +66,7 @@ public class ElasticSearchSearcher { @Inject public ElasticSearchSearcher(Client client, QueryConverter queryConverter, MailboxId.Factory mailboxIdFactory, MessageId.Factory messageIdFactory, - AliasName aliasName, TypeName typeName) { + @Named(ElasticSearchConstants.READ_ALIAS) AliasName aliasName, TypeName typeName) { this(client, queryConverter, DEFAULT_SIZE, mailboxIdFactory, messageIdFactory, aliasName, typeName); } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java index f32f895..4e18134 100644 --- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java +++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java @@ -110,10 +110,11 @@ public class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest @Override protected void initializeMailboxManager() throws Exception { Client client = NodeMappingFactory.applyMapping( - IndexCreationFactory.createIndexAndAlias( - new TestingClientProvider(embeddedElasticSearch.getNode()).get(), - MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS), + new IndexCreationFactory() + .onIndex(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX) + .addAlias( MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS) + .addAlias( MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS) + .createIndexAndAliases(new TestingClientProvider(embeddedElasticSearch.getNode()).get()), MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, MailboxElasticsearchConstants.MESSAGE_TYPE, MailboxMappingFactory.getMappingContent()); @@ -126,13 +127,13 @@ public class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest new DeleteByQueryPerformer(client, Executors.newSingleThreadExecutor(), BATCH_SIZE, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS, + MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS, + MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, new InMemoryId.Factory(), messageIdFactory, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS, + MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), new MessageToElasticSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES)); storeMailboxManager = new InMemoryMailboxManager( http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java ---------------------------------------------------------------------- diff --git a/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java b/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java index cc6b435..d83f96f 100644 --- a/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java +++ b/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java @@ -95,10 +95,11 @@ public class ElasticSearchHostSystem extends JamesImapHostSystem { private void initFields() { Client client = NodeMappingFactory.applyMapping( - IndexCreationFactory.createIndexAndAlias( - new TestingClientProvider(embeddedElasticSearch.getNode()).get(), - MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS), + new IndexCreationFactory() + .onIndex(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX) + .addAlias(MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS) + .addAlias(MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS) + .createIndexAndAliases(new TestingClientProvider(embeddedElasticSearch.getNode()).get()), MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, MailboxElasticsearchConstants.MESSAGE_TYPE, MailboxMappingFactory.getMappingContent()); @@ -109,12 +110,12 @@ public class ElasticSearchHostSystem extends JamesImapHostSystem { ElasticSearchListeningMessageSearchIndex searchIndex = new ElasticSearchListeningMessageSearchIndex( factory, new ElasticSearchIndexer(client, - new DeleteByQueryPerformer(client, Executors.newSingleThreadExecutor(), MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS, + new DeleteByQueryPerformer(client, Executors.newSingleThreadExecutor(), MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), + MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), new InMemoryId.Factory(), messageIdFactory, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), + MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS, MailboxElasticsearchConstants.MESSAGE_TYPE), new MessageToElasticSearchJson(new DefaultTextExtractor(), ZoneId.systemDefault(), IndexAttachments.YES)); MailboxACLResolver aclResolver = new UnionMailboxACLResolver(); http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchConfiguration.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchConfiguration.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchConfiguration.java index 0c39e81..7d65618 100644 --- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchConfiguration.java +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchConfiguration.java @@ -19,13 +19,192 @@ package org.apache.james.modules.mailbox; +import java.util.Objects; +import java.util.Optional; + import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.james.backends.es.AliasName; +import org.apache.james.backends.es.IndexName; +import org.apache.james.mailbox.elasticsearch.IndexAttachments; +import org.apache.james.mailbox.elasticsearch.MailboxElasticsearchConstants; +import org.apache.james.util.Host; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; + +public class ElasticSearchConfiguration { + public static final String ELASTICSEARCH_HOSTS = "elasticsearch.hosts"; + public static final String ELASTICSEARCH_MASTER_HOST = "elasticsearch.masterHost"; + public static final String ELASTICSEARCH_PORT = "elasticsearch.port"; + public static final String ELASTICSEARCH_INDEX_NAME = "elasticsearch.index.name"; + public static final String ELASTICSEARCH_NB_REPLICA = "elasticsearch.nb.replica"; + public static final String ELASTICSEARCH_NB_SHARDS = "elasticsearch.nb.shards"; + public static final String ELASTICSEARCH_ALIAS_READ_NAME = "elasticsearch.alias.read.name"; + public static final String ELASTICSEARCH_ALIAS_WRITE_NAME = "elasticsearch.alias.write.name"; + public static final String ELASTICSEARCH_RETRY_CONNECTION_MIN_DELAY = "elasticsearch.retryConnection.minDelay"; + public static final String ELASTICSEARCH_RETRY_CONNECTION_MAX_RETRIES = "elasticsearch.retryConnection.maxRetries"; + public static final String ELASTICSEARCH_INDEX_ATTACHMENTS = "elasticsearch.indexAttachments"; + + public static final int DEFAULT_CONNECTION_MAX_RETRIES = 7; + public static final int DEFAULT_CONNECTION_MIN_DELAY = 3000; + public static final boolean DEFAULT_INDEX_ATTACHMENTS = true; + public static final int DEFAULT_NB_SHARDS = 1; + public static final int DEFAULT_NB_REPLICA = 0; + public static final int DEFAULT_PORT = 9300; + + public static ElasticSearchConfiguration fromProperties(PropertiesConfiguration configuration) throws ConfigurationException { + int nbShards = configuration.getInt(ELASTICSEARCH_NB_SHARDS, DEFAULT_NB_SHARDS); + int nbReplica = configuration.getInt(ELASTICSEARCH_NB_REPLICA, DEFAULT_NB_REPLICA); + int maxRetries = configuration.getInt(ELASTICSEARCH_RETRY_CONNECTION_MAX_RETRIES, DEFAULT_CONNECTION_MAX_RETRIES); + int minDelay = configuration.getInt(ELASTICSEARCH_RETRY_CONNECTION_MIN_DELAY, DEFAULT_CONNECTION_MIN_DELAY); + IndexAttachments indexAttachments = provideIndexAttachments(configuration); + ImmutableList<Host> hosts = getHosts(configuration); + + AliasName readAlias = Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_READ_NAME)) + .map(AliasName::new) + .orElse(MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS); + AliasName writeAlias = Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_WRITE_NAME)) + .map(AliasName::new) + .orElse(MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS); + IndexName indexName = Optional.ofNullable(configuration.getString(ELASTICSEARCH_INDEX_NAME)) + .map(IndexName::new) + .orElse(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX); + + return new ElasticSearchConfiguration( + hosts, + indexName, + readAlias, + writeAlias, + nbShards, + nbReplica, + minDelay, + maxRetries, + indexAttachments); + } + + private static IndexAttachments provideIndexAttachments(PropertiesConfiguration configuration) { + if (configuration.getBoolean(ELASTICSEARCH_INDEX_ATTACHMENTS, DEFAULT_INDEX_ATTACHMENTS)) { + return IndexAttachments.YES; + } + return IndexAttachments.NO; + } + + private static ImmutableList<Host> getHosts(PropertiesConfiguration propertiesReader) throws ConfigurationException { + Optional<String> monoHostAddress = Optional.ofNullable( + propertiesReader.getString(ELASTICSEARCH_MASTER_HOST, null)); + Optional<Integer> monoHostPort = Optional.ofNullable( + propertiesReader.getInteger(ELASTICSEARCH_PORT, null)); + Optional<String> multiHosts = Optional.ofNullable( + propertiesReader.getString(ELASTICSEARCH_HOSTS, null)); + + validateHostsConfigurationOptions(monoHostAddress, monoHostPort, multiHosts); + + if (monoHostAddress.isPresent()) { + return ImmutableList.of( + Host.from(monoHostAddress.get(), + monoHostPort.get())); + } else { + return Host.parseHosts(multiHosts.get(), DEFAULT_PORT); + } + } + + @VisibleForTesting + static void validateHostsConfigurationOptions(Optional<String> monoHostAddress, + Optional<Integer> monoHostPort, + Optional<String> multiHosts) throws ConfigurationException { + if (monoHostAddress.isPresent() != monoHostPort.isPresent()) { + throw new ConfigurationException(ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + " should be specified together"); + } + if (multiHosts.isPresent() && monoHostAddress.isPresent()) { + throw new ConfigurationException("You should choose between mono host set up and " + ELASTICSEARCH_HOSTS); + } + if (!multiHosts.isPresent() && !monoHostAddress.isPresent()) { + throw new ConfigurationException("You should specify either (" + ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + ") or " + ELASTICSEARCH_HOSTS); + } + } + + private final ImmutableList<Host> hosts; + private final IndexName indexName; + private final AliasName readAliasName; + private final AliasName writeAliasName; + private final int nbShards; + private final int nbReplica; + private final int minDelay; + private final int maxRetries; + private final IndexAttachments indexAttachment; + + public ElasticSearchConfiguration(ImmutableList<Host> hosts, IndexName indexName, AliasName readAliasName, + AliasName writeAliasName, int nbShards, int nbReplica, int minDelay, + int maxRetries, IndexAttachments indexAttachment) { + this.hosts = hosts; + this.indexName = indexName; + this.readAliasName = readAliasName; + this.writeAliasName = writeAliasName; + this.nbShards = nbShards; + this.nbReplica = nbReplica; + this.minDelay = minDelay; + this.maxRetries = maxRetries; + this.indexAttachment = indexAttachment; + } + + public ImmutableList<Host> getHosts() { + return hosts; + } + + public IndexName getIndexName() { + return indexName; + } + + public AliasName getReadAliasName() { + return readAliasName; + } + + public AliasName getWriteAliasName() { + return writeAliasName; + } + + public int getNbShards() { + return nbShards; + } + + public int getNbReplica() { + return nbReplica; + } + + public int getMinDelay() { + return minDelay; + } + + public int getMaxRetries() { + return maxRetries; + } -import java.io.FileNotFoundException; + public IndexAttachments getIndexAttachment() { + return indexAttachment; + } -public interface ElasticSearchConfiguration { + @Override + public final boolean equals(Object o) { + if (o instanceof ElasticSearchConfiguration) { + ElasticSearchConfiguration that = (ElasticSearchConfiguration) o; - PropertiesConfiguration getConfiguration() throws FileNotFoundException, ConfigurationException; + return Objects.equals(this.nbShards, that.nbShards) + && Objects.equals(this.nbReplica, that.nbReplica) + && Objects.equals(this.minDelay, that.minDelay) + && Objects.equals(this.maxRetries, that.maxRetries) + && Objects.equals(this.indexAttachment, that.indexAttachment) + && Objects.equals(this.hosts, that.hosts) + && Objects.equals(this.indexName, that.indexName) + && Objects.equals(this.readAliasName, that.readAliasName) + && Objects.equals(this.writeAliasName, that.writeAliasName); + } + return false; + } + @Override + public final int hashCode() { + return Objects.hash(hosts, indexName, readAliasName, writeAliasName, nbShards, + nbReplica, minDelay, maxRetries, indexAttachment); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java index ea59317..d9e7858 100644 --- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java @@ -21,13 +21,14 @@ package org.apache.james.modules.mailbox; import java.io.FileNotFoundException; import java.time.LocalDateTime; -import java.util.Optional; import java.util.concurrent.ExecutionException; +import javax.inject.Named; import javax.inject.Singleton; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.james.backends.es.ElasticSearchConstants; import org.apache.james.backends.es.AliasName; import org.apache.james.backends.es.ClientProviderImpl; import org.apache.james.backends.es.IndexCreationFactory; @@ -47,7 +48,6 @@ import org.elasticsearch.client.transport.NoNodeAvailableException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -57,14 +57,6 @@ public class ElasticSearchMailboxModule extends AbstractModule { private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchMailboxModule.class); public static final String ELASTICSEARCH_CONFIGURATION_NAME = "elasticsearch"; - public static final String ELASTICSEARCH_HOSTS = "elasticsearch.hosts"; - public static final String ELASTICSEARCH_MASTER_HOST = "elasticsearch.masterHost"; - public static final String ELASTICSEARCH_PORT = "elasticsearch.port"; - private static final int DEFAULT_CONNECTION_MAX_RETRIES = 7; - private static final int DEFAULT_CONNECTION_MIN_DELAY = 3000; - private static final boolean DEFAULT_INDEX_ATTACHMENTS = true; - private static final int DEFAULT_NB_SHARDS = 1; - private static final int DEFAULT_NB_REPLICA = 0; private static final String LOCALHOST = "127.0.0.1"; @Override @@ -76,117 +68,72 @@ public class ElasticSearchMailboxModule extends AbstractModule { } @Provides - protected IndexName provideIndexName(ElasticSearchConfiguration elasticSearchConfiguration) - throws ConfigurationException { + @Singleton + private ElasticSearchConfiguration getElasticSearchConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException { try { - return Optional.ofNullable(elasticSearchConfiguration.getConfiguration() - .getString("elasticsearch.index.name")) - .map(IndexName::new) - .orElse(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX); + PropertiesConfiguration configuration = propertiesProvider.getConfiguration(ELASTICSEARCH_CONFIGURATION_NAME); + return ElasticSearchConfiguration.fromProperties(configuration); } catch (FileNotFoundException e) { - LOGGER.info("Could not find ElasticSearch configuration file. Using default index {}", MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX.getValue()); - return MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX; + LOGGER.warn("Could not find " + ELASTICSEARCH_CONFIGURATION_NAME + " configuration file. Using 127.0.0.1:9300 as contact point"); + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty(ElasticSearchConfiguration.ELASTICSEARCH_HOSTS, LOCALHOST); + return ElasticSearchConfiguration.fromProperties(configuration); } } @Provides - protected AliasName provideAliasName(ElasticSearchConfiguration elasticSearchConfiguration) - throws ConfigurationException { - try { - return Optional.ofNullable(elasticSearchConfiguration.getConfiguration() - .getString("elasticsearch.alias.name")) - .map(AliasName::new) - .orElse(MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS); - } catch (FileNotFoundException e) { - LOGGER.info("Could not find ElasticSearch configuration file. Using default alias {}", MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX.getValue()); - return MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS; - } + protected IndexName provideIndexName(ElasticSearchConfiguration configuration) { + return configuration.getIndexName(); } - @Provides - @Singleton - protected Client provideClientProvider(ElasticSearchConfiguration elasticSearchConfiguration, - IndexName indexName, AliasName aliasName, - AsyncRetryExecutor executor) throws ConfigurationException, FileNotFoundException, ExecutionException, InterruptedException { - PropertiesConfiguration propertiesReader = elasticSearchConfiguration.getConfiguration(); - int maxRetries = propertiesReader.getInt("elasticsearch.retryConnection.maxRetries", DEFAULT_CONNECTION_MAX_RETRIES); - int minDelay = propertiesReader.getInt("elasticsearch.retryConnection.minDelay", DEFAULT_CONNECTION_MIN_DELAY); - - return RetryExecutorUtil.retryOnExceptions(executor, maxRetries, minDelay, NoNodeAvailableException.class) - .getWithRetry(context -> connectToCluster(propertiesReader, indexName, aliasName)) - .get(); + @Provides @Named(ElasticSearchConstants.READ_ALIAS) + protected AliasName provideReadAliasName(ElasticSearchConfiguration configuration) { + return configuration.getReadAliasName(); } - private Client createIndexAndMapping(Client client, IndexName indexName, AliasName aliasName, PropertiesConfiguration propertiesReader) { - IndexCreationFactory.createIndexAndAlias(client, - indexName, - aliasName, - propertiesReader.getInt(ELASTICSEARCH_CONFIGURATION_NAME + ".nb.shards", DEFAULT_NB_SHARDS), - propertiesReader.getInt(ELASTICSEARCH_CONFIGURATION_NAME + ".nb.replica", DEFAULT_NB_REPLICA)); - NodeMappingFactory.applyMapping(client, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, - MailboxElasticsearchConstants.MESSAGE_TYPE, - MailboxMappingFactory.getMappingContent()); - return client; + @Provides @Named(ElasticSearchConstants.WRITE_ALIAS) + protected AliasName provideWriteAliasName(ElasticSearchConfiguration configuration) { + return configuration.getWriteAliasName(); } - private Client connectToCluster(PropertiesConfiguration propertiesReader, IndexName indexName, AliasName aliasName) - throws ConfigurationException { - LOGGER.info("Trying to connect to ElasticSearch service at {}", LocalDateTime.now()); - - return createIndexAndMapping(createClient(propertiesReader), indexName, aliasName, propertiesReader); + @Provides + @Singleton + protected IndexCreationFactory provideIndexCreationFactory(ElasticSearchConfiguration configuration) { + return new IndexCreationFactory() + .onIndex(configuration.getIndexName()) + .addAlias(configuration.getReadAliasName()) + .addAlias(configuration.getWriteAliasName()) + .nbShards(configuration.getNbShards()) + .nbReplica(configuration.getNbReplica()); } @Provides @Singleton - private ElasticSearchConfiguration getElasticSearchConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException { - try { - PropertiesConfiguration configuration = propertiesProvider.getConfiguration(ELASTICSEARCH_CONFIGURATION_NAME); - return () -> configuration; - } catch (FileNotFoundException e) { - LOGGER.warn("Could not find " + ELASTICSEARCH_CONFIGURATION_NAME + " configuration file. Using 127.0.0.1:9300 as contact point"); - PropertiesConfiguration propertiesConfiguration = new PropertiesConfiguration(); - propertiesConfiguration.addProperty(ELASTICSEARCH_HOSTS, LOCALHOST); - return () -> propertiesConfiguration; - } + protected Client provideClientProvider(ElasticSearchConfiguration configuration, + IndexCreationFactory indexCreationFactory, + AsyncRetryExecutor executor) throws ExecutionException, InterruptedException { + + return RetryExecutorUtil.retryOnExceptions(executor, configuration.getMaxRetries(), configuration.getMinDelay(), NoNodeAvailableException.class) + .getWithRetry(context -> connectToCluster(configuration, indexCreationFactory)) + .get(); } - private Client createClient(PropertiesConfiguration propertiesReader) throws ConfigurationException { - Optional<String> monoHostAddress = Optional.ofNullable(propertiesReader.getString(ELASTICSEARCH_MASTER_HOST, null)); - Optional<Integer> monoHostPort = Optional.ofNullable(propertiesReader.getInteger(ELASTICSEARCH_PORT, null)); - Optional<String> multiHosts = Optional.ofNullable(propertiesReader.getString(ELASTICSEARCH_HOSTS, null)); + private Client connectToCluster(ElasticSearchConfiguration configuration, IndexCreationFactory indexCreationFactory) { + LOGGER.info("Trying to connect to ElasticSearch service at {}", LocalDateTime.now()); - validateHostsConfigurationOptions(monoHostAddress, monoHostPort, multiHosts); + Client client = ClientProviderImpl.fromHosts(configuration.getHosts()).get(); - if (monoHostAddress.isPresent()) { - return ClientProviderImpl.forHost(monoHostAddress.get(), monoHostPort.get()).get(); - } else { - return ClientProviderImpl.fromHostsString(multiHosts.get()).get(); - } - } - - @VisibleForTesting - static void validateHostsConfigurationOptions(Optional<String> monoHostAddress, - Optional<Integer> monoHostPort, - Optional<String> multiHosts) throws ConfigurationException { - if (monoHostAddress.isPresent() != monoHostPort.isPresent()) { - throw new ConfigurationException(ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + " should be specified together"); - } - if (multiHosts.isPresent() && monoHostAddress.isPresent()) { - throw new ConfigurationException("You should choose between mono host set up and " + ELASTICSEARCH_HOSTS); - } - if (!multiHosts.isPresent() && !monoHostAddress.isPresent()) { - throw new ConfigurationException("You should specify either (" + ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + ") or " + ELASTICSEARCH_HOSTS); - } + indexCreationFactory.createIndexAndAliases(client); + return NodeMappingFactory.applyMapping(client, + configuration.getIndexName(), + MailboxElasticsearchConstants.MESSAGE_TYPE, + MailboxMappingFactory.getMappingContent()); } @Provides @Singleton - public IndexAttachments provideIndexAttachments(PropertiesConfiguration configuration) { - if (configuration.getBoolean(ELASTICSEARCH_CONFIGURATION_NAME + ".indexAttachments", DEFAULT_INDEX_ATTACHMENTS)) { - return IndexAttachments.YES; - } - return IndexAttachments.NO; + public IndexAttachments provideIndexAttachments(ElasticSearchConfiguration configuration) { + return configuration.getIndexAttachment(); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java index 75fe4a3..85171ba 100644 --- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java @@ -19,12 +19,14 @@ package org.apache.james; +import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.james.modules.mailbox.ElasticSearchConfiguration; import org.apache.james.util.streams.SwarmGenericContainer; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import com.google.common.base.Throwables; import com.google.inject.Module; @@ -33,7 +35,7 @@ public class DockerElasticSearchRule implements GuiceModuleTestRule { private static final int ELASTIC_SEARCH_PORT = 9300; public static final int ELASTIC_SEARCH_HTTP_PORT = 9200; - public PropertiesConfiguration getElasticSearchConfigurationForDocker() { + public ElasticSearchConfiguration getElasticSearchConfigurationForDocker() { PropertiesConfiguration configuration = new PropertiesConfiguration(); configuration.addProperty("elasticsearch.masterHost", getIp()); @@ -50,7 +52,11 @@ public class DockerElasticSearchRule implements GuiceModuleTestRule { configuration.addProperty("elasticsearch.metrics.reports.period", 30); configuration.addProperty("elasticsearch.metrics.reports.index", "james-metrics"); - return configuration; + try { + return ElasticSearchConfiguration.fromProperties(configuration); + } catch (ConfigurationException e) { + throw Throwables.propagate(e); + } } private SwarmGenericContainer elasticSearchContainer = new SwarmGenericContainer("elasticsearch:2.2.2") @@ -67,7 +73,9 @@ public class DockerElasticSearchRule implements GuiceModuleTestRule { @Override public Module getModule() { - return (binder) -> binder.bind(ElasticSearchConfiguration.class).toInstance(this::getElasticSearchConfigurationForDocker); + return (binder) -> + binder.bind(ElasticSearchConfiguration.class) + .toInstance(getElasticSearchConfigurationForDocker()); } public String getIp() { http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestElasticSearchModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestElasticSearchModule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestElasticSearchModule.java index 2b6b272..5e30618 100644 --- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestElasticSearchModule.java +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestElasticSearchModule.java @@ -49,9 +49,12 @@ public class TestElasticSearchModule extends AbstractModule{ @Singleton protected Client provideClientProvider() { Client client = new TestingClientProvider(embeddedElasticSearch.getNode()).get(); - IndexCreationFactory.createIndexAndAlias(client, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, - MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS); + + new IndexCreationFactory() + .onIndex(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX) + .addAlias(MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS) + .addAlias(MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS) + .createIndexAndAliases(client); return NodeMappingFactory.applyMapping(client, MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX, MailboxElasticsearchConstants.MESSAGE_TYPE, http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchConfigurationTest.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchConfigurationTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchConfigurationTest.java new file mode 100644 index 0000000..f4b7765 --- /dev/null +++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchConfigurationTest.java @@ -0,0 +1,347 @@ +/**************************************************************** + * 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.modules.mailbox; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.Optional; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.james.backends.es.AliasName; +import org.apache.james.backends.es.IndexName; +import org.apache.james.mailbox.elasticsearch.IndexAttachments; +import org.apache.james.mailbox.elasticsearch.MailboxElasticsearchConstants; +import org.apache.james.util.Host; +import org.junit.Test; + +public class ElasticSearchConfigurationTest { + + @Test + public void getNbReplicaShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + int value = 36; + configuration.addProperty("elasticsearch.nb.replica", value); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getNbReplica()) + .isEqualTo(value); + } + + @Test + public void getNbReplicaShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getNbReplica()) + .isEqualTo(ElasticSearchConfiguration.DEFAULT_NB_REPLICA); + } + + @Test + public void getNbShardsShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + int value = 36; + configuration.addProperty("elasticsearch.nb.shards", value); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getNbShards()) + .isEqualTo(value); + } + + @Test + public void getNbShardsShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getNbShards()) + .isEqualTo(ElasticSearchConfiguration.DEFAULT_NB_SHARDS); + } + + @Test + public void getMaxRetriesShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + int value = 36; + configuration.addProperty("elasticsearch.retryConnection.maxRetries", value); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getMaxRetries()) + .isEqualTo(value); + } + + @Test + public void getMaxRetriesShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getMaxRetries()) + .isEqualTo(ElasticSearchConfiguration.DEFAULT_CONNECTION_MAX_RETRIES); + } + + @Test + public void getMinDelayShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + int value = 36; + configuration.addProperty("elasticsearch.retryConnection.minDelay", value); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getMinDelay()) + .isEqualTo(value); + } + + @Test + public void getMinDelayShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getMinDelay()) + .isEqualTo(ElasticSearchConfiguration.DEFAULT_CONNECTION_MIN_DELAY); + } + + @Test + public void getIndexNameShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String name = "name"; + configuration.addProperty("elasticsearch.index.name", name); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getIndexName()) + .isEqualTo(new IndexName(name)); + } + + @Test + public void getIndexNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getIndexName()) + .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX); + } + + @Test + public void getReadAliasNameShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String name = "name"; + configuration.addProperty("elasticsearch.alias.read.name", name); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getReadAliasName()) + .isEqualTo(new AliasName(name)); + } + + @Test + public void getReadAliasNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getReadAliasName()) + .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_READ_ALIAS); + } + + + @Test + public void getWriteAliasNameNameShouldReturnConfiguredValue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String name = "name"; + configuration.addProperty("elasticsearch.alias.write.name", name); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getWriteAliasName()) + .isEqualTo(new AliasName(name)); + } + + @Test + public void getWriteAliasNameShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getWriteAliasName()) + .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS); + } + + @Test + public void getIndexAttachmentShouldReturnConfiguredValueWhenTrue() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.indexAttachments", true); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getIndexAttachment()) + .isEqualTo(IndexAttachments.YES); + } + + @Test + public void getIndexAttachmentShouldReturnConfiguredValueWhenFalse() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.indexAttachments", false); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getIndexAttachment()) + .isEqualTo(IndexAttachments.NO); + } + + @Test + public void getIndexAttachmentShouldReturnDefaultValueWhenMissing() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty("elasticsearch.hosts", "127.0.0.1"); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getIndexAttachment()) + .isEqualTo(IndexAttachments.YES); + } + + + @Test + public void getHostsShouldReturnConfiguredHostsWhenNoPort() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String hostname = "myHost"; + configuration.addProperty("elasticsearch.hosts", hostname); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getHosts()) + .containsOnly(Host.from(hostname, ElasticSearchConfiguration.DEFAULT_PORT)); + } + + @Test + public void getHostsShouldReturnConfiguredHosts() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String hostname = "myHost"; + int port = 2154; + configuration.addProperty("elasticsearch.hosts", hostname + ":" + port); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getHosts()) + .containsOnly(Host.from(hostname, port)); + } + + @Test + public void getHostsShouldReturnConfiguredMasterHost() throws ConfigurationException { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String hostname = "myHost"; + configuration.addProperty("elasticsearch.masterHost", hostname); + int port = 9300; + configuration.addProperty("elasticsearch.port", port); + + ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration); + + assertThat(elasticSearchConfiguration.getHosts()) + .containsOnly(Host.from(hostname, port)); + } + + @Test + public void validateHostsConfigurationOptionsShouldThrowWhenNoHostSpecify() throws Exception { + assertThatThrownBy(() -> + ElasticSearchConfiguration.validateHostsConfigurationOptions( + Optional.empty(), + Optional.empty(), + Optional.empty())) + .isInstanceOf(ConfigurationException.class) + .hasMessage("You should specify either (" + ElasticSearchConfiguration.ELASTICSEARCH_MASTER_HOST + + " and " + ElasticSearchConfiguration.ELASTICSEARCH_PORT + + ") or " + ElasticSearchConfiguration.ELASTICSEARCH_HOSTS); + } + + @Test + public void validateHostsConfigurationOptionsShouldThrowWhenMonoAndMultiHostSpecified() throws Exception { + assertThatThrownBy(() -> + ElasticSearchConfiguration.validateHostsConfigurationOptions( + Optional.of("localhost"), + Optional.of(9200), + Optional.of("localhost:9200"))) + .isInstanceOf(ConfigurationException.class) + .hasMessage("You should choose between mono host set up and " + ElasticSearchConfiguration.ELASTICSEARCH_HOSTS); + } + + @Test + public void validateHostsConfigurationOptionsShouldThrowWhenMonoHostWithoutPort() throws Exception { + assertThatThrownBy(() -> + ElasticSearchConfiguration.validateHostsConfigurationOptions( + Optional.of("localhost"), + Optional.empty(), + Optional.empty())) + .isInstanceOf(ConfigurationException.class) + .hasMessage(ElasticSearchConfiguration.ELASTICSEARCH_MASTER_HOST + + " and " + ElasticSearchConfiguration.ELASTICSEARCH_PORT + " should be specified together"); + } + + @Test + public void validateHostsConfigurationOptionsShouldThrowWhenMonoHostWithoutAddress() throws Exception { + assertThatThrownBy(() -> + ElasticSearchConfiguration.validateHostsConfigurationOptions( + Optional.empty(), + Optional.of(9200), + Optional.empty())) + .isInstanceOf(ConfigurationException.class) + .hasMessage(ElasticSearchConfiguration.ELASTICSEARCH_MASTER_HOST + " and " + + ElasticSearchConfiguration.ELASTICSEARCH_PORT + " should be specified together"); + } + + @Test + public void validateHostsConfigurationOptionsShouldAcceptMonoHostConfiguration() throws Exception { + ElasticSearchConfiguration.validateHostsConfigurationOptions( + Optional.of("localhost"), + Optional.of(9200), + Optional.empty()); + } + + @Test + public void validateHostsConfigurationOptionsShouldAcceptMultiHostConfiguration() throws Exception { + ElasticSearchConfiguration.validateHostsConfigurationOptions( + Optional.empty(), + Optional.empty(), + Optional.of("localhost:9200")); + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModuleTest.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModuleTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModuleTest.java deleted file mode 100644 index 41108e7..0000000 --- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModuleTest.java +++ /dev/null @@ -1,215 +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.modules.mailbox; - -import static org.apache.james.modules.mailbox.ElasticSearchMailboxModule.ELASTICSEARCH_HOSTS; -import static org.apache.james.modules.mailbox.ElasticSearchMailboxModule.ELASTICSEARCH_MASTER_HOST; -import static org.apache.james.modules.mailbox.ElasticSearchMailboxModule.ELASTICSEARCH_PORT; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.FileNotFoundException; -import java.util.Optional; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.james.backends.es.AliasName; -import org.apache.james.backends.es.IndexName; -import org.apache.james.mailbox.elasticsearch.IndexAttachments; -import org.apache.james.mailbox.elasticsearch.MailboxElasticsearchConstants; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class ElasticSearchMailboxModuleTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void provideIndexNameShouldRetrievedConfiguredIndexName() throws ConfigurationException { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - String name = "name"; - configuration.addProperty("elasticsearch.index.name", name); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - IndexName indexName = testee.provideIndexName(() -> configuration); - - assertThat(indexName) - .isEqualTo(new IndexName(name)); - } - - @Test - public void provideIndexNameShouldReturnDefaultIndexNameWhenNone() throws ConfigurationException { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - IndexName indexName = testee.provideIndexName(() -> configuration); - - assertThat(indexName) - .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX); - } - - @Test - public void provideIndexNameShouldReturnDefaultIndexNameWhenError() throws ConfigurationException { - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - IndexName indexName = testee.provideIndexName(() -> { - throw new FileNotFoundException(); - }); - - assertThat(indexName) - .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_INDEX); - } - - @Test - public void provideAliasNameShouldRetrievedConfiguredAliasName() throws ConfigurationException { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - String name = "name"; - configuration.addProperty("elasticsearch.alias.name", name); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - AliasName indexName = testee.provideAliasName(() -> configuration); - - assertThat(indexName) - .isEqualTo(new AliasName(name)); - } - - @Test - public void provideAliasNameShouldReturnDefaultAliasNameWhenNone() throws ConfigurationException { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - AliasName aliasName = testee.provideAliasName(() -> configuration); - - assertThat(aliasName) - .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS); - } - - @Test - public void provideAliasNameShouldReturnDefaultAliasNameWhenError() throws ConfigurationException { - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - AliasName aliasName = testee.provideAliasName(() -> { - throw new FileNotFoundException(); - }); - - assertThat(aliasName) - .isEqualTo(MailboxElasticsearchConstants.DEFAULT_MAILBOX_ALIAS); - } - - @Test - public void provideIndexAttachmentsShouldReturnTrueWhenIndexAttachmentsIsTrueInConfiguration() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.addProperty("elasticsearch.indexAttachments", true); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - IndexAttachments indexAttachments = testee.provideIndexAttachments(configuration); - - assertThat(indexAttachments).isEqualTo(IndexAttachments.YES); - } - - @Test - public void provideIndexAttachmentsShouldReturnFalseWhenIndexAttachmentsIsFalseInConfiguration() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.addProperty("elasticsearch.indexAttachments", false); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - IndexAttachments indexAttachments = testee.provideIndexAttachments(configuration); - - assertThat(indexAttachments).isEqualTo(IndexAttachments.NO); - } - - @Test - public void provideIndexAttachmentsShouldReturnTrueWhenIndexAttachmentsIsNotDefinedInConfiguration() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - - ElasticSearchMailboxModule testee = new ElasticSearchMailboxModule(); - - IndexAttachments indexAttachments = testee.provideIndexAttachments(configuration); - - assertThat(indexAttachments).isEqualTo(IndexAttachments.YES); - } - - @Test - public void validateHostsConfigurationOptionsShouldThrowWhenNoHostSpecify() throws Exception { - expectedException.expect(ConfigurationException.class); - expectedException.expectMessage("You should specify either (" + ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + ") or " + ELASTICSEARCH_HOSTS); - - ElasticSearchMailboxModule.validateHostsConfigurationOptions( - Optional.empty(), - Optional.empty(), - Optional.empty()); - } - - @Test - public void validateHostsConfigurationOptionsShouldThrowWhenMonoAndMultiHostSpecified() throws Exception { - expectedException.expect(ConfigurationException.class); - expectedException.expectMessage("You should choose between mono host set up and " + ELASTICSEARCH_HOSTS); - - ElasticSearchMailboxModule.validateHostsConfigurationOptions( - Optional.of("localhost"), - Optional.of(9200), - Optional.of("localhost:9200")); - } - - @Test - public void validateHostsConfigurationOptionsShouldThrowWhenMonoHostWithoutPort() throws Exception { - expectedException.expect(ConfigurationException.class); - expectedException.expectMessage(ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + " should be specified together"); - - ElasticSearchMailboxModule.validateHostsConfigurationOptions( - Optional.of("localhost"), - Optional.empty(), - Optional.empty()); - } - - @Test - public void validateHostsConfigurationOptionsShouldThrowWhenMonoHostWithoutAddress() throws Exception { - expectedException.expect(ConfigurationException.class); - expectedException.expectMessage(ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + " should be specified together"); - - ElasticSearchMailboxModule.validateHostsConfigurationOptions( - Optional.empty(), - Optional.of(9200), - Optional.empty()); - } - - @Test - public void validateHostsConfigurationOptionsShouldAcceptMonoHostConfiguration() throws Exception { - ElasticSearchMailboxModule.validateHostsConfigurationOptions( - Optional.of("localhost"), - Optional.of(9200), - Optional.empty()); - } - - @Test - public void validateHostsConfigurationOptionsShouldAcceptMultiHostConfiguration() throws Exception { - ElasticSearchMailboxModule.validateHostsConfigurationOptions( - Optional.empty(), - Optional.empty(), - Optional.of("localhost:9200")); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/server/container/util-java8/src/main/java/org/apache/james/util/Host.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/Host.java b/server/container/util-java8/src/main/java/org/apache/james/util/Host.java index 3927c73..4776f06 100644 --- a/server/container/util-java8/src/main/java/org/apache/james/util/Host.java +++ b/server/container/util-java8/src/main/java/org/apache/james/util/Host.java @@ -123,7 +123,8 @@ public class Host { public final boolean equals(Object object) { if (object instanceof Host) { Host that = (Host) object; - return Objects.equal(this.hostName, that.hostName) && Objects.equal(this.port, that.port); + return Objects.equal(this.hostName, that.hostName) + && Objects.equal(this.port, that.port); } return false; } http://git-wip-us.apache.org/repos/asf/james-project/blob/f3b6ac5d/src/site/xdoc/server/config-elasticsearch.xml ---------------------------------------------------------------------- diff --git a/src/site/xdoc/server/config-elasticsearch.xml b/src/site/xdoc/server/config-elasticsearch.xml index 2b9ad23..b5ca6c8 100644 --- a/src/site/xdoc/server/config-elasticsearch.xml +++ b/src/site/xdoc/server/config-elasticsearch.xml @@ -58,9 +58,12 @@ <dd>Number of replica for index provisionned by James</dd> <dt><strong>elasticsearch.index.name</strong></dt> <dd>Name of the index backed by the alias. It will be created if missing.</dd> - <dt><strong>elasticsearch.alias.name</strong></dt> - <dd>Name of the alias to use with Apache James. It will be created if missing. - The target of the alias is the index name configured above.</dd> + <dt><strong>elasticsearch.alias.read.name</strong></dt> + <dd>Name of the alias to use by Apache James for reads. It will be created if missing. + The target of the alias is the index name configured above.</dd> + <dt><strong>elasticsearch.alias.write.name</strong></dt> + <dd>Name of the alias to use by Apache James for writes. It will be created if missing. + The target of the alias is the index name configured above.</dd> <dt><strong>elasticsearch.retryConnection.maxRetries</strong></dt> <dd>Number of retries when connecting the cluster</dd> <dt><strong>elasticsearch.retryConnection.minDelay</strong></dt> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org