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

[james-project] 16/19: JAMES-2763 Indexes creation should be done in ConfigurationPerformers

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 a532512ea592160e6bcb066b085f7ca02978f7c6
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue May 28 10:22:07 2019 +0700

    JAMES-2763 Indexes creation should be done in ConfigurationPerformers
---
 .../mailbox/ElasticSearchMailboxModule.java        | 87 ++++++++++++++++------
 .../mailbox/ElasticSearchQuotaSearcherModule.java  | 63 +++++++++++++++-
 ...esWithNonCompatibleElasticSearchServerTest.java |  5 +-
 3 files changed, 126 insertions(+), 29 deletions(-)

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 8bf293c..9c43034 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
@@ -25,7 +25,9 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.time.Duration;
 import java.time.LocalDateTime;
+import java.util.List;
 
+import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
@@ -35,6 +37,7 @@ import org.apache.commons.lang3.time.DurationFormatUtils;
 import org.apache.james.backends.es.ClientProviderImpl;
 import org.apache.james.backends.es.ElasticSearchConfiguration;
 import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.elasticsearch.ElasticSearchMailboxConfiguration;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
@@ -47,13 +50,13 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
-import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaConfiguration;
-import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
+import org.apache.james.utils.ConfigurationPerformer;
 import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
@@ -63,6 +66,55 @@ import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
 
 public class ElasticSearchMailboxModule extends AbstractModule {
+
+    static class MailboxIndexCreator implements Startable {
+
+        private final ElasticSearchConfiguration configuration;
+        private final ElasticSearchMailboxConfiguration mailboxConfiguration;
+        private final RestHighLevelClient client;
+
+        @Inject
+        MailboxIndexCreator(ElasticSearchConfiguration configuration,
+                            ElasticSearchMailboxConfiguration mailboxConfiguration,
+                            RestHighLevelClient client) {
+            this.configuration = configuration;
+            this.mailboxConfiguration = mailboxConfiguration;
+            this.client = client;
+        }
+
+        void createIndex() throws IOException {
+            MailboxIndexCreationUtil.prepareClient(client,
+                mailboxConfiguration.getReadAliasMailboxName(),
+                mailboxConfiguration.getWriteAliasMailboxName(),
+                mailboxConfiguration.getIndexMailboxName(),
+                configuration);
+        }
+    }
+
+    static class ElasticSearchMailboxIndexCreationPerformer implements ConfigurationPerformer {
+
+        private final MailboxIndexCreator mailboxIndexCreator;
+
+        @Inject
+        ElasticSearchMailboxIndexCreationPerformer(MailboxIndexCreator mailboxIndexCreator) {
+            this.mailboxIndexCreator = mailboxIndexCreator;
+        }
+
+        @Override
+        public void initModule() {
+            try {
+                mailboxIndexCreator.createIndex();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public List<Class<? extends Startable>> forClasses() {
+            return ImmutableList.of(MailboxIndexCreator.class);
+        }
+    }
+
     private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchMailboxModule.class);
 
     public static final String ELASTICSEARCH_CONFIGURATION_NAME = "elasticsearch";
@@ -78,6 +130,10 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), MailboxListener.GroupMailboxListener.class)
             .addBinding()
             .to(ElasticSearchListeningMessageSearchIndex.class);
+
+        Multibinder.newSetBinder(binder(), ConfigurationPerformer.class)
+            .addBinding()
+            .to(ElasticSearchMailboxIndexCreationPerformer.class);
     }
 
     @Provides
@@ -133,12 +189,10 @@ public class ElasticSearchMailboxModule extends AbstractModule {
 
     @Provides
     @Singleton
-    protected RestHighLevelClient provideClient(ElasticSearchConfiguration configuration,
-                                   ElasticSearchMailboxConfiguration mailboxConfiguration,
-                                   ElasticSearchQuotaConfiguration quotaConfiguration) {
+    protected RestHighLevelClient provideClient(ElasticSearchConfiguration configuration) {
 
         Duration waitDelay = Duration.ofMillis(configuration.getMinDelay());
-        return Mono.fromCallable(() -> connectToCluster(configuration, mailboxConfiguration, quotaConfiguration))
+        return Mono.fromCallable(() -> connectToCluster(configuration))
             .doOnError(e -> LOGGER.warn("Error establishing ElasticSearch connection. Next retry scheduled in {}",
                 DurationFormatUtils.formatDurationWords(waitDelay.toMillis(), true, true),
                 e))
@@ -147,26 +201,11 @@ public class ElasticSearchMailboxModule extends AbstractModule {
             .block();
     }
 
-    private RestHighLevelClient connectToCluster(ElasticSearchConfiguration configuration,
-                                    ElasticSearchMailboxConfiguration mailboxConfiguration,
-                                    ElasticSearchQuotaConfiguration quotaConfiguration) throws IOException {
+    private RestHighLevelClient connectToCluster(ElasticSearchConfiguration configuration) throws IOException {
         LOGGER.info("Trying to connect to ElasticSearch service at {}", LocalDateTime.now());
 
-        RestHighLevelClient client = ClientProviderImpl.fromHosts(configuration.getHosts(), configuration.getClusterName()).get();
-
-        MailboxIndexCreationUtil.prepareClient(client,
-            mailboxConfiguration.getReadAliasMailboxName(),
-            mailboxConfiguration.getWriteAliasMailboxName(),
-            mailboxConfiguration.getIndexMailboxName(),
-            configuration);
-
-        QuotaSearchIndexCreationUtil.prepareClient(client,
-            quotaConfiguration.getReadAliasQuotaRatioName(),
-            quotaConfiguration.getWriteAliasQuotaRatioName(),
-            quotaConfiguration.getIndexQuotaRatioName(),
-            configuration);
-
-        return client;
+        return ClientProviderImpl.fromHosts(configuration.getHosts(), configuration.getClusterName())
+            .get();
     }
 
     @Provides
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
index c3eb9be..05b4eb8 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
@@ -22,27 +22,84 @@ package org.apache.james.modules.mailbox;
 import static org.apache.james.modules.mailbox.ElasticSearchMailboxModule.ELASTICSEARCH_CONFIGURATION_NAME;
 
 import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+
+import javax.inject.Inject;
 
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.backends.es.ElasticSearchConfiguration;
 import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.quota.search.QuotaSearcher;
 import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaConfiguration;
 import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaSearcher;
+import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
 import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
+import org.apache.james.utils.ConfigurationPerformer;
 import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
 
 public class ElasticSearchQuotaSearcherModule extends AbstractModule {
+
+    static class ElasticSearchQuotaIndexCreator implements Startable {
+        private final ElasticSearchConfiguration configuration;
+        private final ElasticSearchQuotaConfiguration quotaConfiguration;
+        private final RestHighLevelClient client;
+
+        @Inject
+        ElasticSearchQuotaIndexCreator(ElasticSearchConfiguration configuration,
+                                       ElasticSearchQuotaConfiguration quotaConfiguration,
+                                       RestHighLevelClient client) {
+            this.configuration = configuration;
+            this.quotaConfiguration = quotaConfiguration;
+            this.client = client;
+        }
+
+        void createIndex() throws IOException {
+            QuotaSearchIndexCreationUtil.prepareClient(client,
+                quotaConfiguration.getReadAliasQuotaRatioName(),
+                quotaConfiguration.getWriteAliasQuotaRatioName(),
+                quotaConfiguration.getIndexQuotaRatioName(),
+                configuration);
+        }
+    }
+
+    static class ElasticSearchQuotaIndexCreationPerformer implements ConfigurationPerformer {
+
+        private final ElasticSearchQuotaIndexCreator indexCreator;
+
+        @Inject
+        ElasticSearchQuotaIndexCreationPerformer(ElasticSearchQuotaIndexCreator indexCreator) {
+            this.indexCreator = indexCreator;
+        }
+
+        @Override
+        public void initModule() {
+            try {
+                indexCreator.createIndex();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public List<Class<? extends Startable>> forClasses() {
+            return ImmutableList.of(ElasticSearchQuotaIndexCreator.class);
+        }
+    }
+
     private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchQuotaSearcherModule.class);
 
     @Override
@@ -50,6 +107,10 @@ public class ElasticSearchQuotaSearcherModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), MailboxListener.GroupMailboxListener.class)
             .addBinding()
             .to(ElasticSearchQuotaMailboxListener.class);
+
+        Multibinder.newSetBinder(binder(), ConfigurationPerformer.class)
+            .addBinding()
+            .to(ElasticSearchQuotaIndexCreationPerformer.class);
     }
 
     @Provides
@@ -59,8 +120,6 @@ public class ElasticSearchQuotaSearcherModule extends AbstractModule {
             configuration.getReadAliasQuotaRatioName());
     }
 
-
-
     @Provides
     @Singleton
     private ElasticSearchQuotaConfiguration getElasticSearchQuotaConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
index 87347f6..3a4c0b5 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
@@ -28,12 +28,11 @@ import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.store.search.PDFTextExtractor;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.util.docker.Images;
+import org.elasticsearch.ElasticsearchStatusException;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import com.google.inject.ProvisionException;
-
 class JamesWithNonCompatibleElasticSearchServerTest {
 
     private static final int LIMIT_MAX_MESSAGES = 10;
@@ -59,7 +58,7 @@ class JamesWithNonCompatibleElasticSearchServerTest {
     @Test
     void jamesShouldStopWhenStartingWithANonCompatibleElasticSearchServer(GuiceJamesServer server) throws Exception {
         assertThatThrownBy(server::start)
-            .isInstanceOf(ProvisionException.class);
+            .isInstanceOf(ElasticsearchStatusException.class);
 
         assertThat(server.isStarted())
             .isFalse();


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