JAMES-1862 Add FrameHandler when building the server protocols
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b61399a6 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b61399a6 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b61399a6 Branch: refs/heads/master Commit: b61399a6c3dc6f5c717f2ce118e4c3f84c2a4677 Parents: 50cf7b4 Author: Antoine Duprat <adup...@apache.org> Authored: Wed Nov 30 14:27:15 2016 +0100 Committer: Antoine Duprat <adup...@linagora.com> Committed: Tue Dec 6 11:29:31 2016 +0100 ---------------------------------------------------------------------- .../lmtp/netty/NettyLMTPSServerTest.java | 5 +- .../lmtp/netty/NettyLMTPServerTest.java | 4 +- protocols/netty/pom.xml | 14 ++++ .../netty/AbstractChannelPipelineFactory.java | 14 ++-- .../AbstractSSLAwareChannelPipelineFactory.java | 11 +-- .../netty/BasicChannelUpstreamHandler.java | 6 +- .../james/protocols/netty/NettyServer.java | 64 +++++++++++++++--- .../james/protocols/netty/NettyServerTest.java | 71 ++++++++++++++++++++ .../pop3/netty/NettyPOP3SServerTest.java | 5 +- .../pop3/netty/NettyPOP3ServerTest.java | 4 +- .../pop3/netty/NettyStartTlsPOP3ServerTest.java | 5 +- .../smtp/netty/NettySMTPSServerTest.java | 5 +- .../smtp/netty/NettySMTPServerTest.java | 4 +- .../smtp/netty/NettyStartTlsSMTPServerTest.java | 32 +++++++-- .../james/imapserver/netty/IMAPServer.java | 8 ++- .../netty/AbstractConfigurableAsyncServer.java | 12 +++- ...ractExecutorAwareChannelPipelineFactory.java | 9 +-- .../james/lmtpserver/netty/LMTPServer.java | 9 +++ .../netty/ManageSieveServer.java | 16 +++-- .../james/pop3server/netty/POP3Server.java | 9 +++ .../james/smtpserver/netty/SMTPServer.java | 9 +++ 21 files changed, 265 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPSServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPSServerTest.java b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPSServerTest.java index f7c46de..6915fcc 100644 --- a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPSServerTest.java +++ b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPSServerTest.java @@ -13,7 +13,10 @@ public class NettyLMTPSServerTest extends AbstractLMTPSServerTest{ @Override protected ProtocolServer createServer(Protocol protocol, InetSocketAddress address) { - NettyServer server = new NettyServer(protocol, Encryption.createTls(BogusSslContextFactory.getServerContext())); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .secure(Encryption.createTls(BogusSslContextFactory.getServerContext())) + .build(); server.setListenAddresses(address); return server; } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPServerTest.java b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPServerTest.java index ae72cc1..6e1a571 100644 --- a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPServerTest.java +++ b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/netty/NettyLMTPServerTest.java @@ -29,7 +29,9 @@ public class NettyLMTPServerTest extends AbstractLMTPServerTest { @Override protected ProtocolServer createServer(Protocol protocol, InetSocketAddress address) { - NettyServer server = new NettyServer(protocol); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .build(); server.setListenAddresses(address); return server; } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/netty/pom.xml ---------------------------------------------------------------------- diff --git a/protocols/netty/pom.xml b/protocols/netty/pom.xml index 5eb8849..330904f 100644 --- a/protocols/netty/pom.xml +++ b/protocols/netty/pom.xml @@ -39,9 +39,23 @@ <artifactId>protocols-api</artifactId> </dependency> <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> <groupId>io.netty</groupId> <artifactId>netty</artifactId> </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java ---------------------------------------------------------------------- diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java index 90af526..39a5b5f 100644 --- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java +++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java @@ -20,6 +20,7 @@ package org.apache.james.protocols.netty; import static org.jboss.netty.channel.Channels.pipeline; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; @@ -45,21 +46,22 @@ public abstract class AbstractChannelPipelineFactory implements ChannelPipelineF private final ChannelGroupHandler groupHandler; private final int timeout; private final ExecutionHandler eHandler; + private final ChannelHandler frameHandler; public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup channels) { - this(timeout, maxConnections, maxConnectsPerIp, channels, null); + this(timeout, maxConnections, maxConnectsPerIp, channels, null, new DelimiterBasedFrameDecoder(MAX_LINE_LENGTH, false, Delimiters.lineDelimiter())); } - public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup channels, ExecutionHandler eHandler) { + public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup channels, ExecutionHandler eHandler, + ChannelHandler frameHandler) { this.connectionLimitHandler = new ConnectionLimitUpstreamHandler(maxConnections); this.connectionPerIpLimitHandler = new ConnectionPerIpLimitUpstreamHandler(maxConnectsPerIp); this.groupHandler = new ChannelGroupHandler(channels); this.timeout = timeout; this.eHandler = eHandler; + this.frameHandler = frameHandler; } - - /** * @see org.jboss.netty.channel.ChannelPipelineFactory#getPipeline() */ @@ -74,7 +76,7 @@ public abstract class AbstractChannelPipelineFactory implements ChannelPipelineF // Add the text line decoder which limit the max line length, don't strip the delimiter and use CRLF as delimiter - pipeline.addLast(HandlerConstants.FRAMER, new DelimiterBasedFrameDecoder(MAX_LINE_LENGTH, false, Delimiters.lineDelimiter())); + pipeline.addLast(HandlerConstants.FRAMER, frameHandler); // Add the ChunkedWriteHandler to be able to write ChunkInput pipeline.addLast(HandlerConstants.CHUNK_HANDLER, new ChunkedWriteHandler()); @@ -90,8 +92,6 @@ public abstract class AbstractChannelPipelineFactory implements ChannelPipelineF return pipeline; } - - /** * Create the core {@link ChannelUpstreamHandler} to use http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java ---------------------------------------------------------------------- diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java index 1ec33a3..e78695c 100644 --- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java +++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java @@ -21,6 +21,7 @@ package org.apache.james.protocols.netty; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.handler.execution.ExecutionHandler; @@ -37,13 +38,15 @@ public abstract class AbstractSSLAwareChannelPipelineFactory extends AbstractCha private String[] enabledCipherSuites = null; public AbstractSSLAwareChannelPipelineFactory(int timeout, - int maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler eHandler) { - super(timeout, maxConnections, maxConnectsPerIp, group, eHandler); + int maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler eHandler, + ChannelHandler frameHandler) { + super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, frameHandler); } public AbstractSSLAwareChannelPipelineFactory(int timeout, - int maxConnections, int maxConnectsPerIp, ChannelGroup group, String[] enabledCipherSuites, ExecutionHandler eHandler) { - this(timeout, maxConnections, maxConnectsPerIp, group, eHandler); + int maxConnections, int maxConnectsPerIp, ChannelGroup group, String[] enabledCipherSuites, ExecutionHandler eHandler, + ChannelHandler frameHandler) { + this(timeout, maxConnections, maxConnectsPerIp, group, eHandler, frameHandler); // We need to copy the String array becuase of possible security issues. // See https://issues.apache.org/jira/browse/PROTOCOLS-18 http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java ---------------------------------------------------------------------- diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java index c3450d6..1464b2b 100644 --- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java +++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java @@ -23,19 +23,18 @@ import java.util.List; import javax.net.ssl.SSLEngine; -import org.apache.james.protocols.api.ProtocolSessionImpl; +import org.apache.james.protocols.api.Encryption; import org.apache.james.protocols.api.Protocol; import org.apache.james.protocols.api.ProtocolSession; +import org.apache.james.protocols.api.ProtocolSessionImpl; import org.apache.james.protocols.api.ProtocolTransport; import org.apache.james.protocols.api.Response; -import org.apache.james.protocols.api.Encryption; import org.apache.james.protocols.api.future.FutureResponse; import org.apache.james.protocols.api.handler.ConnectHandler; import org.apache.james.protocols.api.handler.DisconnectHandler; import org.apache.james.protocols.api.handler.LineHandler; import org.apache.james.protocols.api.handler.ProtocolHandlerChain; import org.apache.james.protocols.api.handler.ProtocolHandlerResultHandler; -import org.apache.james.protocols.netty.NettyProtocolTransport; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandler.Sharable; @@ -139,7 +138,6 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler { if (lineHandlers.size() > 0) { ChannelBuffer buf = (ChannelBuffer) e.getMessage(); - LineHandler lHandler= (LineHandler) lineHandlers.getLast(); long start = System.currentTimeMillis(); Response response = lHandler.onLine(pSession,buf.toByteBuffer()); http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java ---------------------------------------------------------------------- diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java index 4817182..d2a9285 100644 --- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java +++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java @@ -21,42 +21,81 @@ package org.apache.james.protocols.netty; import javax.net.ssl.SSLContext; -import org.apache.james.protocols.api.Protocol; import org.apache.james.protocols.api.Encryption; +import org.apache.james.protocols.api.Protocol; import org.apache.james.protocols.api.handler.ProtocolHandler; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.group.ChannelGroup; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.handler.execution.ExecutionHandler; import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + /** * Generic NettyServer */ public class NettyServer extends AbstractAsyncServer { + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Protocol protocol; + private Optional<Encryption> secure; + private Optional<ChannelHandler> frameHandler; + + private Builder() { + secure = Optional.absent(); + frameHandler = Optional.absent(); + } + + public Builder protocol(Protocol protocol) { + Preconditions.checkNotNull(protocol, "'protocol' is mandatory"); + this.protocol = protocol; + return this; + } + + public Builder secure(Encryption secure) { + this.secure = Optional.fromNullable(secure); + return this; + } + + public Builder frameHandler(ChannelHandler frameHandler) { + this.frameHandler = Optional.fromNullable(frameHandler); + return this; + } + + public NettyServer build() { + Preconditions.checkState(protocol != null, "'protocol' is mandatory"); + return new NettyServer(protocol, + secure.orNull(), + frameHandler.or(new DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, false, Delimiters.lineDelimiter()))); + } + } + protected final Protocol protocol; + protected final Encryption secure; + private final ChannelHandler frameHandler; private ExecutionHandler eHandler; private ChannelUpstreamHandler coreHandler; - protected final Encryption secure; - private int maxCurConnections; private int maxCurConnectionsPerIP; - public NettyServer(Protocol protocol) { - this(protocol, null); - } - - - public NettyServer(Protocol protocol, Encryption secure) { - super(); + private NettyServer(Protocol protocol, Encryption secure, ChannelHandler frameHandler) { this.protocol = protocol; this.secure = secure; + this.frameHandler = frameHandler; } protected ExecutionHandler createExecutionHandler(int size) { @@ -102,11 +141,14 @@ public class NettyServer extends AbstractAsyncServer { super.bind(); } + private ChannelHandler getFrameHandler() { + return frameHandler; + } @Override protected ChannelPipelineFactory createPipelineFactory(ChannelGroup group) { - return new AbstractSSLAwareChannelPipelineFactory(getTimeout(), maxCurConnections, maxCurConnectionsPerIP, group, eHandler) { + return new AbstractSSLAwareChannelPipelineFactory(getTimeout(), maxCurConnections, maxCurConnectionsPerIP, group, eHandler, getFrameHandler()) { @Override protected ChannelUpstreamHandler createHandler() { http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java b/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java new file mode 100644 index 0000000..1d327db --- /dev/null +++ b/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java @@ -0,0 +1,71 @@ +/**************************************************************** + * 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.protocols.netty; + +import static org.mockito.Mockito.mock; + +import javax.net.ssl.SSLContext; + +import org.apache.james.protocols.api.Encryption; +import org.apache.james.protocols.api.Protocol; +import org.jboss.netty.channel.ChannelHandler; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class NettyServerTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void protocolShouldThrowWhenProtocolIsNull() { + expectedException.expect(NullPointerException.class); + NettyServer.builder() + .protocol(null); + } + + @Test + public void buildShouldThrowWhenProtocolIsNotGiven() { + expectedException.expect(IllegalStateException.class); + NettyServer.builder() + .build(); + } + + @Test + public void buildShouldWorkWhenProtocolIsGiven() { + Protocol protocol = mock(Protocol.class); + NettyServer.builder() + .protocol(protocol) + .build(); + } + + @Test + public void buildShouldWorkWhenEverythingIsGiven() throws Exception { + Protocol protocol = mock(Protocol.class); + Encryption encryption = Encryption.createStartTls(SSLContext.getDefault()); + ChannelHandler channelHandler = mock(ChannelHandler.class); + NettyServer.builder() + .protocol(protocol) + .secure(encryption) + .frameHandler(channelHandler) + .build(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3SServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3SServerTest.java b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3SServerTest.java index 4014038..c1ac359 100644 --- a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3SServerTest.java +++ b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3SServerTest.java @@ -30,7 +30,10 @@ public class NettyPOP3SServerTest extends AbstractPOP3SServerTest { @Override protected ProtocolServer createEncryptedServer(Protocol protocol, InetSocketAddress address, Encryption enc) { - NettyServer server = new NettyServer(protocol, enc); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .secure(enc) + .build(); server.setListenAddresses(address); return server; } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3ServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3ServerTest.java b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3ServerTest.java index 81e29be..8bf701d 100644 --- a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3ServerTest.java +++ b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyPOP3ServerTest.java @@ -29,7 +29,9 @@ public class NettyPOP3ServerTest extends AbstractPOP3ServerTest{ @Override protected ProtocolServer createServer(Protocol protocol, InetSocketAddress address) { - NettyServer server = new NettyServer(protocol); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .build(); server.setListenAddresses(address); return server; } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyStartTlsPOP3ServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyStartTlsPOP3ServerTest.java b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyStartTlsPOP3ServerTest.java index 20b4718..5071353 100644 --- a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyStartTlsPOP3ServerTest.java +++ b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/netty/NettyStartTlsPOP3ServerTest.java @@ -30,7 +30,10 @@ public class NettyStartTlsPOP3ServerTest extends AbstractStartTlsPOP3ServerTest{ @Override protected ProtocolServer createServer(Protocol protocol, InetSocketAddress address, Encryption enc) { - NettyServer server = new NettyServer(protocol, enc); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .secure(enc) + .build(); server.setListenAddresses(address); return server; http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPSServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPSServerTest.java b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPSServerTest.java index b6fa768..cdb3d2e 100644 --- a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPSServerTest.java +++ b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPSServerTest.java @@ -35,7 +35,10 @@ public class NettySMTPSServerTest extends AbstractSMTPSServerTest{ @Override protected ProtocolServer createEncryptedServer(Protocol protocol, InetSocketAddress address, Encryption enc) { - NettyServer server = new NettyServer(protocol, enc); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .secure(enc) + .build(); server.setListenAddresses(address); return server; } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPServerTest.java b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPServerTest.java index af691b0..d796506 100644 --- a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPServerTest.java +++ b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettySMTPServerTest.java @@ -35,7 +35,9 @@ public class NettySMTPServerTest extends AbstractSMTPServerTest{ @Override protected ProtocolServer createServer(Protocol protocol, InetSocketAddress address) { - NettyServer server = new NettyServer(protocol); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .build(); server.setListenAddresses(address); return server; } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java ---------------------------------------------------------------------- diff --git a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java index 5a8058c..e8c16af 100644 --- a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java +++ b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java @@ -42,11 +42,15 @@ import org.apache.james.protocols.api.utils.BogusSslContextFactory; import org.apache.james.protocols.api.utils.BogusTrustManagerFactory; import org.apache.james.protocols.api.utils.MockLogger; import org.apache.james.protocols.api.utils.TestUtils; +import org.apache.james.protocols.netty.AbstractChannelPipelineFactory; import org.apache.james.protocols.netty.NettyServer; import org.apache.james.protocols.smtp.SMTPConfigurationImpl; import org.apache.james.protocols.smtp.SMTPProtocol; import org.apache.james.protocols.smtp.SMTPProtocolHandlerChain; import org.apache.james.protocols.smtp.utils.TestMessageHook; +import org.assertj.core.api.AssertDelegateTarget; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; import org.junit.After; import org.junit.Test; @@ -65,7 +69,11 @@ public class NettyStartTlsSMTPServerTest { } private ProtocolServer createServer(Protocol protocol, InetSocketAddress address, Encryption enc) { - NettyServer server = new NettyServer(protocol, enc); + NettyServer server = NettyServer.builder() + .protocol(protocol) + .secure(enc) + .frameHandler(new DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, false, Delimiters.lineDelimiter())) + .build(); server.setListenAddresses(address); return server; } @@ -125,19 +133,29 @@ public class NettyStartTlsSMTPServerTest { client.connect(address.getAddress().getHostAddress(), address.getPort()); client.sendCommand("EHLO localhost"); - assertThat(isStartTLSAnnounced(client)).isTrue(); + assertThat(new StartTLSAssert(client)).isStartTLSAnnounced(); client.quit(); client.disconnect(); } - private boolean isStartTLSAnnounced(SMTPSClient client) { - for (String reply: client.getReplyStrings()) { - if (reply.toUpperCase(Locale.UK).endsWith("STARTTLS")) { - return true; + private static class StartTLSAssert implements AssertDelegateTarget { + + private final SMTPSClient client; + + public StartTLSAssert(SMTPSClient client) { + this.client = client; + + } + + public boolean isStartTLSAnnounced() { + for (String reply: client.getReplyStrings()) { + if (reply.toUpperCase(Locale.UK).endsWith("STARTTLS")) { + return true; + } } + return false; } - return false; } @Test http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java ---------------------------------------------------------------------- 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 0d592c4..371c50a 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 @@ -35,6 +35,7 @@ import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer; import org.apache.james.protocols.netty.ChannelGroupHandler; import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler; import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; @@ -139,7 +140,7 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC // Add the text line decoder which limit the max line length, // don't strip the delimiter and use CRLF as delimiter // Use a SwitchableDelimiterBasedFrameDecoder, see JAMES-1436 - pipeline.addLast(FRAMER, new SwitchableDelimiterBasedFrameDecoder(maxLineLength, false, Delimiters.lineDelimiter())); + pipeline.addLast(FRAMER, createFrameHandler()); Encryption secure = getEncryption(); if (secure != null && !secure.isStartTLS()) { @@ -192,4 +193,9 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC return null; } + @Override + protected ChannelHandler createFrameHandler() { + return new SwitchableDelimiterBasedFrameDecoder(maxLineLength, false, Delimiters.lineDelimiter()); + } + } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java index 4575172..3fbf7e5 100644 --- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java +++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java @@ -47,6 +47,7 @@ import org.apache.james.protocols.lib.jmx.ServerMBean; import org.apache.james.protocols.netty.AbstractAsyncServer; import org.apache.james.util.concurrent.JMXEnabledThreadPoolExecutor; import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.group.ChannelGroup; @@ -110,11 +111,13 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe private final ConnectionCountHandler countHandler = new ConnectionCountHandler(); private ExecutionHandler executionHandler = null; + private ChannelHandler frameHandler; private int maxExecutorThreads; private MBeanServer mbeanServer; + @Inject public final void setFileSystem(FileSystem filesystem) { this.fileSystem = filesystem; @@ -268,6 +271,7 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe buildSSLContext(); preInit(); executionHandler = createExecutionHander(); + frameHandler = createFrameHandler(); bind(); mbeanServer = ManagementFactory.getPlatformMBeanServer(); @@ -564,6 +568,8 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe return new ExecutionHandler(new JMXEnabledOrderedMemoryAwareThreadPoolExecutor(maxExecutorThreads, 0, 0, getThreadPoolJMXPath(), getDefaultJMXName() + "-executor")); } + protected abstract ChannelHandler createFrameHandler(); + /** * Return the {@link ExecutionHandler} or null if non should be used. Be sure you call {@link #createExecutionHander()} before * @@ -573,11 +579,15 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe return executionHandler; } + protected ChannelHandler getFrameHandler() { + return frameHandler; + } + protected abstract ChannelUpstreamHandler createCoreHandler(); @Override protected ChannelPipelineFactory createPipelineFactory(ChannelGroup group) { - return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), connectionLimit, connPerIP, group, enabledCipherSuites, getExecutionHandler()) { + return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), connectionLimit, connPerIP, group, enabledCipherSuites, getExecutionHandler(), getFrameHandler()) { @Override protected SSLContext getSSLContext() { if (encryption == null) { http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java index 1a88d9e..6b71a51 100644 --- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java +++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java @@ -20,6 +20,7 @@ package org.apache.james.protocols.lib.netty; import org.apache.james.protocols.netty.AbstractSSLAwareChannelPipelineFactory; import org.apache.james.protocols.netty.HandlerConstants; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.handler.execution.ExecutionHandler; @@ -31,12 +32,12 @@ import org.jboss.netty.handler.execution.ExecutionHandler; */ public abstract class AbstractExecutorAwareChannelPipelineFactory extends AbstractSSLAwareChannelPipelineFactory{ - public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler eHandler) { - super(timeout, maxConnections, maxConnectsPerIp, group, eHandler); + public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler eHandler, ChannelHandler frameHandler) { + super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, frameHandler); } - public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup group, String[] enabledCipherSuites, ExecutionHandler eHandler) { - super(timeout, maxConnections, maxConnectsPerIp, group, enabledCipherSuites, eHandler); + public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup group, String[] enabledCipherSuites, ExecutionHandler eHandler, ChannelHandler frameHandler) { + super(timeout, maxConnections, maxConnectsPerIp, group, enabledCipherSuites, eHandler, frameHandler); } @Override http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java index 860a05f..f6c4fee 100644 --- a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java +++ b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java @@ -27,9 +27,13 @@ import org.apache.james.protocols.api.logger.ProtocolLoggerAdapter; import org.apache.james.protocols.lib.handler.HandlersPackage; import org.apache.james.protocols.lib.netty.AbstractProtocolAsyncServer; import org.apache.james.protocols.lmtp.LMTPConfiguration; +import org.apache.james.protocols.netty.AbstractChannelPipelineFactory; import org.apache.james.protocols.smtp.SMTPProtocol; import org.apache.james.smtpserver.netty.SMTPChannelUpstreamHandler; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelUpstreamHandler; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; public class LMTPServer extends AbstractProtocolAsyncServer implements LMTPServerMBean { @@ -155,4 +159,9 @@ public class LMTPServer extends AbstractProtocolAsyncServer implements LMTPServe return JMXHandlersLoader.class; } + @Override + protected ChannelHandler createFrameHandler() { + return new DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, false, Delimiters.lineDelimiter()); + } + } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java index 2308714..82c8ed3 100644 --- a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java +++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java @@ -19,12 +19,17 @@ package org.apache.james.managesieveserver.netty; +import static org.jboss.netty.channel.Channels.pipeline; + +import javax.net.ssl.SSLEngine; + import org.apache.james.managesieve.transcode.ManageSieveProcessor; import org.apache.james.protocols.api.Encryption; import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer; import org.apache.james.protocols.netty.ChannelGroupHandler; import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler; import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; @@ -40,10 +45,6 @@ import org.jboss.netty.util.CharsetUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLEngine; - -import static org.jboss.netty.channel.Channels.pipeline; - public class ManageSieveServer extends AbstractConfigurableAsyncServer implements ManageSieveServerMBean { private static final Logger LOGGER = LoggerFactory.getLogger(ManageSieveServer.class); @@ -114,7 +115,7 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement // Add the text line decoder which limit the max line length, // don't strip the delimiter and use CRLF as delimiter // Use a SwitchableDelimiterBasedFrameDecoder, see JAMES-1436 - pipeline.addLast(FRAMER, new DelimiterBasedFrameDecoder(maxLineLength, false, Delimiters.lineDelimiter())); + pipeline.addLast(FRAMER, createFrameHandler()); pipeline.addLast(CONNECTION_COUNT_HANDLER, getConnectionCountHandler()); pipeline.addLast(CHUNK_WRITE_HANDLER, new ChunkedWriteHandler()); @@ -136,4 +137,9 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement public String getServiceType() { return "Manage Sieve Service"; } + + @Override + protected ChannelHandler createFrameHandler() { + return new DelimiterBasedFrameDecoder(maxLineLength, false, Delimiters.lineDelimiter()); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java index 62ae9fa..5b14d46 100644 --- a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java +++ b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java @@ -24,9 +24,13 @@ import org.apache.james.protocols.api.ProtocolConfiguration; import org.apache.james.protocols.api.logger.ProtocolLoggerAdapter; import org.apache.james.protocols.lib.handler.HandlersPackage; import org.apache.james.protocols.lib.netty.AbstractProtocolAsyncServer; +import org.apache.james.protocols.netty.AbstractChannelPipelineFactory; import org.apache.james.protocols.netty.BasicChannelUpstreamHandler; import org.apache.james.protocols.pop3.POP3Protocol; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelUpstreamHandler; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; /** * NIO POP3 Server which use Netty @@ -100,4 +104,9 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve return JMXHandlersLoader.class; } + @Override + protected ChannelHandler createFrameHandler() { + return new DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, false, Delimiters.lineDelimiter()); + } + } http://git-wip-us.apache.org/repos/asf/james-project/blob/b61399a6/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java index bacc31a..c7d291c 100644 --- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java +++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java @@ -29,12 +29,16 @@ import org.apache.james.protocols.api.ProtocolTransport; import org.apache.james.protocols.api.logger.ProtocolLoggerAdapter; import org.apache.james.protocols.lib.handler.HandlersPackage; import org.apache.james.protocols.lib.netty.AbstractProtocolAsyncServer; +import org.apache.james.protocols.netty.AbstractChannelPipelineFactory; import org.apache.james.protocols.smtp.SMTPConfiguration; import org.apache.james.protocols.smtp.SMTPProtocol; import org.apache.james.smtpserver.CoreCmdHandlerLoader; import org.apache.james.smtpserver.ExtendedSMTPSession; import org.apache.james.smtpserver.jmx.JMXHandlersLoader; +import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelUpstreamHandler; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; /** * NIO SMTPServer which use Netty @@ -359,4 +363,9 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe return JMXHandlersLoader.class; } + @Override + protected ChannelHandler createFrameHandler() { + return new DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, false, Delimiters.lineDelimiter()); + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org