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 2017/04/21 03:57:00 UTC

[01/17] james-project git commit: JAMES-1999 New util for retry executor

Repository: james-project
Updated Branches:
  refs/heads/master b0d35b70b -> 2a4984533


JAMES-1999 New util for retry executor


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/6c5912f1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/6c5912f1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/6c5912f1

Branch: refs/heads/master
Commit: 6c5912f16d6a352b8a501cb11efcf4d39daf2c41
Parents: b0d35b7
Author: quynhn <qn...@linagora.com>
Authored: Fri Apr 14 09:47:30 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 07:51:48 2017 +0700

----------------------------------------------------------------------
 server/container/guice/guice-common/pom.xml     |   9 ++
 .../apache/james/utils/RetryExecutorUtil.java   |  38 ++++++
 .../org/apache/james/utils/FaultyService.java   |  24 ++++
 .../james/utils/RetryExecutorUtilTest.java      | 124 +++++++++++++++++++
 4 files changed, 195 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6c5912f1/server/container/guice/guice-common/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/pom.xml b/server/container/guice/guice-common/pom.xml
index 3186b34..4f63bfa 100644
--- a/server/container/guice/guice-common/pom.xml
+++ b/server/container/guice/guice-common/pom.xml
@@ -277,6 +277,10 @@
                     <scope>test</scope>
                 </dependency>
                 <dependency>
+                    <groupId>com.nurkiewicz.asyncretry</groupId>
+                    <artifactId>asyncretry</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>org.assertj</groupId>
                     <artifactId>assertj-core</artifactId>
                     <version>${assertj-3.version}</version>
@@ -289,6 +293,11 @@
                     <type>test-jar</type>
                 </dependency>
                 <dependency>
+                    <groupId>org.mockito</groupId>
+                    <artifactId>mockito-core</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
                     <groupId>org.slf4j</groupId>
                     <artifactId>slf4j-api</artifactId>
                 </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/6c5912f1/server/container/guice/guice-common/src/main/java/org/apache/james/utils/RetryExecutorUtil.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/RetryExecutorUtil.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/RetryExecutorUtil.java
new file mode 100644
index 0000000..32b807e
--- /dev/null
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/RetryExecutorUtil.java
@@ -0,0 +1,38 @@
+/****************************************************************
+ * 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.utils;
+
+import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
+
+public class RetryExecutorUtil {
+
+    public static final int INITIAL_DELAY_MILLIS = 500;
+    public static final int MULTIPLIER = 2;
+
+    public static AsyncRetryExecutor retryOnExceptions(AsyncRetryExecutor executor, int maxRetries, int minDelay, Class<? extends Throwable>... clazz) {
+        return executor
+            .retryOn(clazz)
+            .withExponentialBackoff(INITIAL_DELAY_MILLIS, MULTIPLIER)
+            .withProportionalJitter()
+            .withMaxRetries(maxRetries)
+            .withMinDelay(minDelay);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6c5912f1/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FaultyService.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FaultyService.java b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FaultyService.java
new file mode 100644
index 0000000..12d8f92
--- /dev/null
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FaultyService.java
@@ -0,0 +1,24 @@
+/****************************************************************
+ * 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.utils;
+
+public interface FaultyService {
+    String faultyService();
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6c5912f1/server/container/guice/guice-common/src/test/java/org/apache/james/utils/RetryExecutorUtilTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/RetryExecutorUtilTest.java b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/RetryExecutorUtilTest.java
new file mode 100644
index 0000000..32477ab
--- /dev/null
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/RetryExecutorUtilTest.java
@@ -0,0 +1,124 @@
+/****************************************************************
+ * 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.utils;
+
+import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
+import com.nurkiewicz.asyncretry.RetryExecutor;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.BDDMockito.given;
+
+public class RetryExecutorUtilTest {
+    private static final int MAX_RETRIES = 3;
+    private static final int MIN_DELAY = 3000;
+    @Mock
+    protected FaultyService serviceMock;
+
+    private RetryExecutor retryExecutor;
+    private ScheduledExecutorService scheduledExecutor;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        scheduledExecutor.shutdownNow();
+    }
+
+    @Test
+    public void retryOnExceptionsAndExecuteShouldRethrowWhenScheduledServiceAlwaysThrowException() throws Exception {
+        given(serviceMock.faultyService())
+                .willThrow(IllegalArgumentException.class)
+                .willThrow(IllegalArgumentException.class)
+                .willThrow(IllegalArgumentException.class)
+                .willThrow(IllegalArgumentException.class);
+
+        retryExecutor = RetryExecutorUtil.retryOnExceptions(new AsyncRetryExecutor(scheduledExecutor), MAX_RETRIES, MIN_DELAY, IllegalArgumentException.class);
+
+        assertThatThrownBy(() -> retryExecutor.getWithRetry(serviceMock::faultyService).get())
+            .isInstanceOf(ExecutionException.class)
+            .hasCauseInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void retryOnExceptionsAndExecuteShouldRetryWhenMatchExceptionAndSuccess() throws Exception {
+        given(serviceMock.faultyService())
+                .willThrow(IllegalArgumentException.class)
+                .willReturn("Foo");
+        retryExecutor = RetryExecutorUtil.retryOnExceptions(new AsyncRetryExecutor(scheduledExecutor), MAX_RETRIES, MIN_DELAY, IllegalArgumentException.class);
+
+        final CompletableFuture<String> future = retryExecutor.getWithRetry(serviceMock::faultyService);
+
+        assertThat(future.get()).isEqualTo("Foo");
+    }
+
+    @Test
+    public void retryOnExceptionsAndExecuteShouldNotRetryWhenDoesNotMatchException() throws Exception {
+        given(serviceMock.faultyService())
+                .willThrow(IllegalStateException.class)
+                .willReturn("Foo");
+
+        retryExecutor = RetryExecutorUtil.retryOnExceptions(new AsyncRetryExecutor(scheduledExecutor), MAX_RETRIES, MIN_DELAY, IllegalArgumentException.class);
+
+        assertThatThrownBy(() -> retryExecutor.getWithRetry(serviceMock::faultyService).get())
+                .isInstanceOf(ExecutionException.class)
+                .hasCauseInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void retryOnExceptionsAndExecuteShouldRetryWithMaxTimesAndReturnValue() throws Exception {
+        given(serviceMock.faultyService())
+                .willThrow(IllegalStateException.class, IllegalStateException.class, IllegalStateException.class)
+                .willReturn("Foo");
+
+        retryExecutor = RetryExecutorUtil.retryOnExceptions(new AsyncRetryExecutor(scheduledExecutor), MAX_RETRIES, MIN_DELAY, IllegalStateException.class);
+
+        final CompletableFuture<String> future = retryExecutor.getWithRetry(serviceMock::faultyService);
+
+        assertThat(future.get()).isEqualTo("Foo");
+    }
+
+    @Test
+    public void retryOnExceptionsAndExecuteShouldFailIfFailMoreThanMaxRetry() throws Exception {
+        given(serviceMock.faultyService()).
+            willThrow(IllegalStateException.class, IllegalStateException.class, IllegalStateException.class, IllegalStateException.class).
+            willReturn("Foo");
+
+        retryExecutor = RetryExecutorUtil.retryOnExceptions(new AsyncRetryExecutor(scheduledExecutor), MAX_RETRIES, MIN_DELAY, IllegalStateException.class);
+
+        assertThatThrownBy(() -> retryExecutor.getWithRetry(serviceMock::faultyService).get())
+                .isInstanceOf(ExecutionException.class)
+                .hasCauseInstanceOf(IllegalStateException.class);
+    }
+}
\ No newline at end of file


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


[04/17] james-project git commit: JAMES-1999 ElasticSearchModule can bind configuration file

Posted by bt...@apache.org.
JAMES-1999 ElasticSearchModule can bind configuration file


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5e1f5727
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5e1f5727
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5e1f5727

Branch: refs/heads/master
Commit: 5e1f5727f48bae035661892fdc256543e0da168c
Parents: bb68be1
Author: quynhn <qn...@linagora.com>
Authored: Tue Apr 18 17:31:45 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 07:52:23 2017 +0700

----------------------------------------------------------------------
 .../mailbox/ElasticSearchConfiguration.java     | 31 ++++++++++++++++++++
 .../mailbox/ElasticSearchMailboxModule.java     | 31 ++++++++++++++------
 2 files changed, 53 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/5e1f5727/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
new file mode 100644
index 0000000..0c39e81
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchConfiguration.java
@@ -0,0 +1,31 @@
+/****************************************************************
+ * 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 org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+import java.io.FileNotFoundException;
+
+public interface ElasticSearchConfiguration {
+
+    PropertiesConfiguration getConfiguration() throws FileNotFoundException, ConfigurationException;
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/5e1f5727/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 48c4145..e114938 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
@@ -27,7 +27,6 @@ import javax.inject.Singleton;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.james.backends.es.ClientProvider;
 import org.apache.james.backends.es.ClientProviderImpl;
 import org.apache.james.backends.es.IndexCreationFactory;
 import org.apache.james.backends.es.IndexName;
@@ -79,8 +78,8 @@ public class ElasticSearchMailboxModule extends AbstractModule {
 
     @Provides
     @Singleton
-    protected Client provideClientProvider(FileSystem fileSystem, AsyncRetryExecutor executor) throws ConfigurationException, FileNotFoundException, ExecutionException, InterruptedException {
-        PropertiesConfiguration propertiesReader = new PropertiesConfiguration(fileSystem.getFile(ES_CONFIG_FILE));
+    protected Client provideClientProvider(ElasticSearchConfiguration elasticSearchConfiguration, 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);
 
@@ -89,9 +88,17 @@ public class ElasticSearchMailboxModule extends AbstractModule {
             .get();
     }
 
-    private Client createClientAndIndex(ClientProvider clientProvider, PropertiesConfiguration propertiesReader) {
-        LOGGER.info("Trying to connect to ElasticSearch service");
-        Client client = clientProvider.get();
+    @Provides
+    @Singleton
+    ElasticSearchConfiguration getElasticSearchConfiguration(FileSystem fileSystem) {
+        return () -> getConfiguration(fileSystem);
+    }
+
+    private PropertiesConfiguration getConfiguration(FileSystem fileSystem) throws FileNotFoundException, ConfigurationException {
+        return new PropertiesConfiguration(fileSystem.getFile(ES_CONFIG_FILE));
+    }
+
+    private Client createIndexAndMapping(Client client, PropertiesConfiguration propertiesReader) {
         IndexCreationFactory.createIndex(client,
             MailboxElasticsearchConstants.MAILBOX_INDEX,
             propertiesReader.getInt("elasticsearch.nb.shards"),
@@ -103,7 +110,13 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         return client;
     }
 
-    private static ClientProvider connectToCluster(PropertiesConfiguration propertiesReader) throws ConfigurationException {
+    private Client connectToCluster(PropertiesConfiguration propertiesReader) throws ConfigurationException {
+        LOGGER.info("Trying to connect to ElasticSearch service");
+
+        return createIndexAndMapping(createClient(propertiesReader), propertiesReader);
+    }
+
+    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));
@@ -111,9 +124,9 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         validateHostsConfigurationOptions(monoHostAddress, monoHostPort, multiHosts);
 
         if (monoHostAddress.isPresent()) {
-            return ClientProviderImpl.forHost(monoHostAddress.get(), monoHostPort.get());
+            return ClientProviderImpl.forHost(monoHostAddress.get(), monoHostPort.get()).get();
         } else {
-            return ClientProviderImpl.fromHostsString(multiHosts.get());
+            return ClientProviderImpl.fromHostsString(multiHosts.get()).get();
         }
     }
 


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


[07/17] james-project git commit: JAMES-2004 Cassandra should try to connect locally by default

Posted by bt...@apache.org.
JAMES-2004 Cassandra should try to connect locally by default


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b62d8b6c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b62d8b6c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b62d8b6c

Branch: refs/heads/master
Commit: b62d8b6c19ef849952d5c53eb0930a6f9fb047e0
Parents: ac3fb27
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 13:35:55 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 .../modules/mailbox/CassandraSessionModule.java | 66 +++++++++++---------
 1 file changed, 38 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/b62d8b6c/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
index 7180599..9f11022 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
@@ -18,18 +18,15 @@
  ****************************************************************/
 package org.apache.james.modules.mailbox;
 
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.PerHostPercentileTracker;
-import com.datastax.driver.core.QueryLogger;
-import com.datastax.driver.core.Session;
-import com.datastax.driver.core.exceptions.NoHostAvailableException;
-import com.github.steveash.guavate.Guavate;
-import com.google.inject.AbstractModule;
-import com.google.inject.Provides;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
-import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
-import com.nurkiewicz.asyncretry.function.RetryCallable;
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.james.backends.cassandra.components.CassandraModule;
@@ -39,20 +36,24 @@ import org.apache.james.backends.cassandra.init.ClusterBuilder;
 import org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactory;
 import org.apache.james.backends.cassandra.init.QueryLoggerConfiguration;
 import org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory;
-import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.util.Host;
+import org.apache.james.utils.PropertiesProvider;
 import org.apache.james.utils.RetryExecutorUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.PerHostPercentileTracker;
+import com.datastax.driver.core.QueryLogger;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.exceptions.NoHostAvailableException;
+import com.github.steveash.guavate.Guavate;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
+import com.nurkiewicz.asyncretry.function.RetryCallable;
 
 public class CassandraSessionModule extends AbstractModule {
     private static final Logger LOGGER = LoggerFactory.getLogger(CassandraSessionModule.class);
@@ -60,8 +61,10 @@ public class CassandraSessionModule extends AbstractModule {
     private static final int DEFAULT_CONNECTION_MAX_RETRIES = 10;
     private static final int DEFAULT_CONNECTION_MIN_DELAY = 5000;
     private static final long CASSANDRA_HIGHEST_TRACKABLE_LATENCY_MILLIS = TimeUnit.SECONDS.toMillis(10);
-    public static final int DEFAULT_REPLICATION_FACTOR = 1;
-    public static final String DEFAULT_KEYSPACE = "apache_james";
+    private static final int DEFAULT_REPLICATION_FACTOR = 1;
+    private static final String DEFAULT_KEYSPACE = "apache_james";
+    private static final String CASSANDRA_NODES = "cassandra.nodes";
+    private static final String LOCALHOST = "127.0.0.1";
 
     @Override
     protected void configure() {
@@ -87,8 +90,8 @@ public class CassandraSessionModule extends AbstractModule {
 
     @Provides
     @Singleton
-    CassandraSessionConfiguration getCassandraSessionConfiguration(FileSystem fileSystem) {
-        return () -> getConfiguration(fileSystem);
+    CassandraSessionConfiguration getCassandraSessionConfiguration(PropertiesProvider propertiesProvider) {
+        return () -> getConfiguration(propertiesProvider);
     }
 
     @Provides
@@ -123,7 +126,7 @@ public class CassandraSessionModule extends AbstractModule {
     }
 
     private List<Host> listCassandraServers(PropertiesConfiguration configuration) {
-        String[] ipAndPorts = configuration.getStringArray("cassandra.nodes");
+        String[] ipAndPorts = configuration.getStringArray(CASSANDRA_NODES);
 
         return Arrays.stream(ipAndPorts)
                 .map(string -> Host.parseConfString(string, ClusterBuilder.DEFAULT_CASSANDRA_PORT))
@@ -177,7 +180,14 @@ public class CassandraSessionModule extends AbstractModule {
         return new AsyncRetryExecutor(scheduler);
     }
 
-    private PropertiesConfiguration getConfiguration(FileSystem fileSystem) throws FileNotFoundException, ConfigurationException {
-        return new PropertiesConfiguration(fileSystem.getFile(FileSystem.FILE_PROTOCOL_AND_CONF + "cassandra.properties"));
+    private PropertiesConfiguration getConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
+        try {
+            return propertiesProvider.getConfiguration("cassandra");
+        } catch (FileNotFoundException e) {
+            LOGGER.warn("Could not locate cassandra configuration file. Defaulting to node " + LOCALHOST + ":9042");
+            PropertiesConfiguration propertiesConfiguration = new PropertiesConfiguration();
+            propertiesConfiguration.addProperty(CASSANDRA_NODES, LOCALHOST);
+            return propertiesConfiguration;
+        }
     }
 }


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


[15/17] james-project git commit: JAMES-2004 Provide logs for guice-memory tests

Posted by bt...@apache.org.
JAMES-2004 Provide logs for guice-memory tests


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/95ba2ae1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/95ba2ae1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/95ba2ae1

Branch: refs/heads/master
Commit: 95ba2ae10b8b39bf33e1322cc7c123c883c86c98
Parents: 50c481d
Author: benwa <bt...@linagora.com>
Authored: Thu Apr 20 09:29:05 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:29:39 2017 +0700

----------------------------------------------------------------------
 server/container/guice/memory-guice/pom.xml     |  6 ++++
 .../src/test/resources/logback-test.xml         | 37 ++++++++++++++++++++
 2 files changed, 43 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/95ba2ae1/server/container/guice/memory-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/pom.xml b/server/container/guice/memory-guice/pom.xml
index 8cffde9..b9ce8b0 100644
--- a/server/container/guice/memory-guice/pom.xml
+++ b/server/container/guice/memory-guice/pom.xml
@@ -277,6 +277,12 @@
                     <version>${assertj-3.version}</version>
                     <scope>test</scope>
                 </dependency>
+                <dependency>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                    <version>1.1.7</version>
+                    <scope>test</scope>
+                </dependency>
             </dependencies>
         </profile>
         <profile>

http://git-wip-us.apache.org/repos/asf/james-project/blob/95ba2ae1/server/container/guice/memory-guice/src/test/resources/logback-test.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/resources/logback-test.xml b/server/container/guice/memory-guice/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..3487f0b
--- /dev/null
+++ b/server/container/guice/memory-guice/src/test/resources/logback-test.xml
@@ -0,0 +1,37 @@
+<?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.
+ -->
+<configuration>
+
+    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
+        <resetJUL>true</resetJUL>
+    </contextListener>
+
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} %highlight([%-5level]) %logger{15} - %msg%n%rEx</pattern>
+            <immediateFlush>false</immediateFlush>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="CONSOLE" />
+    </root>
+
+</configuration>


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


[16/17] james-project git commit: JAMES-2004 Re-add missing configuration file for Guice-memory

Posted by bt...@apache.org.
JAMES-2004 Re-add missing configuration file for Guice-memory


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4624e5d7
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4624e5d7
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4624e5d7

Branch: refs/heads/master
Commit: 4624e5d720cebfcfa197348ac912e5eba5319b4f
Parents: 95ba2ae
Author: benwa <bt...@linagora.com>
Authored: Thu Apr 20 09:43:41 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:29:39 2017 +0700

----------------------------------------------------------------------
 .../src/test/resources/imapserver.xml           | 54 ++++++++++++++++++++
 1 file changed, 54 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4624e5d7/server/container/guice/memory-guice/src/test/resources/imapserver.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/resources/imapserver.xml b/server/container/guice/memory-guice/src/test/resources/imapserver.xml
new file mode 100644
index 0000000..ff478a9
--- /dev/null
+++ b/server/container/guice/memory-guice/src/test/resources/imapserver.xml
@@ -0,0 +1,54 @@
+<?xml version="1.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.
+-->
+
+
+<imapservers>
+	<imapserver enabled="true">
+		<jmxName>imapserver</jmxName>
+		<bind>0.0.0.0:1143</bind>
+		<connectionBacklog>200</connectionBacklog>
+		<tls socketTLS="false" startTLS="false">
+			<!-- To create a new keystore execute:
+            keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore
+              -->
+			<keystore>file://conf/keystore</keystore>
+			<secret>james72laBalle</secret>
+			<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
+		</tls>
+		<connectionLimit>0</connectionLimit>
+		<connectionLimitPerIP>0</connectionLimitPerIP>
+	</imapserver>
+	<imapserver enabled="true">
+		<jmxName>imapserver-ssl</jmxName>
+		<bind>0.0.0.0:1993</bind>
+		<connectionBacklog>200</connectionBacklog>
+		<tls socketTLS="false" startTLS="false">
+			<!-- To create a new keystore execute:
+              keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore
+             -->
+			<keystore>file://conf/keystore</keystore>
+			<secret>james72laBalle</secret>
+			<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
+		</tls>
+		<connectionLimit>0</connectionLimit>
+		<connectionLimitPerIP>0</connectionLimitPerIP>
+	</imapserver>
+</imapservers>


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


[05/17] james-project git commit: JAMES-1999 Add integration testing for retrying connection

Posted by bt...@apache.org.
JAMES-1999 Add integration testing for retrying connection

JAMES-1999 Decrease time for waiting


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/445680d1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/445680d1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/445680d1

Branch: refs/heads/master
Commit: 445680d1a45fed2c8905896db53187d45063fbdd
Parents: 5e1f572
Author: quynhn <qn...@linagora.com>
Authored: Tue Apr 18 17:33:13 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 07:52:53 2017 +0700

----------------------------------------------------------------------
 .../org/apache/james/DockerCassandraRule.java   |   4 +
 .../apache/james/DockerElasticSearchRule.java   | 103 +++++++++++++++
 .../JamesServerWithRetryConnectionTest.java     | 124 +++++++++++++++++++
 3 files changed, 231 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/445680d1/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
index 8b9a000..f5849e6 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
@@ -87,4 +87,8 @@ public class DockerCassandraRule implements GuiceModuleTestRule {
                     .map(binding -> binding.getHostPortSpec())
                     .findFirst().get());
     }
+
+    public SwarmGenericContainer getCassandraContainer() {
+        return cassandraContainer;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/445680d1/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
new file mode 100644
index 0000000..3dd19c2
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java
@@ -0,0 +1,103 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james;
+
+import com.google.inject.Module;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.james.modules.mailbox.CassandraSessionConfiguration;
+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 org.testcontainers.shaded.com.github.dockerjava.api.model.ExposedPort;
+import org.testcontainers.shaded.com.github.dockerjava.api.model.Ports.Binding;
+
+import java.util.Arrays;
+
+
+public class DockerElasticSearchRule implements GuiceModuleTestRule {
+
+    private static final int ELASTIC_SEARCH_PORT = 9300;
+    public static final int ELASTIC_SEARCH_HTTP_PORT = 9200;
+
+    private static boolean isBindingToEveryThing(Binding binding) {
+        String bindingIp = binding.getHostIp();
+        return bindingIp == null || bindingIp.equals("0.0.0.0");
+    }
+
+    public PropertiesConfiguration getElasticSearchConfigurationForDocker() {
+        PropertiesConfiguration configuration = new PropertiesConfiguration();
+
+        configuration.addProperty("elasticsearch.masterHost", getIp());
+        configuration.addProperty("elasticsearch.port", ELASTIC_SEARCH_PORT);
+
+        configuration.addProperty("elasticsearch.nb.shards", 1);
+        configuration.addProperty("elasticsearch.nb.replica", 0);
+        configuration.addProperty("elasticsearch.retryConnection.maxRetries", 7);
+        configuration.addProperty("elasticsearch.retryConnection.minDelay", 30);
+        configuration.addProperty("elasticsearch.indexAttachments", false);
+        configuration.addProperty("elasticsearch.http.host", getIp());
+        configuration.addProperty("elasticsearch.http.port", ELASTIC_SEARCH_HTTP_PORT);
+        configuration.addProperty("elasticsearch.metrics.reports.enabled", true);
+        configuration.addProperty("elasticsearch.metrics.reports.period", 30);
+        configuration.addProperty("elasticsearch.metrics.reports.index", "james-metrics");
+
+        return configuration;
+    }
+
+    private SwarmGenericContainer elasticSearchContainer = new SwarmGenericContainer("elasticsearch:2.2.2");
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return elasticSearchContainer.apply(base, description);
+    }
+
+    @Override
+    public void await() {
+    }
+
+    @Override
+    public Module getModule() {
+        return (binder) -> binder.bind(ElasticSearchConfiguration.class).toInstance(this::getElasticSearchConfigurationForDocker);
+    }
+
+    public String getIp() {
+        return elasticSearchContainer.getIp();
+    }
+
+    public int getBindingPort() {
+        Binding[] bindings =  elasticSearchContainer
+                .getContainerInfo()
+                .getNetworkSettings()
+                .getPorts()
+                .getBindings()
+                .get(ExposedPort.tcp(ELASTIC_SEARCH_PORT));
+
+        return Integer.valueOf(
+                Arrays.stream(bindings)
+                    .filter(DockerElasticSearchRule::isBindingToEveryThing)
+                    .map(binding -> binding.getHostPortSpec())
+                    .findFirst().get());
+    }
+
+    public SwarmGenericContainer getElasticSearchContainer() {
+        return elasticSearchContainer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/445680d1/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java
new file mode 100644
index 0000000..018bda1
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesServerWithRetryConnectionTest.java
@@ -0,0 +1,124 @@
+/****************************************************************
+ * 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;
+
+import org.apache.james.util.streams.SwarmGenericContainer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.testcontainers.DockerClientFactory;
+import org.testcontainers.shaded.com.google.common.base.Throwables;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class JamesServerWithRetryConnectionTest {
+    private static final int IMAP_PORT = 1143;
+    private static final long WAITING_TIME = TimeUnit.MILLISECONDS.convert(10, TimeUnit.SECONDS);
+
+    private static String getDockerHostIp() {
+        return DockerClientFactory.instance().dockerHostIpAddress();
+    }
+
+    private final DockerCassandraRule dockerCassandraRule = new DockerCassandraRule();
+    private final DockerElasticSearchRule dockerElasticSearchRule = new DockerElasticSearchRule();
+
+    @Rule
+    public CassandraJmapTestRule cassandraJmapTestRule = new CassandraJmapTestRule(dockerCassandraRule,
+            dockerElasticSearchRule);
+
+    private GuiceJamesServer jamesServer;
+    private SocketChannel socketChannel;
+    private ExecutorService executorService;
+
+    @Before
+    public void setUp() throws IOException {
+        executorService = Executors.newFixedThreadPool(1);
+        socketChannel = SocketChannel.open();
+    }
+
+    @After
+    public void after() throws IOException {
+        socketChannel.close();
+        if (jamesServer != null) {
+            jamesServer.stop();
+        }
+        executorService.shutdownNow();
+    }
+
+    @Test
+    public void serverShouldStartAtDefault() throws Exception {
+        jamesServer = cassandraJmapTestRule.jmapServer();
+        assertThatServerStartCorrectly();
+    }
+
+    @Test
+    public void serverShouldRetryToConnectToCassandraWhenStartService() throws Exception {
+        jamesServer = cassandraJmapTestRule.jmapServer();
+        dockerCassandraRule.getCassandraContainer().stop();
+
+        waitToStartContainer(WAITING_TIME, dockerCassandraRule.getCassandraContainer());
+
+        assertThatServerStartCorrectly();
+    }
+
+    @Test
+    public void serverShouldRetryToConnectToElasticSearchWhenStartService() throws Exception {
+        jamesServer = cassandraJmapTestRule.jmapServer();
+        dockerElasticSearchRule.getElasticSearchContainer().stop();
+
+        waitToStartContainer(WAITING_TIME, dockerElasticSearchRule.getElasticSearchContainer());
+
+        assertThatServerStartCorrectly();
+    }
+
+    private void waitToStartContainer(long waitingTime, SwarmGenericContainer dockerContainer) {
+        executorService.submit(() -> {
+            try {
+                Thread.sleep(waitingTime);
+            } catch (InterruptedException e) {
+                throw Throwables.propagate(e);
+            }
+            dockerContainer.start();
+        });
+    }
+
+    private void assertThatServerStartCorrectly() throws Exception {
+        jamesServer.start();
+        socketChannel.connect(new InetSocketAddress("127.0.0.1", IMAP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server");
+    }
+
+    private String getServerConnectionResponse(SocketChannel socketChannel) throws IOException {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
+        socketChannel.read(byteBuffer);
+        byte[] bytes = byteBuffer.array();
+        return new String(bytes, Charset.forName("UTF-8"));
+    }
+}


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


[08/17] james-project git commit: JAMES-2004 ElasticSearch should try to connect locally when no configuration file

Posted by bt...@apache.org.
JAMES-2004 ElasticSearch should try to connect locally when no configuration file


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b2a14253
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b2a14253
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b2a14253

Branch: refs/heads/master
Commit: b2a1425376eac9f489835289f378b3d5a8915c66
Parents: b62d8b6
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 13:45:39 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 .../mailbox/ElasticSearchMailboxModule.java     | 25 ++++++++++++--------
 1 file changed, 15 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/b2a14253/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 e114938..43ba8ff 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
@@ -42,6 +42,7 @@ import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 import org.apache.james.mailbox.tika.extractor.TikaTextExtractor;
 import org.apache.james.utils.RetryExecutorUtil;
+import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.transport.NoNodeAvailableException;
 import org.slf4j.Logger;
@@ -88,16 +89,6 @@ public class ElasticSearchMailboxModule extends AbstractModule {
             .get();
     }
 
-    @Provides
-    @Singleton
-    ElasticSearchConfiguration getElasticSearchConfiguration(FileSystem fileSystem) {
-        return () -> getConfiguration(fileSystem);
-    }
-
-    private PropertiesConfiguration getConfiguration(FileSystem fileSystem) throws FileNotFoundException, ConfigurationException {
-        return new PropertiesConfiguration(fileSystem.getFile(ES_CONFIG_FILE));
-    }
-
     private Client createIndexAndMapping(Client client, PropertiesConfiguration propertiesReader) {
         IndexCreationFactory.createIndex(client,
             MailboxElasticsearchConstants.MAILBOX_INDEX,
@@ -116,6 +107,20 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         return createIndexAndMapping(createClient(propertiesReader), propertiesReader);
     }
 
+    @Provides
+    @Singleton
+    private ElasticSearchConfiguration getElasticSearchConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
+        try {
+            PropertiesConfiguration configuration = propertiesProvider.getConfiguration("elasticsearch");
+            return () -> configuration;
+        } catch (FileNotFoundException e) {
+            LOGGER.warn("Could not find elasticsearch configuration file. Using 127.0.0.1:9300 as contact point");
+            PropertiesConfiguration propertiesConfiguration = new PropertiesConfiguration();
+            propertiesConfiguration.addProperty(ELASTICSEARCH_HOSTS, "127.0.0.1");
+            return () -> propertiesConfiguration;
+        }
+    }
+
     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));


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


[17/17] james-project git commit: JAMES-1921 Add RawMailQueueItemDecoratorFactory bean to spring file-queue-contect

Posted by bt...@apache.org.
JAMES-1921 Add RawMailQueueItemDecoratorFactory bean to spring file-queue-contect


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2a498453
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2a498453
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2a498453

Branch: refs/heads/master
Commit: 2a49845339372a6d43cb7ff042627fe13505a805
Parents: 4624e5d
Author: Luc DUZAN <ld...@linagora.com>
Authored: Thu Apr 20 14:54:23 2017 +0200
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 10:55:46 2017 +0700

----------------------------------------------------------------------
 .../src/main/resources/META-INF/spring/file-queue-context.xml    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2a498453/server/queue/queue-file/src/main/resources/META-INF/spring/file-queue-context.xml
----------------------------------------------------------------------
diff --git a/server/queue/queue-file/src/main/resources/META-INF/spring/file-queue-context.xml b/server/queue/queue-file/src/main/resources/META-INF/spring/file-queue-context.xml
index d7eaa83..e86d0a2 100644
--- a/server/queue/queue-file/src/main/resources/META-INF/spring/file-queue-context.xml
+++ b/server/queue/queue-file/src/main/resources/META-INF/spring/file-queue-context.xml
@@ -23,5 +23,5 @@
        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
     <bean id="mailqueuefactory" class="org.apache.james.queue.file.FileMailQueueFactory"/>
-
-</beans>
\ No newline at end of file
+    <bean id="rawMailQueueItemDecoratorFactory" class="org.apache.james.queue.api.RawMailQueueItemDecoratorFactory"/>
+</beans>


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


[06/17] james-project git commit: JAMES-2004 Starting JMAP should be made optional, as well as providing it's configuration file

Posted by bt...@apache.org.
JAMES-2004 Starting JMAP should be made optional, as well as providing it's configuration file


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/67e769c1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/67e769c1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/67e769c1

Branch: refs/heads/master
Commit: 67e769c1db3bc99301fce3a44a59a2857a475c7c
Parents: 445680d
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 08:35:59 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:36 2017 +0700

----------------------------------------------------------------------
 .../destination/conf/jmap.properties            |  2 +
 .../cassandra/destination/conf/jmap.properties  |  2 +
 .../sample-configuration/jmap.properties        |  2 +
 .../java/org/apache/james/jmap/JMAPModule.java  | 16 ++++-
 .../modules/protocols/JMAPServerModule.java     | 16 +++--
 .../james/modules/TestJMAPServerModule.java     |  1 +
 .../apache/james/jmap/JMAPConfiguration.java    | 35 +++++++---
 .../java/org/apache/james/jmap/JMAPServer.java  | 73 ++++++++++----------
 .../james/jmap/JMAPConfigurationTest.java       | 28 +++++++-
 .../crypto/JamesSignatureHandlerProvider.java   |  1 +
 10 files changed, 122 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/dockerfiles/run/guice/cassandra-ldap/destination/conf/jmap.properties
----------------------------------------------------------------------
diff --git a/dockerfiles/run/guice/cassandra-ldap/destination/conf/jmap.properties b/dockerfiles/run/guice/cassandra-ldap/destination/conf/jmap.properties
index 34ab451..63e6702 100644
--- a/dockerfiles/run/guice/cassandra-ldap/destination/conf/jmap.properties
+++ b/dockerfiles/run/guice/cassandra-ldap/destination/conf/jmap.properties
@@ -1,5 +1,7 @@
 # Configuration file for JMAP
 
+enabled=true
+
 tls.keystoreURL=file://conf/keystore
 tls.secret=james72laBalle
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/dockerfiles/run/guice/cassandra/destination/conf/jmap.properties
----------------------------------------------------------------------
diff --git a/dockerfiles/run/guice/cassandra/destination/conf/jmap.properties b/dockerfiles/run/guice/cassandra/destination/conf/jmap.properties
index 34ab451..63e6702 100644
--- a/dockerfiles/run/guice/cassandra/destination/conf/jmap.properties
+++ b/dockerfiles/run/guice/cassandra/destination/conf/jmap.properties
@@ -1,5 +1,7 @@
 # Configuration file for JMAP
 
+enabled=true
+
 tls.keystoreURL=file://conf/keystore
 tls.secret=james72laBalle
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/container/guice/memory-guice/sample-configuration/jmap.properties
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/sample-configuration/jmap.properties b/server/container/guice/memory-guice/sample-configuration/jmap.properties
index 071bafb..709ed8e 100644
--- a/server/container/guice/memory-guice/sample-configuration/jmap.properties
+++ b/server/container/guice/memory-guice/sample-configuration/jmap.properties
@@ -1,5 +1,7 @@
 # Configuration file for JMAP
 
+enabled=true
+
 tls.keystoreURL=file://conf/keystore
 tls.secret=james72laBalle
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index de72639..86f3f5e 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.james.jmap;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.EnumSet;
 import java.util.List;
@@ -44,6 +45,8 @@ import org.apache.james.queue.api.MailQueueItemDecoratorFactory;
 import org.apache.james.transport.matchers.RecipientIsLocal;
 import org.apache.james.utils.ConfigurationPerformer;
 import org.apache.james.utils.PropertiesProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Charsets;
@@ -58,6 +61,7 @@ import com.google.inject.multibindings.Multibinder;
 
 public class JMAPModule extends AbstractModule {
     private static final int DEFAULT_JMAP_PORT = 80;
+    private static final Logger LOGGER = LoggerFactory.getLogger(JMAPModule.class);
 
     @Override
     protected void configure() {
@@ -82,13 +86,21 @@ public class JMAPModule extends AbstractModule {
     @Provides
     @Singleton
     JMAPConfiguration provideConfiguration(PropertiesProvider propertiesProvider, FileSystem fileSystem) throws ConfigurationException, IOException{
-        PropertiesConfiguration configuration = propertiesProvider.getConfiguration("jmap");
-        return JMAPConfiguration.builder()
+        try {
+            PropertiesConfiguration configuration = propertiesProvider.getConfiguration("jmap");
+            return JMAPConfiguration.builder()
+                .enabled(configuration.getBoolean("enabled", true))
                 .keystore(configuration.getString("tls.keystoreURL"))
                 .secret(configuration.getString("tls.secret"))
                 .jwtPublicKeyPem(loadPublicKey(fileSystem, Optional.ofNullable(configuration.getString("jwt.publickeypem.url"))))
                 .port(configuration.getInt("jmap.port", DEFAULT_JMAP_PORT))
                 .build();
+        } catch (FileNotFoundException e) {
+            LOGGER.warn("Could not find JMAP configuration file. JMAP server will not be enabled.");
+            return JMAPConfiguration.builder()
+                .disable()
+                .build();
+        }
     }
 
     @Provides

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
index a04e1db..aa1cc00 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
@@ -22,6 +22,8 @@ package org.apache.james.modules.protocols;
 import java.security.Security;
 import java.util.List;
 
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.jmap.JMAPConfiguration;
 import org.apache.james.jmap.JMAPModule;
 import org.apache.james.jmap.JMAPServer;
 import org.apache.james.jmap.crypto.JamesSignatureHandler;
@@ -40,6 +42,8 @@ import com.google.inject.multibindings.Multibinder;
 
 public class JMAPServerModule extends AbstractModule {
 
+    private static final HierarchicalConfiguration NULL_CONFIGURATION = null;
+
     @Override
     protected void configure() {
         install(new JMAPModule());
@@ -52,19 +56,23 @@ public class JMAPServerModule extends AbstractModule {
 
         private final JMAPServer server;
         private final JamesSignatureHandler signatureHandler;
+        private final JMAPConfiguration jmapConfiguration;
 
         @Inject
-        public JMAPModuleConfigurationPerformer(JMAPServer server, JamesSignatureHandler signatureHandler) {
+        public JMAPModuleConfigurationPerformer(JMAPServer server, JamesSignatureHandler signatureHandler, JMAPConfiguration jmapConfiguration) {
             this.server = server;
             this.signatureHandler = signatureHandler;
+            this.jmapConfiguration = jmapConfiguration;
         }
 
         @Override
         public void initModule() {
             try {
-                signatureHandler.init();
-                server.configure(null);
-                registerPEMWithSecurityProvider();
+                if (jmapConfiguration.isEnabled()) {
+                    signatureHandler.init();
+                    server.configure(NULL_CONFIGURATION);
+                    registerPEMWithSecurityProvider();
+                }
             } catch (Exception e) {
                 Throwables.propagate(e);
             }

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/container/guice/protocols/jmap/src/test/java/org/apache/james/modules/TestJMAPServerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/modules/TestJMAPServerModule.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/modules/TestJMAPServerModule.java
index 6512fac..f23d3b6 100644
--- a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/modules/TestJMAPServerModule.java
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/modules/TestJMAPServerModule.java
@@ -59,6 +59,7 @@ public class TestJMAPServerModule extends AbstractModule{
     @Singleton
     JMAPConfiguration provideConfiguration() throws FileNotFoundException, ConfigurationException{
         return JMAPConfiguration.builder()
+                .enable()
                 .keystore("keystore")
                 .secret("james72laBalle")
                 .jwtPublicKeyPem(Optional.of(PUBLIC_PEM_KEY))

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
index 35d0496..e194e0f 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPConfiguration.java
@@ -33,18 +33,30 @@ public class JMAPConfiguration {
     public static class Builder {
         private String keystore;
         private String secret;
-        private Optional<String> jwtPublicKeyPem;
+        private Optional<Boolean> enabled = Optional.empty();
+        private Optional<String> jwtPublicKeyPem = Optional.empty();
         private Optional<Integer> port = Optional.empty();
 
-        private Builder() {
-            jwtPublicKeyPem = Optional.empty();
-        }
+        private Builder() {}
 
         public Builder keystore(String keystore) {
             this.keystore = keystore;
             return this;
         }
 
+        public Builder enabled(boolean enabled) {
+            this.enabled = Optional.of(enabled);
+            return this;
+        }
+
+        public Builder enable() {
+            return enabled(true);
+        }
+
+        public Builder disable() {
+            return enabled(false);
+        }
+
         public Builder secret(String secret) {
             this.secret = secret;
             return this;
@@ -67,24 +79,31 @@ public class JMAPConfiguration {
         }
 
         public JMAPConfiguration build() {
-            Preconditions.checkState(!Strings.isNullOrEmpty(keystore), "'keystore' is mandatory");
-            Preconditions.checkState(!Strings.isNullOrEmpty(secret), "'secret' is mandatory");
-            return new JMAPConfiguration(keystore, secret, jwtPublicKeyPem, port);
+            Preconditions.checkState(enabled.isPresent(), "You should specify if JMAP server should be started");
+            Preconditions.checkState(!enabled.get() || !Strings.isNullOrEmpty(keystore), "'keystore' is mandatory");
+            Preconditions.checkState(!enabled.get() || !Strings.isNullOrEmpty(secret), "'secret' is mandatory");
+            return new JMAPConfiguration(enabled.get(), keystore, secret, jwtPublicKeyPem, port);
         }
     }
 
+    private final boolean enabled;
     private final String keystore;
     private final String secret;
     private final Optional<String> jwtPublicKeyPem;
     private final Optional<Integer> port;
 
-    @VisibleForTesting JMAPConfiguration(String keystore, String secret, Optional<String> jwtPublicKeyPem, Optional<Integer> port) {
+    @VisibleForTesting JMAPConfiguration(boolean enabled, String keystore, String secret, Optional<String> jwtPublicKeyPem, Optional<Integer> port) {
+        this.enabled = enabled;
         this.keystore = keystore;
         this.secret = secret;
         this.jwtPublicKeyPem = jwtPublicKeyPem;
         this.port = port;
     }
 
+    public boolean isEnabled() {
+        return enabled;
+    }
+
     public String getKeystore() {
         return keystore;
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
index de3ac75..a6ac629 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
@@ -21,6 +21,8 @@ package org.apache.james.jmap;
 
 import static org.apache.james.jmap.BypassAuthOnRequestMethod.bypass;
 
+import java.util.Optional;
+
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
@@ -31,42 +33,45 @@ import org.apache.james.http.jetty.Configuration.Builder;
 import org.apache.james.http.jetty.JettyHttpServer;
 import org.apache.james.lifecycle.api.Configurable;
 
-import com.google.common.base.Throwables;
+import com.github.fge.lambdas.Throwing;
 
 public class JMAPServer implements Configurable {
 
-    private final JettyHttpServer server;
+    private final Optional<JettyHttpServer> server;
 
     @Inject
     private JMAPServer(JMAPConfiguration jmapConfiguration,
                        AuthenticationServlet authenticationServlet, JMAPServlet jmapServlet, DownloadServlet downloadServlet, UploadServlet uploadServlet,
                        AuthenticationFilter authenticationFilter, UserProvisioningFilter userProvisioningFilter, DefaultMailboxesProvisioningFilter defaultMailboxesProvisioningFilter) {
-
-        server = JettyHttpServer.create(
+        if (jmapConfiguration.isEnabled()) {
+            server = Optional.of(JettyHttpServer.create(
                 configurationBuilderFor(jmapConfiguration)
-                        .serve(JMAPUrls.AUTHENTICATION)
-                            .with(authenticationServlet)
-                        .filter(JMAPUrls.AUTHENTICATION)
-                            .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("POST").and("OPTIONS").only()))
-                            .only()
-                        .serve(JMAPUrls.JMAP)
-                            .with(jmapServlet)
-                        .filter(JMAPUrls.JMAP)
-                            .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
-                            .and(userProvisioningFilter)
-                            .and(defaultMailboxesProvisioningFilter)
-                            .only()
-                        .serveAsOneLevelTemplate(JMAPUrls.DOWNLOAD)
-                            .with(downloadServlet)
-                        .filterAsOneLevelTemplate(JMAPUrls.DOWNLOAD)
-                            .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
-                            .only()
-                        .serve(JMAPUrls.UPLOAD)
-                            .with(uploadServlet)
-                        .filterAsOneLevelTemplate(JMAPUrls.UPLOAD)
-                            .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
-                            .only()
-                        .build());
+                    .serve(JMAPUrls.AUTHENTICATION)
+                        .with(authenticationServlet)
+                    .filter(JMAPUrls.AUTHENTICATION)
+                        .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("POST").and("OPTIONS").only()))
+                        .only()
+                    .serve(JMAPUrls.JMAP)
+                        .with(jmapServlet)
+                    .filter(JMAPUrls.JMAP)
+                        .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
+                        .and(userProvisioningFilter)
+                        .and(defaultMailboxesProvisioningFilter)
+                        .only()
+                    .serveAsOneLevelTemplate(JMAPUrls.DOWNLOAD)
+                        .with(downloadServlet)
+                    .filterAsOneLevelTemplate(JMAPUrls.DOWNLOAD)
+                        .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
+                        .only()
+                    .serve(JMAPUrls.UPLOAD)
+                        .with(uploadServlet)
+                    .filterAsOneLevelTemplate(JMAPUrls.UPLOAD)
+                        .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
+                        .only()
+                    .build()));
+        } else {
+            server = Optional.empty();
+        }
     }
 
     private Builder configurationBuilderFor(JMAPConfiguration jmapConfiguration) {
@@ -81,23 +86,15 @@ public class JMAPServer implements Configurable {
 
     @Override
     public void configure(HierarchicalConfiguration config) throws ConfigurationException {
-        try {
-            server.start();
-        } catch (Exception e) {
-            Throwables.propagate(e);
-        }
+        server.ifPresent(Throwing.consumer(JettyHttpServer::start).sneakyThrow());
     }
 
     @PreDestroy
     public void stop() {
-        try {
-            server.stop();
-        } catch (Exception e) {
-            Throwables.propagate(e);
-        }
+        server.ifPresent(Throwing.consumer(JettyHttpServer::stop).sneakyThrow());
     }
 
     public int getPort() {
-        return server.getPort();
+        return server.map(JettyHttpServer::getPort).orElseThrow(() -> new RuntimeException("JMAP server was disabled. No port bound"));
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
index e7a427e..4ffce68 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPConfigurationTest.java
@@ -28,9 +28,13 @@ import org.junit.Test;
 
 public class JMAPConfigurationTest {
 
+    public static final boolean ENABLED = true;
+    public static final boolean DISABLED = false;
+
     @Test
     public void buildShouldThrowWhenKeystoreIsNull() {
         assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .enable()
                 .keystore(null)
                 .build())
             .isInstanceOf(IllegalStateException.class)
@@ -40,6 +44,7 @@ public class JMAPConfigurationTest {
     @Test
     public void buildShouldThrowWhenKeystoreIsEmpty() {
         assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .enable()
                 .keystore("")
                 .build())
             .isInstanceOf(IllegalStateException.class)
@@ -49,6 +54,7 @@ public class JMAPConfigurationTest {
     @Test
     public void buildShouldThrowWhenSecretIsNull() {
         assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .enable()
                 .keystore("keystore")
                 .secret(null)
                 .build())
@@ -59,6 +65,7 @@ public class JMAPConfigurationTest {
     @Test
     public void buildShouldThrowWhenSecretIsEmpty() {
         assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .enable()
                 .keystore("keystore")
                 .secret("")
                 .build())
@@ -69,6 +76,7 @@ public class JMAPConfigurationTest {
     @Test
     public void buildShouldThrowWhenJwtPublicKeyPemIsNull() {
         assertThatThrownBy(() -> JMAPConfiguration.builder()
+                .enable()
                 .keystore("keystore")
                 .secret("secret")
                 .jwtPublicKeyPem(null)
@@ -78,9 +86,10 @@ public class JMAPConfigurationTest {
 
     @Test
     public void buildShouldWorkWhenRandomPort() {
-        JMAPConfiguration expectedJMAPConfiguration = new JMAPConfiguration("keystore", "secret", Optional.of("file://conf/jwt_publickey"), Optional.empty());
+        JMAPConfiguration expectedJMAPConfiguration = new JMAPConfiguration(ENABLED, "keystore", "secret", Optional.of("file://conf/jwt_publickey"), Optional.empty());
 
         JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
+            .enable()
             .keystore("keystore")
             .secret("secret")
             .jwtPublicKeyPem(Optional.of("file://conf/jwt_publickey"))
@@ -91,9 +100,10 @@ public class JMAPConfigurationTest {
 
     @Test
     public void buildShouldWorkWhenFixedPort() {
-        JMAPConfiguration expectedJMAPConfiguration = new JMAPConfiguration("keystore", "secret", Optional.of("file://conf/jwt_publickey"), Optional.of(80));
+        JMAPConfiguration expectedJMAPConfiguration = new JMAPConfiguration(ENABLED, "keystore", "secret", Optional.of("file://conf/jwt_publickey"), Optional.of(80));
 
         JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
+            .enable()
             .keystore("keystore")
             .secret("secret")
             .jwtPublicKeyPem(Optional.of("file://conf/jwt_publickey"))
@@ -101,4 +111,18 @@ public class JMAPConfigurationTest {
             .build();
         assertThat(jmapConfiguration).isEqualToComparingFieldByField(expectedJMAPConfiguration);
     }
+
+    @Test
+    public void buildShouldWorkWhenDisabled() {
+        String keystore = null;
+        String secret = null;
+        Optional<String> jwtPublicKeyPem = Optional.empty();
+        Optional<Integer> port = Optional.empty();
+        JMAPConfiguration expectedJMAPConfiguration = new JMAPConfiguration(DISABLED, keystore, secret, jwtPublicKeyPem, port);
+
+        JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
+            .disable()
+            .build();
+        assertThat(jmapConfiguration).isEqualToComparingFieldByField(expectedJMAPConfiguration);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/67e769c1/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
index 06e3bd3..f3d0656 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
@@ -48,6 +48,7 @@ public class JamesSignatureHandlerProvider {
         };
         JamesSignatureHandler signatureHandler = new JamesSignatureHandler(fileSystem, 
                 JMAPConfiguration.builder()
+                    .enable()
                     .keystore("keystore")
                     .secret("james72laBalle")
                     .build());


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


[03/17] james-project git commit: JAMES-1999 Correct the property key

Posted by bt...@apache.org.
JAMES-1999 Correct the property key


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/bb68be16
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/bb68be16
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/bb68be16

Branch: refs/heads/master
Commit: bb68be1634e6c16034fdaaaf59298acc3a627c50
Parents: d258d90
Author: quynhn <qn...@linagora.com>
Authored: Tue Apr 18 16:56:03 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 07:52:22 2017 +0700

----------------------------------------------------------------------
 .../src/test/java/org/apache/james/DockerCassandraRule.java        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bb68be16/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
index 4980f38..8b9a000 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
@@ -48,7 +48,7 @@ public class DockerCassandraRule implements GuiceModuleTestRule {
         configuration.addProperty("cassandra.keyspace", "apache_james");
         configuration.addProperty("cassandra.replication.factor", 1);
         configuration.addProperty("cassandra.retryConnection.maxRetries", 10);
-        configuration.addProperty("cassandra.retryConnection", 5000);
+        configuration.addProperty("cassandra.retryConnection.minDelay", 5000);
 
         return configuration;
     }


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


[11/17] james-project git commit: JAMES-2004 All XML configuration files should have default values

Posted by bt...@apache.org.
JAMES-2004 All XML configuration files should have default values


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/3aea0817
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/3aea0817
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/3aea0817

Branch: refs/heads/master
Commit: 3aea08173f369ad9d0e4ce43551827c9a63c6c57
Parents: 67e769c
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 08:14:09 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 server/container/guice/guice-common/pom.xml     |  10 +-
 ...ltProcessorsConfigurationProviderModule.java |  43 ++++++
 .../james/utils/FileConfigurationProvider.java  |  40 +++--
 .../utils/InMemoryMailRepositoryStore.java      |  17 ++-
 .../james/AbstractJmapJamesServerTest.java      | 145 -------------------
 .../utils/FileConfigurationProviderTest.java    |   6 +-
 .../utils/InMemoryMailRepositoryStoreTest.java  |  18 ++-
 .../org/apache/james/JPAJamesServerMain.java    |  22 +--
 .../main/resources/defaultMailetContainer.xml   |  87 +++++++++++
 .../org/apache/james/JPAJamesServerMain.java    |  12 +-
 .../main/resources/defaultMailetContainer.xml   |  81 +++++++++++
 .../server/CamelMailetContainerModule.java      |  77 ++++++++--
 .../src/test/resources/imapserver.xml           |  54 -------
 server/container/guice/protocols/jmap/pom.xml   |   9 ++
 .../java/org/apache/james/jmap/JMAPModule.java  |  15 ++
 .../resources/defaultJmapMailetContainer.xml    |  97 +++++++++++++
 .../james/AbstractJmapJamesServerTest.java      | 145 +++++++++++++++++++
 .../user/ldap/ReadOnlyUsersLDAPRepository.java  |  14 ++
 18 files changed, 639 insertions(+), 253 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/pom.xml b/server/container/guice/guice-common/pom.xml
index 4f63bfa..c0ee50b 100644
--- a/server/container/guice/guice-common/pom.xml
+++ b/server/container/guice/guice-common/pom.xml
@@ -192,11 +192,6 @@
                 </dependency>
                 <dependency>
                     <groupId>${project.groupId}</groupId>
-                    <artifactId>james-server-guice-jmap</artifactId>
-                    <scope>test</scope>
-                </dependency>
-                <dependency>
-                    <groupId>${project.groupId}</groupId>
                     <artifactId>james-server-guice-lmtp</artifactId>
                     <scope>test</scope>
                 </dependency>
@@ -301,6 +296,11 @@
                     <groupId>org.slf4j</groupId>
                     <artifactId>slf4j-api</artifactId>
                 </dependency>
+                <dependency>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-simple</artifactId>
+                    <scope>test</scope>
+                </dependency>
             </dependencies>
         </profile>
         <profile>

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
new file mode 100644
index 0000000..a3e27bf
--- /dev/null
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DefaultProcessorsConfigurationProviderModule.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.server;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.utils.FileConfigurationProvider;
+
+import com.google.common.base.Throwables;
+import com.google.inject.AbstractModule;
+
+public class DefaultProcessorsConfigurationProviderModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        bind(CamelMailetContainerModule.DefaultProcessorsConfigurationSupplier.class)
+            .toInstance(
+                () -> {
+                    try {
+                        return FileConfigurationProvider.getConfig(ClassLoader.getSystemResourceAsStream("defaultMailetContainer.xml"));
+                    } catch (ConfigurationException e) {
+                        throw Throwables.propagate(e);
+                    }
+                }
+            );
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
index 6fa9090..c87a628 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/FileConfigurationProvider.java
@@ -22,6 +22,7 @@ package org.apache.james.utils;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
+import java.util.Optional;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -31,6 +32,8 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.configuration.XMLConfiguration;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.modules.CommonServicesModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
@@ -39,7 +42,17 @@ import com.google.common.collect.Iterables;
 
 public class FileConfigurationProvider implements ConfigurationProvider {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(FileConfigurationProvider.class);
     private static final String CONFIGURATION_FILE_SUFFIX = ".xml";
+    public static final HierarchicalConfiguration EMTY_CONFIGURATION = new HierarchicalConfiguration();
+
+    public static XMLConfiguration getConfig(InputStream configStream) throws ConfigurationException {
+        XMLConfiguration config = new XMLConfiguration();
+        config.setDelimiterParsingDisabled(true);
+        config.setAttributeSplittingDisabled(true);
+        config.load(configStream);
+        return config;
+    }
     
     private final FileSystem fileSystem;
     private final String configurationPrefix;
@@ -55,27 +68,30 @@ public class FileConfigurationProvider implements ConfigurationProvider {
         Preconditions.checkNotNull(component);
         List<String> configPathParts = Splitter.on(".").splitToList(component);
         Preconditions.checkArgument(!configPathParts.isEmpty());
-        HierarchicalConfiguration config = getConfig(retrieveConfigInputStream(configPathParts.get(0)));
+
+        Optional<InputStream> inputStream = retrieveConfigInputStream(configPathParts.get(0));
+        if (inputStream.isPresent()) {
+            return selectConfigurationPart(configPathParts,
+                getConfig(inputStream.get()));
+        }
+        return EMTY_CONFIGURATION;
+    }
+
+    private HierarchicalConfiguration selectConfigurationPart(List<String> configPathParts, HierarchicalConfiguration config) {
         return selectHierarchicalConfigPart(config, Iterables.skip(configPathParts, 1));
     }
 
-    private InputStream retrieveConfigInputStream(String configurationFileWithoutExtension) throws ConfigurationException {
+    private Optional<InputStream> retrieveConfigInputStream(String configurationFileWithoutExtension) throws ConfigurationException {
         Preconditions.checkArgument(!Strings.isNullOrEmpty(configurationFileWithoutExtension), "The configuration file name should not be empty or null");
         try {
-            return fileSystem.getResource(configurationPrefix + configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX);
+            return Optional.of(
+                fileSystem.getResource(configurationPrefix + configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX));
         } catch (IOException e) {
-            throw new ConfigurationException("Unable to locate configuration file " + configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX, e);
+            LOGGER.warn("Unable to locate configuration file " + configurationFileWithoutExtension + CONFIGURATION_FILE_SUFFIX + ", assuming empty configuration");
+            return Optional.empty();
         }
     }
 
-    private XMLConfiguration getConfig(InputStream configStream) throws ConfigurationException {
-        XMLConfiguration config = new XMLConfiguration();
-        config.setDelimiterParsingDisabled(true);
-        config.setAttributeSplittingDisabled(true);
-        config.load(configStream);
-        return config;
-    }
-
     private HierarchicalConfiguration selectHierarchicalConfigPart(HierarchicalConfiguration config, Iterable<String> configsPathParts) {
         HierarchicalConfiguration currentConfig = config;
         for (String nextPathPart : configsPathParts) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
index 85b9dad..1c11f3b 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/InMemoryMailRepositoryStore.java
@@ -25,7 +25,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Collectors;
 
 import org.apache.commons.configuration.CombinedConfiguration;
 import org.apache.commons.configuration.ConfigurationException;
@@ -39,6 +38,7 @@ import org.apache.james.repository.api.Initializable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 public class InMemoryMailRepositoryStore implements MailRepositoryStore, Configurable {
@@ -61,9 +61,7 @@ public class InMemoryMailRepositoryStore implements MailRepositoryStore, Configu
 
     @Override
     public List<String> getUrls() {
-        return destinationToRepositoryAssociations.keySet()
-            .stream()
-            .collect(Collectors.toList());
+        return ImmutableList.copyOf(destinationToRepositoryAssociations.keySet());
     }
 
     @Override
@@ -73,12 +71,21 @@ public class InMemoryMailRepositoryStore implements MailRepositoryStore, Configu
 
     public void init() throws Exception {
         LOGGER.info("JamesMailStore init... " + this);
-        List<HierarchicalConfiguration> registeredClasses = configuration.configurationsAt("mailrepositories.mailrepository");
+        List<HierarchicalConfiguration> registeredClasses = retrieveRegisteredClassConfiguration();
         for (HierarchicalConfiguration registeredClass : registeredClasses) {
             readConfigurationEntry(registeredClass);
         }
     }
 
+    private List<HierarchicalConfiguration> retrieveRegisteredClassConfiguration() {
+        try {
+            return configuration.configurationsAt("mailrepositories.mailrepository");
+        } catch (Exception e) {
+            LOGGER.warn("Could not process configuration. Skipping Mail Repository initialization.", e);
+            return ImmutableList.of();
+        }
+    }
+
     @Override
     public MailRepository select(String destination) throws MailRepositoryStoreException {
         MailRepository mailRepository = destinationToRepositoryAssociations.get(destination);

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java b/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
deleted file mode 100644
index 051fc46..0000000
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
+++ /dev/null
@@ -1,145 +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;
-
-import static com.jayway.restassured.RestAssured.given;
-import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
-import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.nio.charset.Charset;
-
-import org.apache.james.utils.DataProbeImpl;
-import org.apache.james.utils.JmapGuiceProbe;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.base.Charsets;
-import com.jayway.restassured.RestAssured;
-import com.jayway.restassured.builder.RequestSpecBuilder;
-import com.jayway.restassured.http.ContentType;
-
-public abstract class AbstractJmapJamesServerTest {
-
-    private static final int IMAP_PORT_SSL = 1993;
-    private static final int POP3_PORT = 1110;
-    private static final int SMTP_PORT = 1025;
-    private static final int LMTP_PORT = 1024;
-
-    protected static final String JAMES_SERVER_HOST = "127.0.0.1";
-    protected static final int IMAP_PORT = 1143; // You need to be root (superuser) to bind to ports under 1024.
-
-    private GuiceJamesServer server;
-    private SocketChannel socketChannel;
-
-    @Before
-    public void setup() throws Exception {
-        server = createJamesServer();
-        socketChannel = SocketChannel.open();
-        server.start();
-
-        RestAssured.requestSpecification = new RequestSpecBuilder()
-        		.setContentType(ContentType.JSON)
-        		.setAccept(ContentType.JSON)
-        		.setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8)))
-        		.setPort(server.getProbe(JmapGuiceProbe.class).getJmapPort())
-        		.build();
-    }
-
-    protected abstract GuiceJamesServer createJamesServer();
-
-    protected abstract void clean();
-
-    @After
-    public void tearDown() throws Exception {
-        if (server != null) {
-            server.stop();
-        }
-        clean();
-    }
-
-    @Test
-    public void hostnameShouldBeUsedAsDefaultDomain() throws Exception {
-        String expectedDefaultDomain = InetAddress.getLocalHost().getHostName();
-
-        assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
-    }
-
-    @Test
-    public void hostnameShouldBeRetrievedWhenRestarting() throws Exception {
-        server.stop();
-        server.start();
-        String expectedDefaultDomain = InetAddress.getLocalHost().getHostName();
-
-        assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
-    }
-
-    @Test
-    public void connectIMAPServerShouldSendShabangOnConnect() throws Exception {
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, IMAP_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server");
-    }
-
-    @Test
-    public void connectOnSecondaryIMAPServerIMAPServerShouldSendShabangOnConnect() throws Exception {
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, IMAP_PORT_SSL));
-        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server");
-    }
-
-    @Test
-    public void connectPOP3ServerShouldSendShabangOnConnect() throws Exception {
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, POP3_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).contains("POP3 server (JAMES POP3 Server ) ready");
-    }
-
-    @Test
-    public void connectSMTPServerShouldSendShabangOnConnect() throws Exception {
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, SMTP_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).startsWith("220 JAMES Linagora's SMTP awesome Server");
-    }
-
-    @Test
-    public void connectLMTPServerShouldSendShabangOnConnect() throws Exception {
-        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, LMTP_PORT));
-        assertThat(getServerConnectionResponse(socketChannel)).contains("LMTP Server (JAMES Protocols Server) ready");
-    }
-
-    @Test
-    public void connectJMAPServerShouldRespondBadRequest() throws Exception {
-        given()
-            .body("{\"badAttributeName\": \"value\"}")
-        .when()
-            .post("/authentication")
-        .then()
-            .statusCode(400);
-    }
-
-    private String getServerConnectionResponse(SocketChannel socketChannel) throws IOException {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
-        socketChannel.read(byteBuffer);
-        byte[] bytes = byteBuffer.array();
-        return new String(bytes, Charset.forName("UTF-8"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
index 0eeb88f..04562f2 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FileConfigurationProviderTest.java
@@ -105,9 +105,9 @@ public class FileConfigurationProviderTest {
         assertThat(hierarchicalConfiguration.getProperty(CONFIG_KEY_2)).isEqualTo(VALUE_2);
     }
 
-    @Test(expected = ConfigurationException.class)
-    public void getConfigurationShouldThrowOnNonExistingXMLFile() throws Exception {
-        assertThat(configurationProvider.getConfiguration(FAKE_CONFIG_KEY)).isNotNull();
+    @Test
+    public void getConfigurationShouldReturnDefaultOnNonExistingXMLFile() throws Exception {
+        assertThat(configurationProvider.getConfiguration(FAKE_CONFIG_KEY)).isEqualTo(FileConfigurationProvider.EMTY_CONFIGURATION);
     }
 
     @Test(expected = IllegalArgumentException.class)

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
index d8582b3..9964eae 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/InMemoryMailRepositoryStoreTest.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.core.JamesServerResourceLoader;
 import org.apache.james.core.filesystem.FileSystemImpl;
 import org.apache.james.filesystem.api.FileSystem;
@@ -45,7 +46,8 @@ public class InMemoryMailRepositoryStoreTest {
         repositoryStore = new InMemoryMailRepositoryStore(Sets.newHashSet(
                 new MailStoreRepositoryModule.FileMailRepositoryProvider(
                         fileSystem)));
-        repositoryStore.configure(new FileConfigurationProvider(fileSystem, FileSystem.CLASSPATH_PROTOCOL).getConfiguration("mailrepositorystore"));
+        repositoryStore.configure(new FileConfigurationProvider(fileSystem, FileSystem.CLASSPATH_PROTOCOL)
+            .getConfiguration("mailrepositorystore"));
         repositoryStore.init();
     }
 
@@ -83,6 +85,20 @@ public class InMemoryMailRepositoryStoreTest {
     }
 
     @Test
+    public void configureShouldNotThrowOnEmptyConfiguration() throws Exception {
+        try {
+            repositoryStore = new InMemoryMailRepositoryStore(Sets.newHashSet(
+                new MailStoreRepositoryModule.FileMailRepositoryProvider(
+                    fileSystem)));
+        } catch (Exception e) {
+            fail("Unexpected failure : ", e);
+        }
+        repositoryStore.configure(new HierarchicalConfiguration());
+
+        repositoryStore.init();
+    }
+
+    @Test
     public void getUrlsShouldBeEmptyIfNoSelectWerePerformed() {
         assertThat(repositoryStore.getUrls()).isEmpty();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java b/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
index 1b64bb2..096559c 100644
--- a/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
+++ b/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java
@@ -32,6 +32,7 @@ import org.apache.james.modules.protocols.ProtocolHandlerModule;
 import org.apache.james.modules.protocols.SMTPServerModule;
 import org.apache.james.modules.server.ActiveMQQueueModule;
 import org.apache.james.modules.server.DataRoutesModules;
+import org.apache.james.modules.server.DefaultProcessorsConfigurationProviderModule;
 import org.apache.james.modules.server.JMXServerModule;
 import org.apache.james.modules.server.MailboxRoutesModule;
 import org.apache.james.modules.server.NoJwtModule;
@@ -44,15 +45,15 @@ import com.google.inject.util.Modules;
 public class JPAJamesServerMain {
 
     public static final Module protocols = Modules.combine(
-            new IMAPServerModule(),
-            new ProtocolHandlerModule(),
-            new POP3ServerModule(),
-            new SMTPServerModule(),
-            new LMTPServerModule(),
-            new ManageSieveServerModule(),
-            new WebAdminServerModule(),
-            new DataRoutesModules(),
-            new MailboxRoutesModule());
+        new IMAPServerModule(),
+        new ProtocolHandlerModule(),
+        new POP3ServerModule(),
+        new SMTPServerModule(),
+        new LMTPServerModule(),
+        new ManageSieveServerModule(),
+        new WebAdminServerModule(),
+        new DataRoutesModules(),
+        new MailboxRoutesModule());
     
     public static final Module jpaServerModule = Modules.combine(
         new JPAMailboxModule(),
@@ -61,7 +62,8 @@ public class JPAJamesServerMain {
         new ActiveMQQueueModule(),
         new RawPostDequeueDecoratorModule(),
         new MailboxModule(),
-        new NoJwtModule());
+        new NoJwtModule(),
+        new DefaultProcessorsConfigurationProviderModule());
 
     public static void main(String[] args) throws Exception {
         GuiceJamesServer server = new GuiceJamesServer()

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml b/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
new file mode 100644
index 0000000..8a0e360
--- /dev/null
+++ b/server/container/guice/jpa-guice/src/main/resources/defaultMailetContainer.xml
@@ -0,0 +1,87 @@
+<!--
+  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.
+ -->
+
+<processors>
+    <processor state="root" enableJmx="false">
+        <mailet match="All" class="PostmasterAlias"/>
+        <mailet match="RelayLimit=30" class="Null"/>
+        <mailet match="All" class="ToProcessor">
+            <processor>transport</processor>
+        </mailet>
+    </processor>
+
+    <processor state="error" enableJmx="false">
+        <mailet match="All" class="Bounce"/>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+
+    <processor state="transport" enableJmx="false">
+        <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+            <name>X-UserIsAuth</name>
+            <value>true</value>
+        </mailet>
+        <mailet match="All" class="RemoveMimeHeader">
+            <name>bcc</name>
+        </mailet>
+        <mailet match="All" class="RecipientRewriteTable" />
+        <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+        <mailet match="HostIsLocal" class="ToProcessor">
+            <processor>local-address-error</processor>
+            <notice>550 - Requested action not taken: no such user here</notice>
+        </mailet>
+        <mailet match="SMTPAuthSuccessful" class="RemoteDelivery">
+            <outgoingQueue>outgoing</outgoingQueue>
+            <delayTime>5000, 100000, 500000</delayTime>
+            <maxRetries>25</maxRetries>
+            <maxDnsProblemRetries>0</maxDnsProblemRetries>
+            <deliveryThreads>10</deliveryThreads>
+            <sendpartial>true</sendpartial>
+            <bounceProcessor>bounces</bounceProcessor>
+        </mailet>
+        <mailet match="All" class="ToProcessor">
+            <processor>relay-denied</processor>
+        </mailet>
+    </processor>
+
+    <processor state="spam" enableJmx="false">
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="local-address-error" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="relay-denied" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="bounces" enableJmx="false">
+        <mailet match="All" class="DSNBounce">
+            <passThrough>false</passThrough>
+        </mailet>
+    </processor>
+
+</processors>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java b/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
index f8ebc93..2fd0585 100644
--- a/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
+++ b/server/container/guice/jpa-smtp/src/main/java/org/apache/james/JPAJamesServerMain.java
@@ -26,6 +26,7 @@ import org.apache.james.modules.protocols.ProtocolHandlerModule;
 import org.apache.james.modules.protocols.SMTPServerModule;
 import org.apache.james.modules.server.ActiveMQQueueModule;
 import org.apache.james.modules.server.DataRoutesModules;
+import org.apache.james.modules.server.DefaultProcessorsConfigurationProviderModule;
 import org.apache.james.modules.server.NoJwtModule;
 import org.apache.james.modules.server.RawPostDequeueDecoratorModule;
 import org.apache.james.modules.server.WebAdminServerModule;
@@ -37,11 +38,12 @@ import com.google.inject.util.Modules;
 public class JPAJamesServerMain {
 
     public static final Module protocols = Modules.combine(
-            new ProtocolHandlerModule(),
-            new SMTPServerModule(),
-            new WebAdminServerModule(),
-            new DataRoutesModules(),
-            new NoJwtModule());
+        new ProtocolHandlerModule(),
+        new SMTPServerModule(),
+        new WebAdminServerModule(),
+        new DataRoutesModules(),
+        new NoJwtModule(),
+        new DefaultProcessorsConfigurationProviderModule());
     
     public static final Module jpaServerModule = Modules.combine(
         new JPADataModule(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml b/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml
new file mode 100644
index 0000000..8ce1d59
--- /dev/null
+++ b/server/container/guice/jpa-smtp/src/main/resources/defaultMailetContainer.xml
@@ -0,0 +1,81 @@
+<!--
+  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.
+ -->
+
+<processors>
+    <processor state="root" enableJmx="false">
+        <mailet match="All" class="PostmasterAlias"/>
+        <mailet match="RelayLimit=30" class="Null"/>
+        <mailet match="All" class="ToProcessor">
+            <processor>transport</processor>
+        </mailet>
+    </processor>
+
+    <processor state="error" enableJmx="false">
+        <mailet match="All" class="Bounce"/>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="transport" enableJmx="false">
+        <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+            <name>X-UserIsAuth</name>
+            <value>true</value>
+        </mailet>
+        <mailet match="All" class="RemoveMimeHeader">
+            <name>bcc</name>
+        </mailet>
+        <mailet match="All" class="RecipientRewriteTable" />
+        <mailet match="SMTPAuthSuccessful" class="RemoteDelivery">
+            <outgoingQueue>outgoing</outgoingQueue>
+            <delayTime>5000, 100000, 500000</delayTime>
+            <maxRetries>25</maxRetries>
+            <maxDnsProblemRetries>0</maxDnsProblemRetries>
+            <deliveryThreads>10</deliveryThreads>
+            <sendpartial>true</sendpartial>
+            <bounceProcessor>bounces</bounceProcessor>
+        </mailet>
+        <mailet match="All" class="ToProcessor">
+            <processor>relay-denied</processor>
+        </mailet>
+    </processor>
+
+    <processor state="spam" enableJmx="false">
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="local-address-error" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="relay-denied" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="bounces" enableJmx="false">
+        <mailet match="All" class="DSNBounce">
+            <passThrough>false</passThrough>
+        </mailet>
+    </processor>
+
+</processors>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
index 34a64a5..58e57c3 100644
--- a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
+++ b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.SimpleRegistry;
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.lifecycle.api.Configurable;
@@ -65,6 +66,7 @@ public class CamelMailetContainerModule extends AbstractModule {
     private static final Logger CAMEL_LOGGER = LoggerFactory.getLogger(CamelCompositeProcessor.class);
     private static final Logger SPOOLER_LOGGER = LoggerFactory.getLogger(JamesMailSpooler.class);
     private static final Logger MAILET_LOGGER = LoggerFactory.getLogger(JamesMailetContext.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamelMailetContainerModule.class);
 
     @Override
     protected void configure() {
@@ -106,7 +108,8 @@ public class CamelMailetContainerModule extends AbstractModule {
         private final JamesMailSpooler jamesMailSpooler;
         private final JamesMailetContext mailetContext;
         private final MailQueueFactory mailQueueFactory;
-        private Set<TransportProcessorCheck> transportProcessorCheckSet;
+        private final DefaultProcessorsConfigurationSupplier defaultProcessorsConfigurationSupplier;
+        private final Set<TransportProcessorCheck> transportProcessorCheckSet;
 
         @Inject
         public MailetModuleConfigurationPerformer(ConfigurationProvider configurationProvider,
@@ -114,13 +117,15 @@ public class CamelMailetContainerModule extends AbstractModule {
                                                 JamesMailSpooler jamesMailSpooler,
                                                 JamesMailetContext mailetContext,
                                                 MailQueueFactory mailQueueFactory,
-                                                Set<TransportProcessorCheck> transportProcessorCheckSet) {
+                                                Set<TransportProcessorCheck> transportProcessorCheckSet,
+                                                DefaultProcessorsConfigurationSupplier defaultProcessorsConfigurationSupplier) {
             this.configurationProvider = configurationProvider;
             this.camelCompositeProcessor = camelCompositeProcessor;
             this.jamesMailSpooler = jamesMailSpooler;
             this.mailetContext = mailetContext;
             this.mailQueueFactory = mailQueueFactory;
             this.transportProcessorCheckSet = transportProcessorCheckSet;
+            this.defaultProcessorsConfigurationSupplier = defaultProcessorsConfigurationSupplier;
         }
 
         @Override
@@ -129,24 +134,66 @@ public class CamelMailetContainerModule extends AbstractModule {
                 DefaultCamelContext camelContext = new DefaultCamelContext();
                 camelContext.disableJMX();
                 camelContext.setRegistry(new SimpleRegistry());
-                camelCompositeProcessor.setLog(CAMEL_LOGGER);
-                camelCompositeProcessor.setCamelContext(camelContext);
-                camelCompositeProcessor.configure(configurationProvider.getConfiguration("mailetcontainer").configurationAt("processors"));
-                camelCompositeProcessor.init();
+                configureProcessors(camelContext);
                 checkProcessors();
-                jamesMailSpooler.setMailProcessor(camelCompositeProcessor);
-                jamesMailSpooler.setLog(SPOOLER_LOGGER);
-                jamesMailSpooler.configure(configurationProvider.getConfiguration("mailetcontainer").configurationAt("spooler"));
-                jamesMailSpooler.init();
-                mailetContext.setLog(MAILET_LOGGER);
-                mailetContext.configure(configurationProvider.getConfiguration("mailetcontainer").configurationAt("context"));
-                mailetContext.retrieveRootMailQueue(mailQueueFactory);
+                configureJamesSpooler();
+                configureMailetContext();
             } catch (Exception e) {
                 throw Throwables.propagate(e);
             }
 
         }
 
+        private void configureProcessors(DefaultCamelContext camelContext) throws Exception {
+            camelCompositeProcessor.setLog(CAMEL_LOGGER);
+            camelCompositeProcessor.setCamelContext(camelContext);
+            camelCompositeProcessor.configure(getProcessorConfiguration());
+            camelCompositeProcessor.init();
+        }
+
+        private HierarchicalConfiguration getProcessorConfiguration() {
+            try {
+                return configurationProvider.getConfiguration("mailetcontainer")
+                    .configurationAt("processors");
+            } catch (Exception e) {
+                LOGGER.warn("Could not load configuration for Processors. Fallback to default.");
+                return defaultProcessorsConfigurationSupplier.getDefaultConfiguration();
+            }
+        }
+
+        private void configureJamesSpooler() throws ConfigurationException {
+            jamesMailSpooler.setMailProcessor(camelCompositeProcessor);
+            jamesMailSpooler.setLog(SPOOLER_LOGGER);
+            jamesMailSpooler.configure(getJamesSpoolerConfiguration());
+            jamesMailSpooler.init();
+        }
+
+        private HierarchicalConfiguration getJamesSpoolerConfiguration() {
+            try {
+                return configurationProvider.getConfiguration("mailetcontainer")
+                    .configurationAt("spooler");
+            } catch (Exception e) {
+                LOGGER.warn("Could not locate configuration for James Spooler. Assuming empty configuration for this component.");
+                return new HierarchicalConfiguration();
+            }
+        }
+
+        private void configureMailetContext() throws ConfigurationException {
+            mailetContext.setLog(MAILET_LOGGER);
+            mailetContext.configure(getMailetContextConfiguration());
+            mailetContext.retrieveRootMailQueue(mailQueueFactory);
+        }
+
+        private HierarchicalConfiguration getMailetContextConfiguration() {
+            try {
+                return configurationProvider.getConfiguration("mailetcontainer")
+                    .configurationAt("context");
+            } catch (Exception e) {
+                LOGGER.warn("Could not locate configuration for Mailet context. Assuming empty configuration for this component.");
+                return new HierarchicalConfiguration();
+            }
+        }
+
         private void checkProcessors() throws ConfigurationException {
             MailProcessor mailProcessor = Optional.ofNullable(camelCompositeProcessor.getProcessor("transport"))
                 .orElseThrow(() -> new RuntimeException("JMAP needs a transport processor"));
@@ -184,4 +231,8 @@ public class CamelMailetContainerModule extends AbstractModule {
         }
     }
 
+    public interface DefaultProcessorsConfigurationSupplier {
+        HierarchicalConfiguration getDefaultConfiguration();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/memory-guice/src/test/resources/imapserver.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/resources/imapserver.xml b/server/container/guice/memory-guice/src/test/resources/imapserver.xml
deleted file mode 100644
index ff478a9..0000000
--- a/server/container/guice/memory-guice/src/test/resources/imapserver.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.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.
--->
-
-
-<imapservers>
-	<imapserver enabled="true">
-		<jmxName>imapserver</jmxName>
-		<bind>0.0.0.0:1143</bind>
-		<connectionBacklog>200</connectionBacklog>
-		<tls socketTLS="false" startTLS="false">
-			<!-- To create a new keystore execute:
-            keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore
-              -->
-			<keystore>file://conf/keystore</keystore>
-			<secret>james72laBalle</secret>
-			<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
-		</tls>
-		<connectionLimit>0</connectionLimit>
-		<connectionLimitPerIP>0</connectionLimitPerIP>
-	</imapserver>
-	<imapserver enabled="true">
-		<jmxName>imapserver-ssl</jmxName>
-		<bind>0.0.0.0:1993</bind>
-		<connectionBacklog>200</connectionBacklog>
-		<tls socketTLS="false" startTLS="false">
-			<!-- To create a new keystore execute:
-              keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore
-             -->
-			<keystore>file://conf/keystore</keystore>
-			<secret>james72laBalle</secret>
-			<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
-		</tls>
-		<connectionLimit>0</connectionLimit>
-		<connectionLimitPerIP>0</connectionLimitPerIP>
-	</imapserver>
-</imapservers>

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/pom.xml b/server/container/guice/protocols/jmap/pom.xml
index dcc9fee..c0b43bd 100644
--- a/server/container/guice/protocols/jmap/pom.xml
+++ b/server/container/guice/protocols/jmap/pom.xml
@@ -160,6 +160,10 @@
                     <scope>test</scope>
                 </dependency>
                 <dependency>
+                    <groupId>org.apache.james</groupId>
+                    <artifactId>james-server-guice-common</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>${project.groupId}</groupId>
                     <artifactId>james-server-guice-configuration</artifactId>
                 </dependency>
@@ -180,6 +184,11 @@
                     <artifactId>guice-multibindings</artifactId>
                 </dependency>
                 <dependency>
+                    <groupId>com.jayway.restassured</groupId>
+                    <artifactId>rest-assured</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
                     <groupId>junit</groupId>
                     <artifactId>junit</artifactId>
                     <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index 86f3f5e..73ef2f5 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Optional;
 
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.DefaultConfigurationBuilder;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.commons.io.FileUtils;
 import org.apache.james.filesystem.api.FileSystem;
@@ -44,6 +45,7 @@ import org.apache.james.modules.server.CamelMailetContainerModule;
 import org.apache.james.queue.api.MailQueueItemDecoratorFactory;
 import org.apache.james.transport.matchers.RecipientIsLocal;
 import org.apache.james.utils.ConfigurationPerformer;
+import org.apache.james.utils.FileConfigurationProvider;
 import org.apache.james.utils.PropertiesProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,6 +53,7 @@ import org.slf4j.LoggerFactory;
 import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Charsets;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
@@ -62,11 +65,23 @@ import com.google.inject.multibindings.Multibinder;
 public class JMAPModule extends AbstractModule {
     private static final int DEFAULT_JMAP_PORT = 80;
     private static final Logger LOGGER = LoggerFactory.getLogger(JMAPModule.class);
+    public static final CamelMailetContainerModule.DefaultProcessorsConfigurationSupplier DEFAULT_JMAP_PROCESSORS_CONFIGURATION_SUPPLIER =
+        () -> {
+            try {
+                return FileConfigurationProvider.getConfig(ClassLoader.getSystemResourceAsStream("defaultJmapMailetContainer.xml"));
+            } catch (ConfigurationException e) {
+                throw Throwables.propagate(e);
+            }
+        };
 
     @Override
     protected void configure() {
         install(new JMAPCommonModule());
         install(new MethodsModule());
+        install(binder -> binder
+            .bind(CamelMailetContainerModule.DefaultProcessorsConfigurationSupplier.class)
+            .toInstance(DEFAULT_JMAP_PROCESSORS_CONFIGURATION_SUPPLIER));
+
         bind(JMAPServer.class).in(Scopes.SINGLETON);
         bind(RequestHandler.class).in(Scopes.SINGLETON);
         bind(UploadHandler.class).in(Scopes.SINGLETON);

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
new file mode 100644
index 0000000..81386a4
--- /dev/null
+++ b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
@@ -0,0 +1,97 @@
+<!--
+  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.
+ -->
+
+<processors>
+    <processor state="root" enableJmx="false">
+        <mailet match="All" class="PostmasterAlias"/>
+        <mailet match="RelayLimit=30" class="Null"/>
+        <mailet match="All" class="ToProcessor">
+            <processor>transport</processor>
+        </mailet>
+    </processor>
+
+    <processor state="error" enableJmx="false">
+        <mailet match="All" class="Bounce"/>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+
+    <processor state="transport" enableJmx="false">
+        <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+            <name>X-UserIsAuth</name>
+            <value>true</value>
+        </mailet>
+        <mailet match="All" class="RemoveMimeHeader">
+            <name>bcc</name>
+        </mailet>
+        <mailet match="All" class="RecipientRewriteTable" />
+        <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
+        <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+        <mailet match="HostIsLocal" class="ToProcessor">
+            <processor>local-address-error</processor>
+            <notice>550 - Requested action not taken: no such user here</notice>
+        </mailet>
+        <mailet match="SMTPAuthSuccessful" class="ToProcessor">
+            <processor>relay</processor>
+        </mailet>
+        <mailet match="HasMailAttribute=org.apache.james.jmap.send.MailMetaData.messageId" class="ToProcessor">
+            <processor>relay</processor>
+        </mailet>
+        <mailet match="All" class="ToProcessor">
+            <processor>relay-denied</processor>
+        </mailet>
+    </processor>
+
+    <processor state="relay" enableJmx="true">
+        <mailet match="All" class="RemoteDelivery">
+            <outgoingQueue>outgoing</outgoingQueue>
+            <delayTime>5000, 100000, 500000</delayTime>
+            <maxRetries>25</maxRetries>
+            <maxDnsProblemRetries>0</maxDnsProblemRetries>
+            <deliveryThreads>10</deliveryThreads>
+            <sendpartial>true</sendpartial>
+            <bounceProcessor>bounces</bounceProcessor>
+        </mailet>
+    </processor>
+
+    <processor state="spam" enableJmx="false">
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="local-address-error" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="relay-denied" enableJmx="false">
+        <mailet match="All" class="Bounce">
+            <attachment>none</attachment>
+        </mailet>
+        <mailet match="All" class="Null"/>
+    </processor>
+
+    <processor state="bounces" enableJmx="false">
+        <mailet match="All" class="DSNBounce">
+            <passThrough>false</passThrough>
+        </mailet>
+    </processor>
+
+</processors>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
new file mode 100644
index 0000000..46a4394
--- /dev/null
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
@@ -0,0 +1,145 @@
+/****************************************************************
+ * 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;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.JmapGuiceProbe;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class AbstractJmapJamesServerTest {
+
+    private static final int IMAP_PORT_SSL = 1993;
+    private static final int POP3_PORT = 1110;
+    private static final int SMTP_PORT = 1025;
+    private static final int LMTP_PORT = 1024;
+
+    protected static final String JAMES_SERVER_HOST = "127.0.0.1";
+    protected static final int IMAP_PORT = 1143; // You need to be root (superuser) to bind to ports under 1024.
+
+    private GuiceJamesServer server;
+    private SocketChannel socketChannel;
+
+    @Before
+    public void setup() throws Exception {
+        server = createJamesServer();
+        socketChannel = SocketChannel.open();
+        server.start();
+
+        RestAssured.requestSpecification = new RequestSpecBuilder()
+            .setContentType(ContentType.JSON)
+            .setAccept(ContentType.JSON)
+            .setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8)))
+            .setPort(server.getProbe(JmapGuiceProbe.class).getJmapPort())
+            .build();
+    }
+
+    protected abstract GuiceJamesServer createJamesServer();
+
+    protected abstract void clean();
+
+    @After
+    public void tearDown() throws Exception {
+        if (server != null) {
+            server.stop();
+        }
+        clean();
+    }
+
+    @Test
+    public void hostnameShouldBeUsedAsDefaultDomain() throws Exception {
+        String expectedDefaultDomain = InetAddress.getLocalHost().getHostName();
+
+        assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
+    }
+
+    @Test
+    public void hostnameShouldBeRetrievedWhenRestarting() throws Exception {
+        server.stop();
+        server.start();
+        String expectedDefaultDomain = InetAddress.getLocalHost().getHostName();
+
+        assertThat(server.getProbe(DataProbeImpl.class).getDefaultDomain()).isEqualTo(expectedDefaultDomain);
+    }
+
+    @Test
+    public void connectIMAPServerShouldSendShabangOnConnect() throws Exception {
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, IMAP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server");
+    }
+
+    @Test
+    public void connectOnSecondaryIMAPServerIMAPServerShouldSendShabangOnConnect() throws Exception {
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, IMAP_PORT_SSL));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("* OK JAMES IMAP4rev1 Server");
+    }
+
+    @Test
+    public void connectPOP3ServerShouldSendShabangOnConnect() throws Exception {
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, POP3_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).contains("POP3 server (JAMES POP3 Server ) ready");
+    }
+
+    @Test
+    public void connectSMTPServerShouldSendShabangOnConnect() throws Exception {
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, SMTP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).startsWith("220 JAMES Linagora's SMTP awesome Server");
+    }
+
+    @Test
+    public void connectLMTPServerShouldSendShabangOnConnect() throws Exception {
+        socketChannel.connect(new InetSocketAddress(JAMES_SERVER_HOST, LMTP_PORT));
+        assertThat(getServerConnectionResponse(socketChannel)).contains("LMTP Server (JAMES Protocols Server) ready");
+    }
+
+    @Test
+    public void connectJMAPServerShouldRespondBadRequest() throws Exception {
+        given()
+            .body("{\"badAttributeName\": \"value\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    private String getServerConnectionResponse(SocketChannel socketChannel) throws IOException {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
+        socketChannel.read(byteBuffer);
+        byte[] bytes = byteBuffer.array();
+        return new String(bytes, Charset.forName("UTF-8"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3aea0817/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
index 7d8ff6c..e91ede4 100644
--- a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
+++ b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
@@ -388,6 +388,20 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
         filter = configuration.getString("[@filter]");
 
         administratorId = Optional.fromNullable(configuration.getString("[@administratorId]"));
+
+        checkState();
+    }
+
+    private void checkState() throws ConfigurationException {
+        if (userBase == null) {
+            throw new ConfigurationException("[@userBase] is mandatory");
+        }
+        if (userIdAttribute == null) {
+            throw new ConfigurationException("[@userIdAttribute] is mandatory");
+        }
+        if (userObjectClass == null) {
+            throw new ConfigurationException("[@userObjectClass] is mandatory");
+        }
     }
 
     /**


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


[10/17] james-project git commit: JAMES-2004 Make JMX configuration file optional

Posted by bt...@apache.org.
JAMES-2004 Make JMX configuration file optional


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fec6a27e
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fec6a27e
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fec6a27e

Branch: refs/heads/master
Commit: fec6a27ef5c60c54b60a6919939802d922ff74bb
Parents: 3aea081
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 10:22:38 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 .../apache/james/modules/server/JMXServer.java  | 24 ++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/fec6a27e/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServer.java
----------------------------------------------------------------------
diff --git a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServer.java b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServer.java
index 5078629..8be9f76 100644
--- a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServer.java
+++ b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServer.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.modules.server;
 
+import java.io.FileNotFoundException;
 import java.lang.management.ManagementFactory;
 import java.net.ServerSocket;
 import java.rmi.registry.LocateRegistry;
@@ -34,9 +35,13 @@ import javax.management.remote.JMXConnectorServer;
 import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
 
+import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.util.RestrictingRMISocketFactory;
+import org.apache.james.utils.PropertiesProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Throwables;
@@ -44,7 +49,9 @@ import com.google.common.collect.ImmutableMap;
 
 public class JMXServer {
 
-    private final FileSystem fileSystem;
+    private static final Logger LOGGER = LoggerFactory.getLogger(JMXServer.class);
+
+    private final PropertiesProvider propertiesProvider;
     private final Set<String> registeredKeys;
     private final Object lock;
     private JMXConnectorServer jmxConnectorServer;
@@ -52,8 +59,8 @@ public class JMXServer {
     private RestrictingRMISocketFactory restrictingRMISocketFactory;
 
     @Inject
-    public JMXServer(FileSystem fileSystem) {
-        this.fileSystem = fileSystem;
+    public JMXServer(PropertiesProvider propertiesProvider) {
+        this.propertiesProvider = propertiesProvider;
         isStarted = false;
         registeredKeys = new HashSet<>();
         lock = new Object();
@@ -89,7 +96,7 @@ public class JMXServer {
 
     private void doStart() {
         try {
-            PropertiesConfiguration configuration = new PropertiesConfiguration(fileSystem.getFile(FileSystem.FILE_PROTOCOL_AND_CONF + "jmx.properties"));
+            PropertiesConfiguration configuration = getPropertiesConfiguration();
             String address = configuration.getString("jmx.address", "localhost");
             int port = configuration.getInt("jmx.port", 9999);
             String serviceURL = "service:jmx:rmi://" + address + "/jndi/rmi://" + address+ ":" + port +"/jmxrmi";
@@ -107,6 +114,15 @@ public class JMXServer {
         }
     }
 
+    private PropertiesConfiguration getPropertiesConfiguration() throws ConfigurationException {
+        try {
+            return propertiesProvider.getConfiguration("jmx");
+        } catch (FileNotFoundException e) {
+            LOGGER.warn("Could not locate configuration file for JMX. Defaults to rmi://127.0.0.1:9999");
+            return new PropertiesConfiguration();
+        }
+    }
+
     private void doStop() {
         try {
             MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();


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


[14/17] james-project git commit: JAMES-2004 Adding tests for default configuration

Posted by bt...@apache.org.
JAMES-2004 Adding tests for default configuration


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/50c481d6
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/50c481d6
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/50c481d6

Branch: refs/heads/master
Commit: 50c481d60ec08758af630fa881c7f52de20158b1
Parents: e0f2a4c
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 15:07:20 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:29:34 2017 +0700

----------------------------------------------------------------------
 .../james/DefaultCassandraJamesServerTest.java  |  59 +++++++++
 .../java/org/apache/james/GuiceJamesServer.java |   7 ++
 .../james/utils/FailingPropertiesProvider.java  |  41 +++++++
 .../james/DefaultMemoryJamesServerTest.java     |  59 +++++++++
 .../org/apache/james/GuiceJamesServerTest.java  | 121 +++++++++++++++++++
 5 files changed, 287 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/50c481d6/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DefaultCassandraJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DefaultCassandraJamesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DefaultCassandraJamesServerTest.java
new file mode 100644
index 0000000..4c41e12
--- /dev/null
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DefaultCassandraJamesServerTest.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.utils.ConfigurationProvider;
+import org.apache.james.utils.FailingPropertiesProvider;
+import org.apache.james.utils.PropertiesProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DefaultCassandraJamesServerTest {
+
+    @Rule
+    public CassandraJmapTestRule cassandraJmap = CassandraJmapTestRule.defaultTestRule();
+
+    private GuiceJamesServer guiceJamesServer;
+
+    @Before
+    public void setUp() {
+        guiceJamesServer = cassandraJmap.jmapServer()
+            .overrideWith(binder -> binder.bind(PropertiesProvider.class).to(FailingPropertiesProvider.class))
+            .overrideWith(binder -> binder.bind(ConfigurationProvider.class).toInstance(s -> new HierarchicalConfiguration()));
+    }
+
+    @After
+    public void clean() {
+        guiceJamesServer.stop();
+    }
+
+    @Test
+    public void memoryJamesServerShouldStartWithNoConfigurationFile() throws Exception {
+        guiceJamesServer.start();
+
+        assertThat(guiceJamesServer.isStarted()).isTrue();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/50c481d6/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java b/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
index b9a5bd0..075f5c4 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/GuiceJamesServer.java
@@ -42,6 +42,7 @@ public class GuiceJamesServer {
     protected final Module module;
     private Stager<PreDestroy> preDestroy;
     private GuiceProbeProvider guiceProbeProvider;
+    private boolean isStarted = false;
 
     public GuiceJamesServer() {
         this(Modules.combine(
@@ -66,14 +67,20 @@ public class GuiceJamesServer {
         preDestroy = injector.getInstance(Key.get(new TypeLiteral<Stager<PreDestroy>>() {}));
         injector.getInstance(ConfigurationsPerformer.class).initModules();
         guiceProbeProvider = injector.getInstance(GuiceProbeProvider.class);
+        isStarted = true;
     }
 
     public void stop() {
         if (preDestroy != null) {
             preDestroy.stage();
+            isStarted = false;
         }
     }
 
+    public boolean isStarted() {
+        return isStarted;
+    }
+
     public <T extends GuiceProbe> T getProbe(Class<T> probe) {
         return guiceProbeProvider.getProbe(probe);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/50c481d6/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FailingPropertiesProvider.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FailingPropertiesProvider.java b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FailingPropertiesProvider.java
new file mode 100644
index 0000000..c134952
--- /dev/null
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/utils/FailingPropertiesProvider.java
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.utils;
+
+import java.io.FileNotFoundException;
+
+import javax.inject.Inject;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.james.filesystem.api.FileSystem;
+
+public class FailingPropertiesProvider extends PropertiesProvider {
+
+    @Inject
+    public FailingPropertiesProvider(FileSystem fileSystem) {
+        super(fileSystem);
+    }
+
+    @Override
+    public PropertiesConfiguration getConfiguration(String fileName) throws FileNotFoundException, ConfigurationException {
+        throw new FileNotFoundException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/50c481d6/server/container/guice/memory-guice/src/test/java/org/apache/james/DefaultMemoryJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/java/org/apache/james/DefaultMemoryJamesServerTest.java b/server/container/guice/memory-guice/src/test/java/org/apache/james/DefaultMemoryJamesServerTest.java
new file mode 100644
index 0000000..ec90ac2
--- /dev/null
+++ b/server/container/guice/memory-guice/src/test/java/org/apache/james/DefaultMemoryJamesServerTest.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.utils.ConfigurationProvider;
+import org.apache.james.utils.FailingPropertiesProvider;
+import org.apache.james.utils.PropertiesProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DefaultMemoryJamesServerTest {
+
+    @Rule
+    public MemoryJmapTestRule memoryJmap = new MemoryJmapTestRule();
+
+    private GuiceJamesServer guiceJamesServer;
+
+    @Before
+    public void setUp() {
+        guiceJamesServer = memoryJmap.jmapServer()
+            .overrideWith(binder -> binder.bind(PropertiesProvider.class).to(FailingPropertiesProvider.class))
+            .overrideWith(binder -> binder.bind(ConfigurationProvider.class).toInstance(s -> new HierarchicalConfiguration()));
+    }
+
+    @After
+    public void clean() {
+        guiceJamesServer.stop();
+    }
+
+    @Test
+    public void memoryJamesServerShouldStartWithNoConfigurationFile() throws Exception {
+        guiceJamesServer.start();
+
+        assertThat(guiceJamesServer.isStarted()).isTrue();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/50c481d6/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerTest.java b/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerTest.java
new file mode 100644
index 0000000..59327bb
--- /dev/null
+++ b/server/container/guice/memory-guice/src/test/java/org/apache/james/GuiceJamesServerTest.java
@@ -0,0 +1,121 @@
+package org.apache.james;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import org.apache.james.lifecycle.api.Configurable;
+import org.apache.james.utils.ConfigurationPerformer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.multibindings.Multibinder;
+
+public class GuiceJamesServerTest {
+
+    public static final ConfigurationPerformer THROWING_CONFIGURATION_PERFORMER = new ConfigurationPerformer() {
+        @Override
+        public void initModule() {
+            throw new RuntimeException();
+        }
+
+        @Override
+        public List<Class<? extends Configurable>> forClasses() {
+            return ImmutableList.of();
+        }
+    };
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Rule
+    public MemoryJmapTestRule memoryJmapTestRule = new MemoryJmapTestRule();
+    private GuiceJamesServer guiceJamesServer;
+
+
+    @Before
+    public void setUp() {
+        guiceJamesServer = memoryJmapTestRule.jmapServer();
+    }
+
+    @After
+    public void tearDown() {
+        guiceJamesServer.stop();
+    }
+
+    @Test
+    public void serverShouldBeStartedAfterCallingStart() throws Exception {
+        guiceJamesServer.start();
+
+        assertThat(guiceJamesServer.isStarted()).isTrue();
+    }
+
+    @Test
+    public void serverShouldNotBeStartedAfterCallingStop() throws Exception {
+        guiceJamesServer.start();
+
+        guiceJamesServer.stop();
+
+        assertThat(guiceJamesServer.isStarted()).isFalse();
+    }
+
+    @Test
+    public void serverShouldNotBeStartedBeforeCallingStart() throws Exception {
+        assertThat(guiceJamesServer.isStarted()).isFalse();
+    }
+
+    @Test
+    public void serverShouldPropagateUncaughtConfigurationException() throws Exception {
+        expectedException.expect(RuntimeException.class);
+
+        GuiceJamesServer overWrittenServer = null;
+
+        try {
+            overWrittenServer = this.guiceJamesServer.overrideWith(
+                binder -> Multibinder.newSetBinder(binder, ConfigurationPerformer.class).addBinding().toInstance(
+                    new ConfigurationPerformer() {
+                        @Override
+                        public void initModule() {
+                            throw new RuntimeException();
+                        }
+
+                        @Override
+                        public List<Class<? extends Configurable>> forClasses() {
+                            return ImmutableList.of();
+                        }
+                    }
+                )
+            );
+            overWrittenServer.start();
+        } finally {
+            if (overWrittenServer != null) {
+                overWrittenServer.stop();
+            }
+        }
+    }
+
+    @Test
+    public void serverShouldNotBeStartedOnUncaughtException() throws Exception {
+        GuiceJamesServer overWrittenServer = null;
+
+        try {
+            overWrittenServer = this.guiceJamesServer.overrideWith(
+                binder -> Multibinder.newSetBinder(binder, ConfigurationPerformer.class)
+                    .addBinding()
+                    .toInstance(THROWING_CONFIGURATION_PERFORMER));
+
+            try {
+                overWrittenServer.start();
+            } catch (RuntimeException e) {}
+
+            assertThat(overWrittenServer.isStarted()).isFalse();
+        } finally {
+            if (overWrittenServer != null) {
+                overWrittenServer.stop();
+            }
+        }
+    }
+}


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


[02/17] james-project git commit: JAMES-1999 Elasticsearch does not retry to connect when error

Posted by bt...@apache.org.
JAMES-1999 Elasticsearch does not retry to connect when error


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d258d900
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d258d900
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d258d900

Branch: refs/heads/master
Commit: d258d900fea5c220480bcaad095942ecd59d2b12
Parents: 6c5912f
Author: quynhn <qn...@linagora.com>
Authored: Fri Apr 14 09:48:31 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 07:52:19 2017 +0700

----------------------------------------------------------------------
 .../modules/mailbox/CassandraSessionModule.java | 43 ++++++++++++--------
 .../mailbox/ElasticSearchMailboxModule.java     | 26 ++++++------
 2 files changed, 40 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d258d900/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
index 8146c5a..8b92f99 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
@@ -29,6 +29,7 @@ import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
 import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
+import com.nurkiewicz.asyncretry.function.RetryCallable;
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.james.backends.cassandra.components.CassandraModule;
@@ -40,6 +41,9 @@ import org.apache.james.backends.cassandra.init.QueryLoggerConfiguration;
 import org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.util.Host;
+import org.apache.james.utils.RetryExecutorUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.FileNotFoundException;
 import java.util.Arrays;
@@ -51,6 +55,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
 public class CassandraSessionModule extends AbstractModule {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraSessionModule.class);
 
     private static final int DEFAULT_CONNECTION_MAX_RETRIES = 10;
     private static final int DEFAULT_CONNECTION_MIN_DELAY = 5000;
@@ -91,19 +96,30 @@ public class CassandraSessionModule extends AbstractModule {
         List<Host> servers = listCassandraServers(configuration);
         QueryLoggerConfiguration queryLoggerConfiguration = getCassandraQueryLoggerConf(configuration);
 
-        return getRetryer(executor, configuration)
-                .getWithRetry(ctx -> ClusterWithKeyspaceCreatedFactory
-                        .config(
-                            ClusterBuilder.builder()
-                                .servers(servers)
-                                .queryLoggerConfiguration(queryLoggerConfiguration)
-                                .build(),
-                            configuration.getString("cassandra.keyspace"))
-                        .replicationFactor(configuration.getInt("cassandra.replication.factor"))
-                        .clusterWithInitializedKeyspace())
+        int maxRetries = configuration.getInt("cassandra.retryConnection.maxRetries", DEFAULT_CONNECTION_MAX_RETRIES);
+        int minDelay = configuration.getInt("cassandra.retryConnection.minDelay", DEFAULT_CONNECTION_MIN_DELAY);
+
+        return RetryExecutorUtil.retryOnExceptions(executor, maxRetries, minDelay, NoHostAvailableException.class)
+                .getWithRetry(getClusterRetryCallable(configuration, servers, queryLoggerConfiguration))
                 .get();
     }
 
+    private RetryCallable<Cluster> getClusterRetryCallable(PropertiesConfiguration configuration, List<Host> servers, QueryLoggerConfiguration queryLoggerConfiguration) {
+        LOGGER.info("Trying to connect to Cassandra service");
+
+        return context -> ClusterWithKeyspaceCreatedFactory
+            .config(getCluster(servers, queryLoggerConfiguration), configuration.getString("cassandra.keyspace"))
+            .replicationFactor(configuration.getInt("cassandra.replication.factor"))
+            .clusterWithInitializedKeyspace();
+    }
+
+    private Cluster getCluster(List<Host> servers, QueryLoggerConfiguration queryLoggerConfiguration) {
+        return ClusterBuilder.builder()
+            .servers(servers)
+            .queryLoggerConfiguration(queryLoggerConfiguration)
+            .build();
+    }
+
     private List<Host> listCassandraServers(PropertiesConfiguration configuration) {
         String[] ipAndPorts = configuration.getStringArray("cassandra.nodes");
 
@@ -154,13 +170,6 @@ public class CassandraSessionModule extends AbstractModule {
         return builder.build();
     }
 
-    private static AsyncRetryExecutor getRetryer(AsyncRetryExecutor executor, PropertiesConfiguration configuration) {
-        return executor.retryOn(NoHostAvailableException.class)
-                .withProportionalJitter()
-                .withMaxRetries(configuration.getInt("cassandra.retryConnection.maxRetries", DEFAULT_CONNECTION_MAX_RETRIES))
-                .withMinDelay(configuration.getInt("cassandra.retryConnection.minDelay", DEFAULT_CONNECTION_MIN_DELAY));
-    }
-
     @Provides
     private AsyncRetryExecutor provideAsyncRetryExecutor(ScheduledExecutorService scheduler) {
         return new AsyncRetryExecutor(scheduler);

http://git-wip-us.apache.org/repos/asf/james-project/blob/d258d900/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 4c3c9ef..48c4145 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
@@ -42,8 +42,11 @@ import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 import org.apache.james.mailbox.tika.extractor.TikaTextExtractor;
+import org.apache.james.utils.RetryExecutorUtil;
 import org.elasticsearch.client.Client;
 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;
@@ -52,6 +55,7 @@ import com.google.inject.Scopes;
 import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
 
 public class ElasticSearchMailboxModule extends AbstractModule {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchMailboxModule.class);
 
     public static final String ES_CONFIG_FILE = FileSystem.FILE_PROTOCOL_AND_CONF + "elasticsearch.properties";
     public static final String ELASTICSEARCH_HOSTS = "elasticsearch.hosts";
@@ -77,11 +81,17 @@ public class ElasticSearchMailboxModule extends AbstractModule {
     @Singleton
     protected Client provideClientProvider(FileSystem fileSystem, AsyncRetryExecutor executor) throws ConfigurationException, FileNotFoundException, ExecutionException, InterruptedException {
         PropertiesConfiguration propertiesReader = new PropertiesConfiguration(fileSystem.getFile(ES_CONFIG_FILE));
+        int maxRetries = propertiesReader.getInt("elasticsearch.retryConnection.maxRetries", DEFAULT_CONNECTION_MAX_RETRIES);
+        int minDelay = propertiesReader.getInt("elasticsearch.retryConnection.minDelay", DEFAULT_CONNECTION_MIN_DELAY);
 
-        ClientProvider clientProvider = connectToCluster(propertiesReader);
+        return RetryExecutorUtil.retryOnExceptions(executor, maxRetries, minDelay, NoNodeAvailableException.class)
+            .getWithRetry(context -> connectToCluster(propertiesReader))
+            .get();
+    }
 
-        Client client = getRetryer(executor, propertiesReader)
-                .getWithRetry(ctx -> clientProvider.get()).get();
+    private Client createClientAndIndex(ClientProvider clientProvider, PropertiesConfiguration propertiesReader) {
+        LOGGER.info("Trying to connect to ElasticSearch service");
+        Client client = clientProvider.get();
         IndexCreationFactory.createIndex(client,
             MailboxElasticsearchConstants.MAILBOX_INDEX,
             propertiesReader.getInt("elasticsearch.nb.shards"),
@@ -122,15 +132,7 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         }
     }
 
-    private static AsyncRetryExecutor getRetryer(AsyncRetryExecutor executor, PropertiesConfiguration configuration) {
-        return executor
-                .withProportionalJitter()
-                .retryOn(NoNodeAvailableException.class)
-                .withMaxRetries(configuration.getInt("elasticsearch.retryConnection.maxRetries", DEFAULT_CONNECTION_MAX_RETRIES))
-                .withMinDelay(configuration.getInt("elasticsearch.retryConnection.minDelay", DEFAULT_CONNECTION_MIN_DELAY));
-    }
-
-    @Provides 
+    @Provides
     @Singleton
     public IndexAttachments provideIndexAttachments(PropertiesConfiguration configuration) {
         if (configuration.getBoolean("elasticsearch.indexAttachments", DEFAULT_INDEX_ATTACHMENTS)) {


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


[09/17] james-project git commit: JAMES-2004 Adding default options for ElasticSearch shards and replica

Posted by bt...@apache.org.
JAMES-2004 Adding default options for ElasticSearch shards and replica


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/e0f2a4c5
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/e0f2a4c5
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/e0f2a4c5

Branch: refs/heads/master
Commit: e0f2a4c53ef779bfdeab044d08f64361fac77c9a
Parents: b2a1425
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 13:46:21 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 .../mailbox/ElasticSearchMailboxModule.java        | 17 ++++++++++-------
 .../modules/server/ESMetricReporterModule.java     | 13 ++++---------
 2 files changed, 14 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/e0f2a4c5/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 43ba8ff..d1b124b 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
@@ -57,13 +57,16 @@ import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
 public class ElasticSearchMailboxModule extends AbstractModule {
     private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchMailboxModule.class);
 
-    public static final String ES_CONFIG_FILE = FileSystem.FILE_PROTOCOL_AND_CONF + "elasticsearch.properties";
+    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
     protected void configure() {
@@ -92,8 +95,8 @@ public class ElasticSearchMailboxModule extends AbstractModule {
     private Client createIndexAndMapping(Client client, PropertiesConfiguration propertiesReader) {
         IndexCreationFactory.createIndex(client,
             MailboxElasticsearchConstants.MAILBOX_INDEX,
-            propertiesReader.getInt("elasticsearch.nb.shards"),
-            propertiesReader.getInt("elasticsearch.nb.replica"));
+            propertiesReader.getInt(ELASTICSEARCH_CONFIGURATION_NAME + ".nb.shards", DEFAULT_NB_SHARDS),
+            propertiesReader.getInt(ELASTICSEARCH_CONFIGURATION_NAME + ".nb.replica", DEFAULT_NB_REPLICA));
         NodeMappingFactory.applyMapping(client,
             MailboxElasticsearchConstants.MAILBOX_INDEX,
             MailboxElasticsearchConstants.MESSAGE_TYPE,
@@ -111,12 +114,12 @@ public class ElasticSearchMailboxModule extends AbstractModule {
     @Singleton
     private ElasticSearchConfiguration getElasticSearchConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
         try {
-            PropertiesConfiguration configuration = propertiesProvider.getConfiguration("elasticsearch");
+            PropertiesConfiguration configuration = propertiesProvider.getConfiguration(ELASTICSEARCH_CONFIGURATION_NAME);
             return () -> configuration;
         } catch (FileNotFoundException e) {
-            LOGGER.warn("Could not find elasticsearch configuration file. Using 127.0.0.1:9300 as contact point");
+            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, "127.0.0.1");
+            propertiesConfiguration.addProperty(ELASTICSEARCH_HOSTS, LOCALHOST);
             return () -> propertiesConfiguration;
         }
     }
@@ -153,7 +156,7 @@ public class ElasticSearchMailboxModule extends AbstractModule {
     @Provides
     @Singleton
     public IndexAttachments provideIndexAttachments(PropertiesConfiguration configuration) {
-        if (configuration.getBoolean("elasticsearch.indexAttachments", DEFAULT_INDEX_ATTACHMENTS)) {
+        if (configuration.getBoolean(ELASTICSEARCH_CONFIGURATION_NAME + ".indexAttachments", DEFAULT_INDEX_ATTACHMENTS)) {
             return IndexAttachments.YES;
         }
         return IndexAttachments.NO;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e0f2a4c5/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/server/ESMetricReporterModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/server/ESMetricReporterModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/server/ESMetricReporterModule.java
index d0229dd..b6906bc 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/server/ESMetricReporterModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/server/ESMetricReporterModule.java
@@ -26,12 +26,12 @@ import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.commons.lang.NotImplementedException;
-import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.metrics.es.ESMetricReporter;
 import org.apache.james.metrics.es.ESReporterConfiguration;
 import org.apache.james.modules.mailbox.ElasticSearchMailboxModule;
 import org.apache.james.utils.ConfigurationPerformer;
+import org.apache.james.utils.PropertiesProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,9 +54,9 @@ public class ESMetricReporterModule extends AbstractModule {
     }
 
     @Provides
-    public ESReporterConfiguration provideConfiguration(FileSystem fileSystem) throws ConfigurationException {
+    public ESReporterConfiguration provideConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
         try {
-            PropertiesConfiguration propertiesReader = getPropertiesConfiguration(fileSystem);
+            PropertiesConfiguration propertiesReader = propertiesProvider.getConfiguration(ElasticSearchMailboxModule.ELASTICSEARCH_CONFIGURATION_NAME);
 
             if (isMetricEnable(propertiesReader)) {
                 return ESReporterConfiguration.builder()
@@ -68,7 +68,7 @@ public class ESMetricReporterModule extends AbstractModule {
                     .build();
             }
         } catch (FileNotFoundException e) {
-            LOGGER.info("Can not locate " + ElasticSearchMailboxModule.ES_CONFIG_FILE);
+            LOGGER.info("Can not locate " + ElasticSearchMailboxModule.ELASTICSEARCH_CONFIGURATION_NAME + " configuration");
         }
         return ESReporterConfiguration.builder()
             .disabled()
@@ -84,11 +84,6 @@ public class ESMetricReporterModule extends AbstractModule {
         return propertiesReader.getBoolean("elasticsearch.metrics.reports.enabled", DEFAULT_DISABLE);
     }
 
-    private PropertiesConfiguration getPropertiesConfiguration(FileSystem fileSystem) throws ConfigurationException, FileNotFoundException {
-        return new PropertiesConfiguration(
-                    fileSystem.getFile(ElasticSearchMailboxModule.ES_CONFIG_FILE));
-    }
-
     @Singleton
     public static class ESMetricReporterStarter implements ConfigurationPerformer, Configurable {
 


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


[13/17] james-project git commit: JAMES-2004 Fail when file not found in PropertiesProvider

Posted by bt...@apache.org.
JAMES-2004 Fail when file not found in PropertiesProvider


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/9f7a4dc0
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/9f7a4dc0
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/9f7a4dc0

Branch: refs/heads/master
Commit: 9f7a4dc0c848042459f259192b8f50c813543830
Parents: fec6a27
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 12:37:55 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 .../main/java/org/apache/james/utils/PropertiesProvider.java  | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9f7a4dc0/server/container/guice/configuration/src/main/java/org/apache/james/utils/PropertiesProvider.java
----------------------------------------------------------------------
diff --git a/server/container/guice/configuration/src/main/java/org/apache/james/utils/PropertiesProvider.java b/server/container/guice/configuration/src/main/java/org/apache/james/utils/PropertiesProvider.java
index 780b5ee..d9a090a 100644
--- a/server/container/guice/configuration/src/main/java/org/apache/james/utils/PropertiesProvider.java
+++ b/server/container/guice/configuration/src/main/java/org/apache/james/utils/PropertiesProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.utils;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 
 import javax.inject.Inject;
@@ -41,6 +42,10 @@ public class PropertiesProvider {
 
     public PropertiesConfiguration getConfiguration(String fileName) throws FileNotFoundException, ConfigurationException {
         Preconditions.checkArgument(!Strings.isNullOrEmpty(fileName));
-        return new PropertiesConfiguration(fileSystem.getFile(FileSystem.FILE_PROTOCOL_AND_CONF + fileName + ".properties"));
+        File file = fileSystem.getFile(FileSystem.FILE_PROTOCOL_AND_CONF + fileName + ".properties");
+        if (!file.exists()) {
+            throw new FileNotFoundException();
+        }
+        return new PropertiesConfiguration(file);
     }
 }
\ No newline at end of file


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


[12/17] james-project git commit: JAMES-2004 Provide default values for Cassandra keyspace and replication factor

Posted by bt...@apache.org.
JAMES-2004 Provide default values for Cassandra keyspace and replication factor


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ac3fb27c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ac3fb27c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ac3fb27c

Branch: refs/heads/master
Commit: ac3fb27c215dfc9027293d9fec92d9103a9c944f
Parents: 9f7a4dc
Author: benwa <bt...@linagora.com>
Authored: Tue Apr 18 13:29:18 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Apr 21 08:27:41 2017 +0700

----------------------------------------------------------------------
 .../apache/james/modules/mailbox/CassandraSessionModule.java | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ac3fb27c/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
index 8b92f99..7180599 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java
@@ -60,6 +60,8 @@ public class CassandraSessionModule extends AbstractModule {
     private static final int DEFAULT_CONNECTION_MAX_RETRIES = 10;
     private static final int DEFAULT_CONNECTION_MIN_DELAY = 5000;
     private static final long CASSANDRA_HIGHEST_TRACKABLE_LATENCY_MILLIS = TimeUnit.SECONDS.toMillis(10);
+    public static final int DEFAULT_REPLICATION_FACTOR = 1;
+    public static final String DEFAULT_KEYSPACE = "apache_james";
 
     @Override
     protected void configure() {
@@ -79,7 +81,7 @@ public class CassandraSessionModule extends AbstractModule {
     @Singleton
     Session provideSession(CassandraSessionConfiguration configuration, Cluster cluster, CassandraModule cassandraModule)
             throws FileNotFoundException, ConfigurationException{
-        String keyspace = configuration.getConfiguration().getString("cassandra.keyspace");
+        String keyspace = configuration.getConfiguration().getString("cassandra.keyspace", DEFAULT_KEYSPACE);
         return new SessionWithInitializedTablesFactory(cassandraModule).createSession(cluster, keyspace);
     }
 
@@ -108,8 +110,8 @@ public class CassandraSessionModule extends AbstractModule {
         LOGGER.info("Trying to connect to Cassandra service");
 
         return context -> ClusterWithKeyspaceCreatedFactory
-            .config(getCluster(servers, queryLoggerConfiguration), configuration.getString("cassandra.keyspace"))
-            .replicationFactor(configuration.getInt("cassandra.replication.factor"))
+            .config(getCluster(servers, queryLoggerConfiguration), configuration.getString("cassandra.keyspace", DEFAULT_KEYSPACE))
+            .replicationFactor(configuration.getInt("cassandra.replication.factor", DEFAULT_REPLICATION_FACTOR))
             .clusterWithInitializedKeyspace();
     }
 


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