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 <btell...@linagora.com> Authored: Tue Apr 18 08:14:09 2017 +0700 Committer: benwa <btell...@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-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org