You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/01/19 03:21:54 UTC
[james-project] 01/03: JAMES-3867 Allow IMAP extensions configuration
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit e1377cdc6fc9c0a419d290bf6b85cfa3e127a2e7
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 16 10:51:07 2023 +0700
JAMES-3867 Allow IMAP extensions configuration
One can define custom, per-IMAP server
configuration values.
---
.../apache/james/examples/imap/PingProcessor.java | 16 +++++++++++++--
.../custom-imap/src/main/resources/imapserver.xml | 15 ++------------
.../examples/imap/ImapCustomPackagesTest.java | 9 ++++++++-
.../apache/james/imap/api/ImapConfiguration.java | 23 +++++++++++++++++++---
.../apache/james/imapserver/netty/IMAPServer.java | 1 +
.../netty/IMAPServerConfigurationTest.java | 7 +++++++
6 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/examples/custom-imap/src/main/java/org/apache/james/examples/imap/PingProcessor.java b/examples/custom-imap/src/main/java/org/apache/james/examples/imap/PingProcessor.java
index a308295870..fe26a5c6a3 100644
--- a/examples/custom-imap/src/main/java/org/apache/james/examples/imap/PingProcessor.java
+++ b/examples/custom-imap/src/main/java/org/apache/james/examples/imap/PingProcessor.java
@@ -19,8 +19,11 @@
package org.apache.james.examples.imap;
+import java.util.Properties;
+
import javax.inject.Inject;
+import org.apache.james.imap.api.ImapConfiguration;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.api.message.response.StatusResponseFactory;
import org.apache.james.imap.api.process.ImapSession;
@@ -30,8 +33,8 @@ import org.apache.james.util.MDCBuilder;
import reactor.core.publisher.Mono;
public class PingProcessor extends AbstractProcessor<PingImapPackages.PingRequest> {
-
private final StatusResponseFactory factory;
+ private String pongResponse;
@Inject
public PingProcessor(StatusResponseFactory factory) {
@@ -39,10 +42,19 @@ public class PingProcessor extends AbstractProcessor<PingImapPackages.PingReques
this.factory = factory;
}
+ @Override
+ public void configure(ImapConfiguration imapConfiguration) {
+ Properties customProperties = imapConfiguration.getCustomProperties();
+
+ pongResponse = (String) customProperties
+ .getOrDefault("pong.response", "completed.");
+ }
+
@Override
protected Mono<Void> doProcess(PingImapPackages.PingRequest request, Responder responder, ImapSession session) {
return Mono.fromRunnable(() -> responder.respond(new PingImapPackages.PingResponse()))
- .then(Mono.fromRunnable(() -> responder.respond(factory.taggedOk(request.getTag(), request.getCommand(), HumanReadableText.COMPLETED))));
+ .then(Mono.fromRunnable(() -> responder.respond(
+ factory.taggedOk(request.getTag(), request.getCommand(), new HumanReadableText("org.apache.james.imap.COMPLETED", pongResponse)))));
}
@Override
diff --git a/examples/custom-imap/src/main/resources/imapserver.xml b/examples/custom-imap/src/main/resources/imapserver.xml
index c9eff82382..a6c9d42c66 100644
--- a/examples/custom-imap/src/main/resources/imapserver.xml
+++ b/examples/custom-imap/src/main/resources/imapserver.xml
@@ -33,19 +33,8 @@ under the License.
<connectionLimitPerIP>0</connectionLimitPerIP>
<plainAuthDisallowed>false</plainAuthDisallowed>
<gracefulShutdown>false</gracefulShutdown>
- </imapserver>
- <imapserver enabled="true">
- <jmxName>imapserver-ssl</jmxName>
- <bind>0.0.0.0:0</bind>
- <connectionBacklog>200</connectionBacklog>
- <tls socketTLS="false" startTLS="true">
- <keystore>classpath://keystore</keystore>
- <secret>james72laBalle</secret>
- <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
- </tls>
- <connectionLimit>0</connectionLimit>
- <connectionLimitPerIP>0</connectionLimitPerIP>
- <gracefulShutdown>false</gracefulShutdown>
+ <customProperties>pong.response=customImapParameter</customProperties>
+ <customProperties>prop.b=anotherValue</customProperties>
</imapserver>
<imapPackages>org.apache.james.modules.protocols.DefaultImapPackage</imapPackages>
<imapPackages>org.apache.james.examples.imap.PingImapPackages</imapPackages>
diff --git a/examples/custom-imap/src/test/java/org/apache/james/examples/imap/ImapCustomPackagesTest.java b/examples/custom-imap/src/test/java/org/apache/james/examples/imap/ImapCustomPackagesTest.java
index cc50e91782..b9ff7387c5 100644
--- a/examples/custom-imap/src/test/java/org/apache/james/examples/imap/ImapCustomPackagesTest.java
+++ b/examples/custom-imap/src/test/java/org/apache/james/examples/imap/ImapCustomPackagesTest.java
@@ -39,7 +39,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
-public class ImapCustomPackagesTest {
+class ImapCustomPackagesTest {
@RegisterExtension
static JamesServerExtension jamesServerExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
@@ -67,4 +67,11 @@ public class ImapCustomPackagesTest {
.contains("PONG");
}
+ @Test
+ void imapServerShouldSupportCustomConfigurationValues(GuiceJamesServer server) throws IOException {
+ assertThat(new TestIMAPClient().connect("127.0.0.1", server.getProbe(ImapGuiceProbe.class).getImapPort())
+ .login(BOB, BOB_PASSWORD)
+ .sendCommand("PING"))
+ .contains("customImapParameter");
+ }
}
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
index bb92d5b6e3..f42a9117d8 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
@@ -21,6 +21,7 @@ package org.apache.james.imap.api;
import java.time.Duration;
import java.util.Optional;
+import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
@@ -58,6 +59,7 @@ public class ImapConfiguration {
private Optional<Boolean> enableIdle;
private ImmutableSet<String> disabledCaps;
private Optional<Boolean> isCondstoreEnable;
+ private Optional<Properties> customProperties;
private Builder() {
this.appendLimit = Optional.empty();
@@ -68,6 +70,7 @@ public class ImapConfiguration {
this.enableIdle = Optional.empty();
this.disabledCaps = ImmutableSet.of();
this.isCondstoreEnable = Optional.empty();
+ this.customProperties = Optional.empty();
}
public Builder idleTimeInterval(long idleTimeInterval) {
@@ -127,6 +130,11 @@ public class ImapConfiguration {
return this;
}
+ public Builder withCustomProperties(Properties customProperties) {
+ this.customProperties = Optional.of(customProperties);
+ return this;
+ }
+
public ImapConfiguration build() {
ImmutableSet<Capability> normalizeDisableCaps = disabledCaps.stream()
.filter(Builder::noBlankString)
@@ -141,7 +149,8 @@ public class ImapConfiguration {
maxQueueSize.orElse(DEFAULT_QUEUE_SIZE),
idleTimeIntervalUnit.orElse(DEFAULT_HEARTBEAT_INTERVAL_UNIT),
normalizeDisableCaps,
- isCondstoreEnable.orElse(DEFAULT_CONDSTORE_DISABLE));
+ isCondstoreEnable.orElse(DEFAULT_CONDSTORE_DISABLE),
+ customProperties.orElseGet(Properties::new));
}
}
@@ -153,8 +162,9 @@ public class ImapConfiguration {
private final ImmutableSet<Capability> disabledCaps;
private final boolean enableIdle;
private final boolean isCondstoreEnable;
+ private final Properties customProperties;
- private ImapConfiguration(Optional<Long> appendLimit, boolean enableIdle, long idleTimeInterval, int concurrentRequests, int maxQueueSize, TimeUnit idleTimeIntervalUnit, ImmutableSet<Capability> disabledCaps, boolean isCondstoreEnable) {
+ private ImapConfiguration(Optional<Long> appendLimit, boolean enableIdle, long idleTimeInterval, int concurrentRequests, int maxQueueSize, TimeUnit idleTimeIntervalUnit, ImmutableSet<Capability> disabledCaps, boolean isCondstoreEnable, Properties customProperties) {
this.appendLimit = appendLimit;
this.enableIdle = enableIdle;
this.idleTimeInterval = idleTimeInterval;
@@ -163,6 +173,7 @@ public class ImapConfiguration {
this.idleTimeIntervalUnit = idleTimeIntervalUnit;
this.disabledCaps = disabledCaps;
this.isCondstoreEnable = isCondstoreEnable;
+ this.customProperties = customProperties;
}
public Optional<Long> getAppendLimit() {
@@ -201,6 +212,10 @@ public class ImapConfiguration {
return Duration.of(getIdleTimeInterval(), getIdleTimeIntervalUnit().toChronoUnit());
}
+ public Properties getCustomProperties() {
+ return customProperties;
+ }
+
@Override
public final boolean equals(Object obj) {
if (obj instanceof ImapConfiguration) {
@@ -212,6 +227,7 @@ public class ImapConfiguration {
&& Objects.equal(that.getConcurrentRequests(), concurrentRequests)
&& Objects.equal(that.getMaxQueueSize(), maxQueueSize)
&& Objects.equal(that.getDisabledCaps(), disabledCaps)
+ && Objects.equal(that.getCustomProperties(), customProperties)
&& Objects.equal(that.isCondstoreEnable(), isCondstoreEnable);
}
return false;
@@ -220,7 +236,7 @@ public class ImapConfiguration {
@Override
public final int hashCode() {
return Objects.hashCode(enableIdle, idleTimeInterval, idleTimeIntervalUnit, disabledCaps, isCondstoreEnable,
- concurrentRequests, maxQueueSize, appendLimit);
+ concurrentRequests, maxQueueSize, appendLimit, customProperties);
}
@Override
@@ -234,6 +250,7 @@ public class ImapConfiguration {
.add("isCondstoreEnable", isCondstoreEnable)
.add("concurrentRequests", concurrentRequests)
.add("maxQueueSize", maxQueueSize)
+ .add("customProperties", customProperties)
.toString();
}
}
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
index 073db65280..0ce7dd543e 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
@@ -202,6 +202,7 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
.appendLimit(Optional.of(parseLiteralSizeLimit(configuration)).filter(i -> i > 0))
.maxQueueSize(configuration.getInteger("maxQueueSize", ImapConfiguration.DEFAULT_QUEUE_SIZE))
.concurrentRequests(configuration.getInteger("concurrentRequests", ImapConfiguration.DEFAULT_CONCURRENT_REQUESTS))
+ .withCustomProperties(configuration.getProperties("customProperties"))
.build();
}
diff --git a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerConfigurationTest.java b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerConfigurationTest.java
index d8060a3fda..4a73081d1d 100644
--- a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerConfigurationTest.java
+++ b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerConfigurationTest.java
@@ -21,6 +21,7 @@ package org.apache.james.imapserver.netty;
import static org.assertj.core.api.Assertions.assertThat;
+import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
@@ -57,8 +58,13 @@ class IMAPServerConfigurationTest {
configurationBuilder.addProperty("concurrentRequests", "42");
configurationBuilder.addProperty("idleTimeIntervalUnit", "MINUTES");
configurationBuilder.addProperty("disabledCaps", "ACL | MOVE");
+ configurationBuilder.addProperty("customProperties", "abc=def");
+ configurationBuilder.addProperty("customProperties", "ghi=jkl");
ImapConfiguration imapConfiguration = IMAPServer.getImapConfiguration(configurationBuilder);
+ Properties customProperties = new Properties();
+ customProperties.put("abc", "def");
+ customProperties.put("ghi", "jkl");
ImapConfiguration expectImapConfiguration = ImapConfiguration.builder()
.enableIdle(false)
.idleTimeInterval(1)
@@ -66,6 +72,7 @@ class IMAPServerConfigurationTest {
.disabledCaps(ImmutableSet.of("ACL", "MOVE"))
.maxQueueSize(12)
.concurrentRequests(42)
+ .withCustomProperties(customProperties)
.build();
assertThat(imapConfiguration).isEqualTo(expectImapConfiguration);
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org