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 2022/03/22 02:01:31 UTC

[james-project] branch master updated (b1beff3 -> acb10d3)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.


    from b1beff3  [PERF] Naming threads: Spooler threads should be named
     new f1ed753  JAMES-3715 Upgrade to netty 4
     new 7fd6eb0  JAMES-3715 Carry over `ioWorkerCount` configuration parameter
     new 130c548  JAMES-3715 Remove no longer use methods
     new fee18d4  JAMES-3639 AbstractConfigurableAsyncServer: Remove no longer used x509Algorithm
     new 95d33ed  JAMES-3715 Remove no longer needed JMXEnabledThreadPoolExecutor
     new 92dcc05  JAMES-3715 Execute core handlers outside of the event loop
     new 43205f9  JAMES-3715 Fix SMTP pipelining
     new c8d2e98  JAMES-3715 IMAP incorporate line overrides to the frame decoder
     new 67f3e11  JAMES-3715 IMAP: Avoid a deadlock upon STARTTLS
     new acb5a92  JAMES-3715 IMAP: Avoid a deadlock upon COMPRESS
     new 06eb2ee  JAMES-3715 Restore changes to logback-test.xml
     new 3222c5d  JAMES-3715 IMAP fix framer issues (IndexOutOfBound on bytebuf when turned on/off)
     new ff9ecad  JAMES-3715 IMAP: IdleStateHandler is not needed
     new 2dffa13  JAMES-3715 IMAP: Improve threading model
     new c62f06b  JAMES-3715 IMAP: We no longer have EXECUTION_HANDLER in Netty 4
     new 69aa316  JAMES-3715 Avoid creating a CONTINUATION REQUEST on each IMAP request
     new 98af5c6  JAMES-3715 ImapRequestFrameDecoder avoid calling ChannelPipeline::get on each request
     new 5618e72  JAMES-3715 Avoid stateful static fields
     new 98fc221  JAMES-3715 Writing on the first context bypasses the SSL encoder
     new 5926ca2  JAMES-3715 Name netty threads
     new 5e685fa  JAMES-3715 Cap boss threads to 2
     new 999d2c4  JAMES-3715 Fix IDLE when COMPRESS is enabled
     new 354fb76  JAMES-3715 Add missing license
     new 59c824b  JAMES-3715 TCP_NODELAY as a child option
     new 27ab3a4  JAMES-3715 ChannelGroups: rely on immediate executor
     new b2d9f9e  JAMES-3715 Close opened channels
     new 2768b2e  JAMES-3715 Get rid of no longer needed ChannelGroupHandler
     new 1a5c3a7  JAMES-3715 Rename: UpstreamHandler -> InboundHandler
     new acb10d3  JAMES-3715 netty-all dependency in protocols-imap4 is no longer needed for testing

The 29 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 pom.xml                                            |   9 +-
 .../james/protocols/api/ProtocolSession.java       |   6 -
 .../james/protocols/api/ProtocolSessionImpl.java   |   5 -
 .../james/protocols/api/ProtocolTransport.java     |   5 -
 .../api/AbstractProtocolTransportTest.java         |   5 -
 .../apache/james/imap/api/process/ImapSession.java |   5 +-
 .../apache/james/imap/encode/FakeImapSession.java  |   5 +-
 .../james/imap/processor/CompressProcessor.java    |   6 +-
 .../james/imap/processor/StartTLSProcessor.java    |   6 +-
 .../processor/fetch/PartialFetchBodyElement.java   |   5 +-
 .../protocols/lmtp/netty/NettyLMTPSServerTest.java |  17 +-
 .../protocols/lmtp/netty/NettyLMTPServerTest.java  |  14 +-
 protocols/netty/pom.xml                            |   3 +-
 .../james/protocols/netty/AbstractAsyncServer.java | 110 +++--
 .../netty/AbstractChannelPipelineFactory.java      |  62 ++-
 .../AbstractSSLAwareChannelPipelineFactory.java    |  36 +-
 .../AllButStartTlsLineBasedChannelHandler.java     |  27 +-
 .../AllButStartTlsLineChannelHandlerFactory.java   |   4 +-
 ...andler.java => BasicChannelInboundHandler.java} | 504 +++++++++++----------
 .../james/protocols/netty/ChannelGroupHandler.java |  49 --
 .../protocols/netty/ChannelHandlerFactory.java     |   4 +-
 .../netty/ConnectionLimitUpstreamHandler.java      |  24 +-
 .../netty/ConnectionPerIpLimitUpstreamHandler.java |  28 +-
 .../james/protocols/netty/HandlerConstants.java    |   6 +-
 .../LineDelimiterBasedChannelHandlerFactory.java   |   6 +-
 ...elHandlerFactory.java => LineHandlerAware.java} |   9 +-
 .../netty/LineHandlerUpstreamHandler.java          |  23 +-
 .../protocols/netty/NettyProtocolTransport.java    |  65 ++-
 .../apache/james/protocols/netty/NettyServer.java  |  57 ++-
 .../protocols/netty/ProtocolMDCContextFactory.java |   8 +-
 .../james/protocols/netty/TimeoutHandler.java      |  21 +-
 .../james/protocols/netty/NettyServerTest.java     |  21 +-
 .../pop3/core/CRLFTerminatedInputStream.java       |  17 +-
 .../protocols/pop3/AbstractPOP3ServerTest.java     |   2 +-
 .../protocols/pop3/netty/NettyPOP3SServerTest.java |  15 +-
 .../protocols/pop3/netty/NettyPOP3ServerTest.java  |  18 +-
 .../pop3/netty/NettyStartTlsPOP3ServerTest.java    |  18 +-
 protocols/smtp/pom.xml                             |   2 +-
 .../protocols/smtp/core/SMTPMDCContextFactory.java |   3 +-
 .../protocols/smtp/netty/NettySMTPSServerTest.java |  17 +-
 .../protocols/smtp/netty/NettySMTPServerTest.java  |  16 +-
 .../smtp/netty/NettyStartTlsSMTPServerTest.java    |  11 +-
 .../protocols/smtp/utils/BaseFakeSMTPSession.java  |   5 -
 server/blob/blob-s3/pom.xml                        |   1 -
 .../modules/protocols/ProtocolHandlerModule.java   |   1 -
 .../james/modules/protocols/IMAPServerModule.java  |   2 -
 .../james/modules/protocols/LMTPServerModule.java  |   2 -
 .../james/modules/protocols/NettyServerModule.java |  45 --
 .../james/modules/protocols/POP3ServerModule.java  |   2 -
 .../james/modules/protocols/SMTPServerModule.java  |   2 -
 .../META-INF/org/apache/james/spring-server.xml    |   2 -
 .../concurrent/JMXEnabledThreadPoolExecutor.java   | 174 -------
 .../james/mock/smtp/server/MockSMTPServerTest.java |   2 +-
 ...eJmapRFC8621AuthenticationStrategyContract.java |   2 +-
 server/protocols/protocols-imap4/pom.xml           |  12 +-
 .../netty/AbstractNettyImapRequestLineReader.java  |  15 +-
 .../netty/ChannelImapResponseWriter.java           |  34 +-
 .../james/imapserver/netty/IMAPMDCContext.java     |   7 +-
 .../apache/james/imapserver/netty/IMAPServer.java  |  56 +--
 .../james/imapserver/netty/IMAPServerFactory.java  |   6 +-
 .../netty/ImapChannelUpstreamHandler.java          | 112 +++--
 .../imapserver/netty/ImapHeartbeatHandler.java     |  29 +-
 .../imapserver/netty/ImapIdleStateHandler.java     |  31 +-
 .../imapserver/netty/ImapLineHandlerAdapter.java   |  29 +-
 .../imapserver/netty/ImapRequestFrameDecoder.java  | 155 ++++---
 .../james/imapserver/netty/NettyConstants.java     |  14 +-
 .../netty/NettyImapRequestLineReader.java          |  27 +-
 .../james/imapserver/netty/NettyImapSession.java   | 103 +++--
 .../netty/NettyStreamImapRequestLineReader.java    |   3 +-
 .../james/imapserver/netty/OioIMAPServer.java      |  51 ---
 .../imapserver/netty/OioIMAPServerFactory.java     |  43 --
 .../netty/SwitchableLineBasedFrameDecoder.java     |  38 +-
 .../SwitchableLineBasedFrameDecoderFactory.java    |   5 +-
 .../netty/ImapRequestFrameDecoderTest.java         |  80 ----
 server/protocols/protocols-library/pom.xml         |   2 +-
 .../lib/netty/AbstractConfigurableAsyncServer.java |  92 +---
 ...bstractExecutorAwareChannelPipelineFactory.java |  24 +-
 .../lib/netty/ConnectionCountHandler.java          |  17 +-
 ...nabledOrderedMemoryAwareThreadPoolExecutor.java | 141 ------
 .../lib/AbstractConfigurableAsyncServerTest.java   |   4 +-
 server/protocols/protocols-lmtp/pom.xml            |   2 +-
 .../apache/james/lmtpserver/netty/LMTPServer.java  |   9 +-
 .../james/lmtpserver/netty/LMTPServerFactory.java  |   7 +-
 .../james/lmtpserver/netty/OioLMTPServer.java      |  50 --
 .../lmtpserver/netty/OioLMTPServerFactory.java     |  41 --
 .../apache/james/lmtpserver/LmtpServerTest.java    |   3 +-
 server/protocols/protocols-managesieve/pom.xml     |   2 +-
 .../netty/ChannelManageSieveResponseWriter.java    |   9 +-
 .../netty/ManageSieveChannelUpstreamHandler.java   |  91 ++--
 .../netty/ManageSieveMDCContext.java               |  14 +-
 .../managesieveserver/netty/ManageSieveServer.java |  57 +--
 .../netty/ManageSieveServerFactory.java            |   8 -
 .../managesieveserver/netty/NettyConstants.java}   |  15 +-
 server/protocols/protocols-pop3/pom.xml            |   2 +-
 .../james/pop3server/netty/OioPOP3Server.java      |  44 --
 .../pop3server/netty/OioPOP3ServerFactory.java     |  29 --
 .../apache/james/pop3server/netty/POP3Server.java  |  16 +-
 .../james/pop3server/netty/POP3ServerFactory.java  |   8 -
 .../apache/james/pop3server/OioPOP3ServerTest.java |  31 --
 .../apache/james/pop3server/POP3ServerTest.java    |   5 -
 server/protocols/protocols-smtp/pom.xml            |   2 +-
 .../org/apache/james/smtpserver/SMTPConstants.java |   5 +
 .../james/smtpserver/netty/OioSMTPServer.java      |  47 --
 .../smtpserver/netty/OioSMTPServerFactory.java     |  43 --
 ...Handler.java => SMTPChannelInboundHandler.java} | 169 ++++---
 .../apache/james/smtpserver/netty/SMTPServer.java  |  15 +-
 .../james/smtpserver/netty/SMTPServerFactory.java  |   6 +-
 .../apache/james/smtpserver/AuthAnnounceTest.java  |   5 -
 .../java/org/apache/james/smtpserver/DSNTest.java  |   5 -
 .../apache/james/smtpserver/OioSMTPServerTest.java |  31 --
 .../org/apache/james/smtpserver/SMTPSaslTest.java  |   5 -
 .../apache/james/smtpserver/SMTPServerTest.java    |   5 -
 112 files changed, 1153 insertions(+), 2272 deletions(-)
 rename protocols/netty/src/main/java/org/apache/james/protocols/netty/{BasicChannelUpstreamHandler.java => BasicChannelInboundHandler.java} (67%)
 delete mode 100644 protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java
 copy protocols/netty/src/main/java/org/apache/james/protocols/netty/{ChannelHandlerFactory.java => LineHandlerAware.java} (86%)
 delete mode 100644 server/container/guice/protocols/netty/src/main/java/org/apache/james/modules/protocols/NettyServerModule.java
 delete mode 100644 server/container/util/src/main/java/org/apache/james/util/concurrent/JMXEnabledThreadPoolExecutor.java
 delete mode 100644 server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServer.java
 delete mode 100644 server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServerFactory.java
 delete mode 100644 server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoderTest.java
 delete mode 100644 server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/JMXEnabledOrderedMemoryAwareThreadPoolExecutor.java
 delete mode 100644 server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServer.java
 delete mode 100644 server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServerFactory.java
 copy server/{data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/impl/InMemoryEventSourcingFilteringManagementTest.java => protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/NettyConstants.java} (75%)
 delete mode 100644 server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3Server.java
 delete mode 100644 server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3ServerFactory.java
 delete mode 100644 server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/OioPOP3ServerTest.java
 delete mode 100644 server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServer.java
 delete mode 100644 server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServerFactory.java
 rename server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/{SMTPChannelUpstreamHandler.java => SMTPChannelInboundHandler.java} (67%)
 delete mode 100644 server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/OioSMTPServerTest.java

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


[james-project] 24/29: JAMES-3715 TCP_NODELAY as a child option

Posted by bt...@apache.org.
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 59c824bb36e3df5add43f9a1b4496b401131a93a
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 21 10:18:10 2022 +0700

    JAMES-3715 TCP_NODELAY as a child option
    
    Like this was the case for Netty3 implementation. This can explain the small
    higher latencies we observed in the performance tests.
---
 .../main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index 22e1471..cd95677 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -120,7 +120,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
         // Bind and start to accept incoming connections.
         bootstrap.option(ChannelOption.SO_BACKLOG, backlog);
         bootstrap.option(ChannelOption.SO_REUSEADDR, true);
-        bootstrap.option(ChannelOption.TCP_NODELAY, true);
+        bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
     }
     
     @Override

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


[james-project] 27/29: JAMES-3715 Get rid of no longer needed ChannelGroupHandler

Posted by bt...@apache.org.
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 2768b2e27dc879c8a126c51969f1847cc6c71503
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 21 10:41:18 2022 +0700

    JAMES-3715 Get rid of no longer needed ChannelGroupHandler
---
 .../james/protocols/netty/AbstractAsyncServer.java |  4 +--
 .../netty/AbstractChannelPipelineFactory.java      | 11 ++----
 .../AbstractSSLAwareChannelPipelineFactory.java    |  9 +++--
 .../james/protocols/netty/ChannelGroupHandler.java | 40 ----------------------
 .../apache/james/protocols/netty/NettyServer.java  |  4 +--
 .../apache/james/imapserver/netty/IMAPServer.java  | 10 ++----
 .../james/imapserver/netty/NettyConstants.java     |  1 -
 .../lib/netty/AbstractConfigurableAsyncServer.java |  5 ++-
 ...bstractExecutorAwareChannelPipelineFactory.java |  5 ++-
 .../managesieveserver/netty/ManageSieveServer.java | 11 ++----
 10 files changed, 19 insertions(+), 81 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index 1e6bdb2..78e05e2 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -97,7 +97,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
 
         bootstrap.group(bossGroup, workerGroup);
 
-        ChannelInitializer<SocketChannel> factory = createPipelineFactory(channels);
+        ChannelInitializer<SocketChannel> factory = createPipelineFactory();
 
         // Configure the pipeline factory.
         bootstrap.childHandler(factory);
@@ -153,7 +153,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     /**
      * Create ChannelPipelineFactory to use by this Server implementation
      */
-    protected abstract ChannelInitializer<SocketChannel> createPipelineFactory(ChannelGroup group);
+    protected abstract ChannelInitializer<SocketChannel> createPipelineFactory();
 
     /**
      * Set the read/write timeout for the server. This will throw a {@link IllegalStateException} if the
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 db4a1bd..601f91a 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
@@ -22,7 +22,6 @@ import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
-import io.netty.channel.group.ChannelGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.handler.stream.ChunkedWriteHandler;
 import io.netty.util.concurrent.EventExecutorGroup;
@@ -36,21 +35,18 @@ public abstract class AbstractChannelPipelineFactory<C extends SocketChannel> ex
 
     protected final ConnectionLimitUpstreamHandler connectionLimitHandler;
     protected final ConnectionPerIpLimitUpstreamHandler connectionPerIpLimitHandler;
-    private final ChannelGroupHandler groupHandler;
     private final int timeout;
     private final ChannelHandlerFactory frameHandlerFactory;
     private final EventExecutorGroup eventExecutorGroup;
 
-    public AbstractChannelPipelineFactory(ChannelGroup channels,
-                                          ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
-        this(0, 0, 0, channels, frameHandlerFactory, eventExecutorGroup);
+    public AbstractChannelPipelineFactory(ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
+        this(0, 0, 0, frameHandlerFactory, eventExecutorGroup);
     }
 
-    public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup channels,
+    public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp,
                                           ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
         this.connectionLimitHandler = new ConnectionLimitUpstreamHandler(maxConnections);
         this.connectionPerIpLimitHandler = new ConnectionPerIpLimitUpstreamHandler(maxConnectsPerIp);
-        this.groupHandler = new ChannelGroupHandler(channels);
         this.timeout = timeout;
         this.frameHandlerFactory = frameHandlerFactory;
         this.eventExecutorGroup = eventExecutorGroup;
@@ -61,7 +57,6 @@ public abstract class AbstractChannelPipelineFactory<C extends SocketChannel> ex
     protected void initChannel(C channel) throws Exception {
         // Create a default pipeline implementation.
         ChannelPipeline pipeline = channel.pipeline();
-        pipeline.addLast(HandlerConstants.GROUP_HANDLER, groupHandler);
 
         pipeline.addLast(HandlerConstants.CONNECTION_LIMIT_HANDLER, connectionLimitHandler);
 
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 f3399c9..2203efd 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
@@ -24,7 +24,6 @@ import org.apache.james.protocols.api.Encryption;
 
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelPipeline;
-import io.netty.channel.group.ChannelGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.util.concurrent.EventExecutorGroup;
@@ -39,16 +38,16 @@ public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketCha
     private Encryption secure;
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
-                                                  int maxConnections, int maxConnectsPerIp, ChannelGroup group,
+                                                  int maxConnections, int maxConnectsPerIp,
                                                   ChannelHandlerFactory frameHandlerFactory,
                                                   EventExecutorGroup eventExecutorGroup) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory, eventExecutorGroup);
+        super(timeout, maxConnections, maxConnectsPerIp, frameHandlerFactory, eventExecutorGroup);
     }
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
-            int maxConnections, int maxConnectsPerIp, ChannelGroup group, Encryption secure,
+            int maxConnections, int maxConnectsPerIp, Encryption secure,
             ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
-        this(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory, eventExecutorGroup);
+        this(timeout, maxConnections, maxConnectsPerIp, frameHandlerFactory, eventExecutorGroup);
 
         this.secure = secure;
     }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java
deleted file mode 100644
index 152f888..0000000
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java
+++ /dev/null
@@ -1,40 +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.protocols.netty;
-
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.group.ChannelGroup;
-
-/**
- * Add channels to the channel group after the channel was opened.
- * 
- * This handler is thread-safe and thus can be shared across pipelines
- */
-@ChannelHandler.Sharable
-public final class ChannelGroupHandler extends ChannelInboundHandlerAdapter {
-    private final ChannelGroup channels;
-    
-    public ChannelGroupHandler(ChannelGroup channels) {
-        this.channels = channels;
-    }
-   
-
-}
\ No newline at end of file
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 82e0e4f..951cdda 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
@@ -29,7 +29,6 @@ import com.google.common.base.Preconditions;
 
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.DefaultEventLoopGroup;
-import io.netty.channel.group.ChannelGroup;
 
 
 /**
@@ -111,13 +110,12 @@ public class NettyServer extends AbstractAsyncServer {
     }
 
     @Override
-    protected AbstractChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory() {
 
         return new AbstractSSLAwareChannelPipelineFactory(
             getTimeout(),
             maxCurConnections,
             maxCurConnectionsPerIP,
-            group,
             secure,
             getFrameHandlerFactory(),
             new DefaultEventLoopGroup(16)) {
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 f689024..f39c826 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
@@ -36,7 +36,6 @@ import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
-import org.apache.james.protocols.netty.ChannelGroupHandler;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
 import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
@@ -51,7 +50,6 @@ import com.google.common.collect.ImmutableSet;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelPipeline;
-import io.netty.channel.group.ChannelGroup;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.handler.stream.ChunkedWriteHandler;
 
@@ -206,22 +204,20 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
         return "IMAP Service";
     }
 
+
     @Override
-    protected AbstractChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory() {
         
-        return new AbstractChannelPipelineFactory(group, getFrameHandlerFactory(), getExecutorGroup()) {
+        return new AbstractChannelPipelineFactory(getFrameHandlerFactory(), getExecutorGroup()) {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
                 return createCoreHandler();
             }
 
-            private final ChannelGroupHandler groupHandler = new ChannelGroupHandler(group);
-
             @Override
             public void initChannel(Channel channel) throws Exception {
                 ChannelPipeline pipeline = channel.pipeline();
-                pipeline.addLast(GROUP_HANDLER, groupHandler);
                 pipeline.addLast(TIMEOUT_HANDLER, new ImapIdleStateHandler(timeout));
                 pipeline.addLast(CONNECTION_LIMIT_HANDLER, new ConnectionLimitUpstreamHandler(IMAPServer.this.connectionLimit));
 
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
index 68bbd6d..afe1c26 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
@@ -36,7 +36,6 @@ public interface NettyConstants {
     String FRAMER = "framer";
     String TIMEOUT_HANDLER = "timeoutHandler";
     String CORE_HANDLER = "coreHandler";
-    String GROUP_HANDLER = "groupHandler";
     String CONNECTION_LIMIT_HANDLER = "connectionLimitHandler";
     String CONNECTION_LIMIT_PER_IP_HANDLER = "connectionPerIpLimitHandler";
     String CONNECTION_COUNT_HANDLER = "connectionCountHandler";
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 ec8a20a..1d4bc96 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
@@ -55,7 +55,6 @@ import org.slf4j.LoggerFactory;
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelOption;
-import io.netty.channel.group.ChannelGroup;
 import io.netty.util.concurrent.DefaultEventExecutorGroup;
 import io.netty.util.concurrent.EventExecutorGroup;
 import nl.altindag.ssl.SSLFactory;
@@ -555,8 +554,8 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
     protected abstract ChannelInboundHandlerAdapter createCoreHandler();
     
     @Override
-    protected AbstractChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
-        return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), connectionLimit, connPerIP, group,
+    protected AbstractChannelPipelineFactory createPipelineFactory() {
+        return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), connectionLimit, connPerIP,
             getEncryption(), getFrameHandlerFactory(), getExecutorGroup()) {
 
             @Override
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 4890f3c..07e55ea 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
@@ -23,7 +23,6 @@ import org.apache.james.protocols.netty.AbstractSSLAwareChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 
 import io.netty.channel.ChannelHandler;
-import io.netty.channel.group.ChannelGroup;
 import io.netty.util.concurrent.EventExecutorGroup;
 
 /**
@@ -35,9 +34,9 @@ import io.netty.util.concurrent.EventExecutorGroup;
 public abstract class AbstractExecutorAwareChannelPipelineFactory extends AbstractSSLAwareChannelPipelineFactory {
 
     public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp,
-                                                       ChannelGroup group, Encryption encryption,
+                                                       Encryption encryption,
                                                        ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, encryption, frameHandlerFactory, eventExecutorGroup);
+        super(timeout, maxConnections, maxConnectsPerIp, encryption, frameHandlerFactory, eventExecutorGroup);
     }
     
     /**
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 294ddc7..75d6b32 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
@@ -27,7 +27,6 @@ import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.AllButStartTlsLineChannelHandlerFactory;
-import org.apache.james.protocols.netty.ChannelGroupHandler;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
 import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
@@ -37,7 +36,6 @@ import org.slf4j.LoggerFactory;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelPipeline;
-import io.netty.channel.group.ChannelGroup;
 import io.netty.handler.codec.string.StringDecoder;
 import io.netty.handler.codec.string.StringEncoder;
 import io.netty.handler.ssl.SslHandler;
@@ -51,12 +49,10 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement
     static final String SSL_HANDLER = "sslHandler";
     static final String FRAMER = "framer";
     static final String CORE_HANDLER = "coreHandler";
-    static final String GROUP_HANDLER = "groupHandler";
     static final String CONNECTION_LIMIT_HANDLER = "connectionLimitHandler";
     static final String CONNECTION_LIMIT_PER_IP_HANDLER = "connectionPerIpLimitHandler";
     static final String CONNECTION_COUNT_HANDLER = "connectionCountHandler";
     static final String CHUNK_WRITE_HANDLER = "chunkWriteHandler";
-    static final String EXECUTION_HANDLER = "executionHandler";
 
     private final int maxLineLength;
     private final ManageSieveProcessor manageSieveProcessor;
@@ -84,17 +80,15 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement
     }
 
     @Override
-    protected AbstractChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory() {
 
-        return new AbstractChannelPipelineFactory(group, createFrameHandlerFactory(), getExecutorGroup()) {
+        return new AbstractChannelPipelineFactory(createFrameHandlerFactory(), getExecutorGroup()) {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
                 return createCoreHandler();
             }
 
-            private final ChannelGroupHandler groupHandler = new ChannelGroupHandler(group);
-
             @Override
             public void initChannel(Channel channel) throws Exception {
                 ChannelPipeline pipeline = channel.pipeline();
@@ -107,7 +101,6 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement
                     pipeline.addFirst(SSL_HANDLER, new SslHandler(engine));
 
                 }
-                pipeline.addLast(GROUP_HANDLER, groupHandler);
                 pipeline.addLast(CONNECTION_LIMIT_HANDLER, new ConnectionLimitUpstreamHandler(ManageSieveServer.this.connectionLimit));
                 pipeline.addLast(CONNECTION_LIMIT_PER_IP_HANDLER, new ConnectionPerIpLimitUpstreamHandler(ManageSieveServer.this.connPerIP));
                 // Add the text line decoder which limit the max line length,

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


[james-project] 09/29: JAMES-3715 IMAP: Avoid a deadlock upon STARTTLS

Posted by bt...@apache.org.
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 67f3e11af82f9e13b0fbcdbc41771789ec572742
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 7 15:36:28 2022 +0700

    JAMES-3715 IMAP: Avoid a deadlock upon STARTTLS
    
    The initial STARTTLS OK response was never sent because it was sent out of
    the event loop.
    
    We explicitly write it from the event loop so that the client is guarantied to receive it.
    
    We wrap the answer inside the "disabled-auto-read" to guaranty that a
    "too quick client" do not end up with a race condition...
---
 .../apache/james/imap/api/process/ImapSession.java |  3 +-
 .../apache/james/imap/encode/FakeImapSession.java  |  3 +-
 .../james/imap/processor/StartTLSProcessor.java    |  6 ++--
 .../james/imapserver/netty/NettyImapSession.java   | 39 +++++++++++++++++++++-
 4 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
index 6c3ac4a..4444ed4 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
@@ -25,6 +25,7 @@ import java.util.Optional;
 import org.apache.commons.text.RandomStringGenerator;
 import org.apache.james.core.Username;
 import org.apache.james.imap.api.ImapSessionState;
+import org.apache.james.imap.message.response.ImmutableStatusResponse;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.protocols.api.CommandDetectionSession;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
@@ -156,7 +157,7 @@ public interface ImapSession extends CommandDetectionSession {
      * 
      * @return true if the encryption of the session was successfully
      */
-    boolean startTLS();
+    boolean startTLS(ImmutableStatusResponse startTlsResponse);
 
     /**
      * Return true if the session is bound to a TLS encrypted socket.
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
index 153f615..cb1de55 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
@@ -26,6 +26,7 @@ import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.process.ImapLineHandler;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
+import org.apache.james.imap.message.response.ImmutableStatusResponse;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
 
 public class FakeImapSession implements ImapSession {
@@ -118,7 +119,7 @@ public class FakeImapSession implements ImapSession {
     }
     
     @Override
-    public boolean startTLS() {
+    public boolean startTLS(ImmutableStatusResponse response) {
         return false;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
index 028ac98..e5d63de 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
@@ -29,6 +29,7 @@ import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.message.request.StartTLSRequest;
+import org.apache.james.imap.message.response.ImmutableStatusResponse;
 import org.apache.james.imap.processor.base.AbstractChainedProcessor;
 import org.apache.james.util.MDCBuilder;
 
@@ -49,13 +50,10 @@ public class StartTLSProcessor extends AbstractChainedProcessor<StartTLSRequest>
     @Override
     protected void doProcess(StartTLSRequest request, Responder responder, ImapSession session) {
         if (session.supportStartTLS()) {
-            responder.respond(factory.taggedOk(request.getTag(), request.getCommand(), HumanReadableText.STARTTLS));
-            session.startTLS();
-
+            session.startTLS((ImmutableStatusResponse) factory.taggedOk(request.getTag(), request.getCommand(), HumanReadableText.STARTTLS));
         } else {
             responder.respond(factory.taggedBad(request.getTag(), request.getCommand(), HumanReadableText.UNKNOWN_COMMAND));
         }
-
     }
 
     @Override
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index 11223ef..2e6c109 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -18,18 +18,27 @@
  ****************************************************************/
 package org.apache.james.imapserver.netty;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 
+import org.apache.commons.lang3.NotImplementedException;
 import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.process.ImapLineHandler;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
+import org.apache.james.imap.encode.ImapResponseWriter;
+import org.apache.james.imap.encode.StatusResponseEncoder;
+import org.apache.james.imap.encode.base.ImapResponseComposerImpl;
+import org.apache.james.imap.encode.main.DefaultLocalizer;
+import org.apache.james.imap.message.Literal;
+import org.apache.james.imap.message.response.ImmutableStatusResponse;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.netty.LineHandlerAware;
 
+import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 import io.netty.handler.codec.compression.JZlibDecoder;
 import io.netty.handler.codec.compression.JZlibEncoder;
@@ -141,13 +150,20 @@ public class NettyImapSession implements ImapSession, NettyConstants {
     }
 
     @Override
-    public boolean startTLS() {
+    public boolean startTLS(ImmutableStatusResponse statusResponse) {
         if (!supportStartTLS()) {
             return false;
         }
         channel.config().setAutoRead(false);
+        try {
+            new StatusResponseEncoder(new DefaultLocalizer()).encode(statusResponse,
+                new ImapResponseComposerImpl(new EventLoopImapResponseWriter(channel), 2048));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
 
         SslHandler filter = new SslHandler(secure.createSSLEngine(), false);
+
         filter.engine().setUseClientMode(false);
         channel.pipeline().addFirst(SSL_HANDLER, filter);
 
@@ -156,6 +172,27 @@ public class NettyImapSession implements ImapSession, NettyConstants {
         return true;
     }
 
+    public static class EventLoopImapResponseWriter implements ImapResponseWriter {
+        private final Channel channel;
+
+        public EventLoopImapResponseWriter(Channel channel) {
+            this.channel = channel;
+        }
+
+        @Override
+        public void write(byte[] buffer) {
+            if (channel.isActive()) {
+                channel.pipeline().firstContext().writeAndFlush(Unpooled.wrappedBuffer(buffer));
+            }
+        }
+
+        @Override
+        public void write(Literal literal) {
+            throw new NotImplementedException();
+        }
+    }
+
+
     @Override
     public boolean supportStartTLS() {
         return secure != null && secure.getContext() != null;

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


[james-project] 04/29: JAMES-3639 AbstractConfigurableAsyncServer: Remove no longer used x509Algorithm

Posted by bt...@apache.org.
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 fee18d4c1e2b92f39b79fb0356074342e0631829
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Feb 27 20:34:11 2022 +0700

    JAMES-3639 AbstractConfigurableAsyncServer: Remove no longer used x509Algorithm
---
 .../org/apache/james/protocols/netty/AbstractAsyncServer.java    | 3 +--
 .../protocols/lib/netty/AbstractConfigurableAsyncServer.java     | 9 ---------
 2 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index 52371d8..e723546 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -50,7 +50,6 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     
     private volatile int timeout = 120;
 
-    private ServerBootstrap bootstrap;
     private EventLoopGroup bossGroup;
     private EventLoopGroup workerGroup;
 
@@ -89,7 +88,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
             throw new RuntimeException("Please specify at least on socketaddress to which the server should get bound!");
         }
 
-        bootstrap = new ServerBootstrap();
+        ServerBootstrap bootstrap = new ServerBootstrap();
         bootstrap.channel(NioServerSocketChannel.class);
 
         bossGroup = new NioEventLoopGroup();
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 c85cf5d..1ccbd84 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
@@ -81,14 +81,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
     public static final String HELLO_NAME = "helloName";
 
     public static final int DEFAULT_MAX_EXECUTOR_COUNT = 16;
-    
-    // By default, use the Sun X509 algorithm that comes with the Sun JCE
-    // provider for SSL
-    // certificates
-    private static final String defaultX509algorithm = "SunX509";
-
-    // The X.509 certificate algorithm
-    private String x509Algorithm = defaultX509algorithm;
 
     private FileSystem fileSystem;
 
@@ -263,7 +255,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
                 throw new ConfigurationException("keystore or (privateKey and certificates) needs to get configured");
             }
             secret = config.getString("tls.secret", null);
-            x509Algorithm = config.getString("tls.algorithm", defaultX509algorithm);
 
             truststore = config.getString("tls.clientAuth.truststore", null);
             truststoreType = config.getString("tls.clientAuth.truststoreType", "JKS");

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


[james-project] 20/29: JAMES-3715 Name netty threads

Posted by bt...@apache.org.
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 5926ca203cb0bd5b6ccf3cfbce6a7e7a1f8bd243
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 17 14:03:37 2022 +0700

    JAMES-3715 Name netty threads
    
    This helps reviewing thread usage when relying on jstack utility.
---
 .../java/org/apache/james/protocols/netty/AbstractAsyncServer.java  | 6 ++++--
 .../james/protocols/lib/netty/AbstractConfigurableAsyncServer.java  | 1 -
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index e723546..a2f8e93 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.james.protocols.api.ProtocolServer;
+import org.apache.james.util.concurrent.NamedThreadFactory;
 
 import com.google.common.collect.ImmutableList;
 
@@ -60,6 +61,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     private volatile int ioWorker = DEFAULT_IO_WORKER_COUNT;
     
     private List<InetSocketAddress> addresses = new ArrayList<>();
+    protected String jmxName;
     
     public synchronized void setListenAddresses(InetSocketAddress... addresses) {
         if (started) {
@@ -91,8 +93,8 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
         ServerBootstrap bootstrap = new ServerBootstrap();
         bootstrap.channel(NioServerSocketChannel.class);
 
-        bossGroup = new NioEventLoopGroup();
-        workerGroup = new NioEventLoopGroup(ioWorker);
+        bossGroup = new NioEventLoopGroup(NamedThreadFactory.withName(jmxName + "-boss"));
+        workerGroup = new NioEventLoopGroup(ioWorker, NamedThreadFactory.withName(jmxName + "-io"));
 
         bootstrap.group(bossGroup, workerGroup);
 
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 1da9ce6..ec8a20a 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
@@ -113,7 +113,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
 
     protected Encryption encryption;
 
-    protected String jmxName;
 
     private String[] enabledCipherSuites;
 

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


[james-project] 26/29: JAMES-3715 Close opened channels

Posted by bt...@apache.org.
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 b2d9f9e142d6c8be12ad656d94facffe5917c77f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 21 10:33:12 2022 +0700

    JAMES-3715 Close opened channels
    
    See https://github.com/apache/james-project/pull/898 for graceful shutdown
---
 .../apache/james/protocols/netty/AbstractAsyncServer.java   | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index eefeff6..1e6bdb2 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -136,19 +136,20 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
             workerGroup.shutdownGracefully();
         }
 
+        if (channels != null) {
+            channels.close();
+        }
+
         started = false;
     }
 
     @Override
     public synchronized List<InetSocketAddress> getListenAddresses() {
-        ImmutableList.Builder<InetSocketAddress> builder = ImmutableList.builder();
-        for (Channel channel : ImmutableList.copyOf(channels.iterator())) {
-            builder.add((InetSocketAddress) channel.localAddress());
-        }
-        return builder.build();
+        return channels.stream()
+            .map(channel -> (InetSocketAddress) channel.localAddress())
+            .collect(ImmutableList.toImmutableList());
     }
     
-    
     /**
      * Create ChannelPipelineFactory to use by this Server implementation
      */

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


[james-project] 11/29: JAMES-3715 Restore changes to logback-test.xml

Posted by bt...@apache.org.
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 06eb2ee47675830c0a7e9f8afbaa6453d2554a3b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Mar 8 12:22:38 2022 +0700

    JAMES-3715 Restore changes to logback-test.xml
---
 testing/base/src/main/resources/logback-test.xml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/testing/base/src/main/resources/logback-test.xml b/testing/base/src/main/resources/logback-test.xml
index a09363d..ddcf72c 100644
--- a/testing/base/src/main/resources/logback-test.xml
+++ b/testing/base/src/main/resources/logback-test.xml
@@ -17,7 +17,10 @@
                 <encoder>
                         <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
                 </encoder>
-                <immediateFlush>true</immediateFlush>
+                <immediateFlush>false</immediateFlush>
+                <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                        <level>ERROR</level>
+                </filter>
         </appender>
 
         <root level="WARN">

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


[james-project] 10/29: JAMES-3715 IMAP: Avoid a deadlock upon COMPRESS

Posted by bt...@apache.org.
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 acb5a9282eee20ebaadc803d3d259427502e49b6
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 7 16:10:27 2022 +0700

    JAMES-3715 IMAP: Avoid a deadlock upon COMPRESS
    
    The initial COMPRESS OK response was never sent because it was sent out of
    the event loop.
    
    We explicitly write it from the event loop so that the client is guarantied to receive it.
    
    We wrap the answer inside the "disabled-auto-read" to guaranty that a
    "too quick client" do not end up with a race condition...
---
 .../apache/james/imap/api/process/ImapSession.java  |  2 +-
 .../apache/james/imap/encode/FakeImapSession.java   |  2 +-
 .../james/imap/processor/CompressProcessor.java     |  6 ++++--
 .../james/imapserver/netty/NettyImapSession.java    | 21 ++++++++++++++-------
 4 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
index 4444ed4..1f793c2 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
@@ -193,7 +193,7 @@ public interface ImapSession extends CommandDetectionSession {
      * 
      * @return success
      */
-    boolean startCompression();
+    boolean startCompression(ImmutableStatusResponse response);
 
     /**
      * Push in a new {@link ImapLineHandler} which is called for the next line received
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
index cb1de55..4f2b5ae 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
@@ -134,7 +134,7 @@ public class FakeImapSession implements ImapSession {
     }
 
     @Override
-    public boolean startCompression() {
+    public boolean startCompression(ImmutableStatusResponse response) {
         return false;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
index 449a545..566d1a0 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
@@ -25,10 +25,12 @@ import java.util.List;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.message.Capability;
+import org.apache.james.imap.api.message.response.StatusResponse;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.message.request.CompressRequest;
+import org.apache.james.imap.message.response.ImmutableStatusResponse;
 import org.apache.james.imap.processor.base.AbstractChainedProcessor;
 import org.apache.james.util.MDCBuilder;
 
@@ -55,9 +57,9 @@ public class CompressProcessor extends AbstractChainedProcessor<CompressRequest>
                 if (request.getAlgorithm().equalsIgnoreCase(ALGO) == false) {
                     responder.respond(factory.taggedBad(request.getTag(), request.getCommand(), HumanReadableText.ILLEGAL_ARGUMENTS));
                 } else {
-                    responder.respond(factory.taggedOk(request.getTag(), request.getCommand(), HumanReadableText.DEFLATE_ACTIVE));
+                    StatusResponse response = factory.taggedOk(request.getTag(), request.getCommand(), HumanReadableText.DEFLATE_ACTIVE);
 
-                    if (session.startCompression()) {
+                    if (session.startCompression((ImmutableStatusResponse) response)) {
                         session.setAttribute(COMPRESSED, true);
                     }
                 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index 2e6c109..d92ff14 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -48,6 +48,8 @@ import io.netty.handler.codec.compression.ZlibWrapper;
 import io.netty.handler.ssl.SslHandler;
 
 public class NettyImapSession implements ImapSession, NettyConstants {
+    private static final int BUFFER_SIZE = 2048;
+
     private ImapSessionState state = ImapSessionState.NON_AUTHENTICATED;
     private SelectedMailbox selectedMailbox;
     private final Map<String, Object> attributesByKey = new HashMap<>();
@@ -155,12 +157,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
             return false;
         }
         channel.config().setAutoRead(false);
-        try {
-            new StatusResponseEncoder(new DefaultLocalizer()).encode(statusResponse,
-                new ImapResponseComposerImpl(new EventLoopImapResponseWriter(channel), 2048));
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+        writeOnTheEventLoop(statusResponse);
 
         SslHandler filter = new SslHandler(secure.createSSLEngine(), false);
 
@@ -172,6 +169,15 @@ public class NettyImapSession implements ImapSession, NettyConstants {
         return true;
     }
 
+    private void writeOnTheEventLoop(ImmutableStatusResponse statusResponse) {
+        try {
+            new StatusResponseEncoder(new DefaultLocalizer()).encode(statusResponse,
+                new ImapResponseComposerImpl(new EventLoopImapResponseWriter(channel), BUFFER_SIZE));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     public static class EventLoopImapResponseWriter implements ImapResponseWriter {
         private final Channel channel;
 
@@ -204,12 +210,13 @@ public class NettyImapSession implements ImapSession, NettyConstants {
     }
 
     @Override
-    public boolean startCompression() {
+    public boolean startCompression(ImmutableStatusResponse response) {
         if (!isCompressionSupported()) {
             return false;
         }
 
         channel.config().setAutoRead(false);
+        writeOnTheEventLoop(response);
         ZlibDecoder decoder = new JZlibDecoder(ZlibWrapper.NONE);
         ZlibEncoder encoder = new JZlibEncoder(ZlibWrapper.NONE, 5);
 

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


[james-project] 18/29: JAMES-3715 Avoid stateful static fields

Posted by bt...@apache.org.
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 5618e72d24f13971bd3bbe7fd70162ab54ef317d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Mar 16 13:03:15 2022 +0700

    JAMES-3715 Avoid stateful static fields
    
    ByteBuf are pooled and can be released. Rely on supplier instead.
---
 .../james/imapserver/netty/AbstractNettyImapRequestLineReader.java   | 5 +++--
 .../java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
index 9230b50..14be6d5 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
@@ -19,6 +19,7 @@
 package org.apache.james.imapserver.netty;
 
 import java.nio.charset.StandardCharsets;
+import java.util.function.Supplier;
 
 import org.apache.james.imap.decode.ImapRequestLineReader;
 
@@ -27,7 +28,7 @@ import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 
 public abstract class AbstractNettyImapRequestLineReader extends ImapRequestLineReader {
-    private static final ByteBuf CONTINUATION_REQUEST = Unpooled.wrappedUnmodifiableBuffer(Unpooled.wrappedBuffer("+ Ok\r\n".getBytes(StandardCharsets.US_ASCII)));
+    private static final Supplier<ByteBuf> CONTINUATION_REQUEST = () -> Unpooled.wrappedUnmodifiableBuffer(Unpooled.wrappedBuffer("+ Ok\r\n".getBytes(StandardCharsets.US_ASCII)));
 
     private final Channel channel;
     private final boolean retry;
@@ -44,7 +45,7 @@ public abstract class AbstractNettyImapRequestLineReader extends ImapRequestLine
         // request..
 
         if (!retry) {
-            channel.writeAndFlush(CONTINUATION_REQUEST);
+            channel.writeAndFlush(CONTINUATION_REQUEST.get());
         }
     }
 
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java
index 0bfa67f..21c3781 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java
@@ -19,6 +19,7 @@
 package org.apache.james.imapserver.netty;
 
 import java.nio.charset.StandardCharsets;
+import java.util.function.Supplier;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -31,7 +32,7 @@ import io.netty.handler.timeout.IdleStateHandler;
 @ChannelHandler.Sharable
 public class ImapHeartbeatHandler extends IdleStateHandler {
 
-    private static final ByteBuf HEARTBEAT_BUFFER = Unpooled.wrappedUnmodifiableBuffer(Unpooled.wrappedBuffer("* OK Hang in there..\r\n".getBytes(StandardCharsets.US_ASCII)));
+    private static final Supplier<ByteBuf> HEARTBEAT_BUFFER = () -> Unpooled.wrappedUnmodifiableBuffer(Unpooled.wrappedBuffer("* OK Hang in there..\r\n".getBytes(StandardCharsets.US_ASCII)));
 
     ImapHeartbeatHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {
         super(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds);
@@ -40,7 +41,7 @@ public class ImapHeartbeatHandler extends IdleStateHandler {
     @Override
     public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
         if (e.state().equals(IdleState.WRITER_IDLE)) {
-            ctx.channel().writeAndFlush(HEARTBEAT_BUFFER);
+            ctx.channel().writeAndFlush(HEARTBEAT_BUFFER.get());
         }
         super.channelIdle(ctx, e);
     }

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


[james-project] 28/29: JAMES-3715 Rename: UpstreamHandler -> InboundHandler

Posted by bt...@apache.org.
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 1a5c3a7edacc3c07103be77d6e883d9fcdccb06e
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 21 10:44:00 2022 +0700

    JAMES-3715 Rename: UpstreamHandler -> InboundHandler
---
 ...andler.java => BasicChannelInboundHandler.java} | 508 ++++++++++-----------
 .../apache/james/protocols/netty/NettyServer.java  |   2 +-
 .../apache/james/lmtpserver/netty/LMTPServer.java  |   4 +-
 .../apache/james/pop3server/netty/POP3Server.java  |   4 +-
 ...Handler.java => SMTPChannelInboundHandler.java} | 166 +++----
 .../apache/james/smtpserver/netty/SMTPServer.java  |   2 +-
 6 files changed, 343 insertions(+), 343 deletions(-)

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/BasicChannelInboundHandler.java
similarity index 94%
rename from protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java
rename to protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelInboundHandler.java
index 96a9d0d..7fc2fbc 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/BasicChannelInboundHandler.java
@@ -1,254 +1,254 @@
-/****************************************************************
- * 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.apache.james.protocols.api.ProtocolSession.State.Connection;
-
-import java.io.Closeable;
-import java.nio.channels.ClosedChannelException;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentLinkedDeque;
-
-import javax.net.ssl.SSLEngine;
-
-import org.apache.james.protocols.api.CommandDetectionSession;
-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.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.util.MDCBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Iterables;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.handler.codec.TooLongFrameException;
-import io.netty.util.AttributeKey;
-
-/**
- * {@link ChannelInboundHandlerAdapter} which is used by the SMTPServer and other line based protocols
- */
-public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter implements LineHandlerAware {
-    private static final Logger LOGGER = LoggerFactory.getLogger(BasicChannelUpstreamHandler.class);
-    public static final ProtocolSession.AttachmentKey<MDCBuilder> MDC_ATTRIBUTE_KEY = ProtocolSession.AttachmentKey.of("bound_MDC", MDCBuilder.class);
-    public static final AttributeKey<CommandDetectionSession> SESSION_ATTRIBUTE_KEY =
-            AttributeKey.valueOf("session");
-
-    private final ProtocolMDCContextFactory mdcContextFactory;
-    protected final Protocol protocol;
-    protected final ProtocolHandlerChain chain;
-    protected final Encryption secure;
-    private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
-
-    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol) {
-        this(mdcContextFactory, protocol, null);
-    }
-
-    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, Encryption secure) {
-        this.mdcContextFactory = mdcContextFactory;
-        this.protocol = protocol;
-        this.chain = protocol.getProtocolChain();
-        this.secure = secure;
-    }
-
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public void channelActive(ChannelHandlerContext ctx) throws Exception {
-        MDCBuilder boundMDC = mdcContextFactory.onBound(protocol, ctx);
-        try (Closeable closeable = boundMDC.build()) {
-            ProtocolSession session = createSession(ctx);
-            session.setAttachment(MDC_ATTRIBUTE_KEY, boundMDC, Connection);
-            ctx.channel().attr(SESSION_ATTRIBUTE_KEY).set(session);
-
-            List<ConnectHandler> connectHandlers = chain.getHandlers(ConnectHandler.class);
-            List<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
-
-            LOGGER.info("Connection established from {}", session.getRemoteAddress().getAddress().getHostAddress());
-            if (connectHandlers != null) {
-                for (ConnectHandler cHandler : connectHandlers) {
-                    long start = System.currentTimeMillis();
-                    Response response = cHandler.onConnect(session);
-                    long executionTime = System.currentTimeMillis() - start;
-
-                    for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
-                        resultHandler.onResponse(session, response, executionTime, cHandler);
-                    }
-                    if (response != null) {
-                        // TODO: This kind of sucks but I was able to come up with something more elegant here
-                        ((ProtocolSessionImpl) session).getProtocolTransport().writeResponse(response, session);
-                    }
-
-                }
-            }
-
-            super.channelActive(ctx);
-        }
-    }
-
-    private MDCBuilder mdc(ChannelHandlerContext ctx) {
-        ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
-
-        return Optional.ofNullable(session)
-            .flatMap(s -> s.getAttachment(MDC_ATTRIBUTE_KEY, Connection))
-            .map(mdc -> mdcContextFactory.withContext(session)
-                .addToContext(mdc))
-            .orElseGet(MDCBuilder::create);
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-        try (Closeable closeable = mdc(ctx).build()) {
-            List<DisconnectHandler> connectHandlers = chain.getHandlers(DisconnectHandler.class);
-            ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
-            if (connectHandlers != null) {
-                for (DisconnectHandler connectHandler : connectHandlers) {
-                    connectHandler.onDisconnect(session);
-                }
-            }
-            LOGGER.info("Connection closed for {}", session.getRemoteAddress().getAddress().getHostAddress());
-            cleanup(ctx);
-            super.channelInactive(ctx);
-        }
-    }
-
-
-    /**
-     * Call the {@link LineHandler} 
-     */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        ChannelInboundHandlerAdapter override = Iterables.getFirst(behaviourOverrides, null);
-        if (override != null) {
-            override.channelRead(ctx, msg);
-            return;
-        }
-
-        try (Closeable closeable = mdc(ctx).build()) {
-            ProtocolSession pSession = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
-            LinkedList<LineHandler> lineHandlers = chain.getHandlers(LineHandler.class);
-            LinkedList<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
-
-
-            if (lineHandlers.size() > 0) {
-
-                ByteBuf buf = (ByteBuf) msg;
-                LineHandler lHandler = (LineHandler) lineHandlers.getLast();
-                long start = System.currentTimeMillis();
-                Response response = lHandler.onLine(pSession, buf.nioBuffer());
-                long executionTime = System.currentTimeMillis() - start;
-
-                for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
-                    response = resultHandler.onResponse(pSession, response, executionTime, lHandler);
-                }
-                if (response != null) {
-                    // TODO: This kind of sucks but I was able to come up with something more elegant here
-                    ((ProtocolSessionImpl) pSession).getProtocolTransport().writeResponse(response, pSession);
-                }
-
-            }
-
-            ((ByteBuf) msg).release();
-            super.channelReadComplete(ctx);
-        }
-    }
-
-
-    /**
-     * Cleanup the channel
-     */
-    protected void cleanup(ChannelHandlerContext ctx) {
-        ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).getAndRemove();
-        if (session != null) {
-            session.resetState();
-        }
-        ctx.close();
-    }
-
-    
-    
-    protected ProtocolSession createSession(ChannelHandlerContext ctx) throws Exception {
-        SSLEngine engine = null;
-        if (secure != null) {
-            engine = secure.createSSLEngine();
-        }
-
-        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine));
-    }
-
-    @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-        try (Closeable closeable = mdc(ctx).build()) {
-            Channel channel = ctx.channel();
-            ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
-            if (cause instanceof TooLongFrameException && session != null) {
-                Response r = session.newLineTooLongResponse();
-                ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
-                if (r != null) {
-                    transport.writeResponse(r, session);
-                }
-            } else {
-                if (channel.isActive() && session != null) {
-                    ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
-
-                    Response r = session.newFatalErrorResponse();
-                    if (r != null) {
-                        transport.writeResponse(r, session);
-                    }
-                    transport.writeResponse(Response.DISCONNECT, session);
-                }
-                if (cause instanceof ClosedChannelException) {
-                    LOGGER.info("Channel closed before we could send in flight messages to the users (ClosedChannelException): {}", cause.getMessage());
-                } else {
-                    LOGGER.error("Unable to process request", cause);
-                }
-                ctx.close();
-            }
-        }
-    }
-
-    @Override
-    public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
-        behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
-    }
-
-    @Override
-    public void popLineHandler() {
-        if (!behaviourOverrides.isEmpty()) {
-            behaviourOverrides.removeFirst();
-        }
-    }
-
-}
+/****************************************************************
+ * 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.apache.james.protocols.api.ProtocolSession.State.Connection;
+
+import java.io.Closeable;
+import java.nio.channels.ClosedChannelException;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentLinkedDeque;
+
+import javax.net.ssl.SSLEngine;
+
+import org.apache.james.protocols.api.CommandDetectionSession;
+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.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.util.MDCBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Iterables;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.codec.TooLongFrameException;
+import io.netty.util.AttributeKey;
+
+/**
+ * {@link ChannelInboundHandlerAdapter} which is used by the SMTPServer and other line based protocols
+ */
+public class BasicChannelInboundHandler extends ChannelInboundHandlerAdapter implements LineHandlerAware {
+    private static final Logger LOGGER = LoggerFactory.getLogger(BasicChannelInboundHandler.class);
+    public static final ProtocolSession.AttachmentKey<MDCBuilder> MDC_ATTRIBUTE_KEY = ProtocolSession.AttachmentKey.of("bound_MDC", MDCBuilder.class);
+    public static final AttributeKey<CommandDetectionSession> SESSION_ATTRIBUTE_KEY =
+            AttributeKey.valueOf("session");
+
+    private final ProtocolMDCContextFactory mdcContextFactory;
+    protected final Protocol protocol;
+    protected final ProtocolHandlerChain chain;
+    protected final Encryption secure;
+    private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
+
+    public BasicChannelInboundHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol) {
+        this(mdcContextFactory, protocol, null);
+    }
+
+    public BasicChannelInboundHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, Encryption secure) {
+        this.mdcContextFactory = mdcContextFactory;
+        this.protocol = protocol;
+        this.chain = protocol.getProtocolChain();
+        this.secure = secure;
+    }
+
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        MDCBuilder boundMDC = mdcContextFactory.onBound(protocol, ctx);
+        try (Closeable closeable = boundMDC.build()) {
+            ProtocolSession session = createSession(ctx);
+            session.setAttachment(MDC_ATTRIBUTE_KEY, boundMDC, Connection);
+            ctx.channel().attr(SESSION_ATTRIBUTE_KEY).set(session);
+
+            List<ConnectHandler> connectHandlers = chain.getHandlers(ConnectHandler.class);
+            List<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
+
+            LOGGER.info("Connection established from {}", session.getRemoteAddress().getAddress().getHostAddress());
+            if (connectHandlers != null) {
+                for (ConnectHandler cHandler : connectHandlers) {
+                    long start = System.currentTimeMillis();
+                    Response response = cHandler.onConnect(session);
+                    long executionTime = System.currentTimeMillis() - start;
+
+                    for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
+                        resultHandler.onResponse(session, response, executionTime, cHandler);
+                    }
+                    if (response != null) {
+                        // TODO: This kind of sucks but I was able to come up with something more elegant here
+                        ((ProtocolSessionImpl) session).getProtocolTransport().writeResponse(response, session);
+                    }
+
+                }
+            }
+
+            super.channelActive(ctx);
+        }
+    }
+
+    private MDCBuilder mdc(ChannelHandlerContext ctx) {
+        ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
+
+        return Optional.ofNullable(session)
+            .flatMap(s -> s.getAttachment(MDC_ATTRIBUTE_KEY, Connection))
+            .map(mdc -> mdcContextFactory.withContext(session)
+                .addToContext(mdc))
+            .orElseGet(MDCBuilder::create);
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        try (Closeable closeable = mdc(ctx).build()) {
+            List<DisconnectHandler> connectHandlers = chain.getHandlers(DisconnectHandler.class);
+            ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
+            if (connectHandlers != null) {
+                for (DisconnectHandler connectHandler : connectHandlers) {
+                    connectHandler.onDisconnect(session);
+                }
+            }
+            LOGGER.info("Connection closed for {}", session.getRemoteAddress().getAddress().getHostAddress());
+            cleanup(ctx);
+            super.channelInactive(ctx);
+        }
+    }
+
+
+    /**
+     * Call the {@link LineHandler} 
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ChannelInboundHandlerAdapter override = Iterables.getFirst(behaviourOverrides, null);
+        if (override != null) {
+            override.channelRead(ctx, msg);
+            return;
+        }
+
+        try (Closeable closeable = mdc(ctx).build()) {
+            ProtocolSession pSession = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
+            LinkedList<LineHandler> lineHandlers = chain.getHandlers(LineHandler.class);
+            LinkedList<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
+
+
+            if (lineHandlers.size() > 0) {
+
+                ByteBuf buf = (ByteBuf) msg;
+                LineHandler lHandler = (LineHandler) lineHandlers.getLast();
+                long start = System.currentTimeMillis();
+                Response response = lHandler.onLine(pSession, buf.nioBuffer());
+                long executionTime = System.currentTimeMillis() - start;
+
+                for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
+                    response = resultHandler.onResponse(pSession, response, executionTime, lHandler);
+                }
+                if (response != null) {
+                    // TODO: This kind of sucks but I was able to come up with something more elegant here
+                    ((ProtocolSessionImpl) pSession).getProtocolTransport().writeResponse(response, pSession);
+                }
+
+            }
+
+            ((ByteBuf) msg).release();
+            super.channelReadComplete(ctx);
+        }
+    }
+
+
+    /**
+     * Cleanup the channel
+     */
+    protected void cleanup(ChannelHandlerContext ctx) {
+        ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).getAndRemove();
+        if (session != null) {
+            session.resetState();
+        }
+        ctx.close();
+    }
+
+    
+    
+    protected ProtocolSession createSession(ChannelHandlerContext ctx) throws Exception {
+        SSLEngine engine = null;
+        if (secure != null) {
+            engine = secure.createSSLEngine();
+        }
+
+        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine));
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        try (Closeable closeable = mdc(ctx).build()) {
+            Channel channel = ctx.channel();
+            ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
+            if (cause instanceof TooLongFrameException && session != null) {
+                Response r = session.newLineTooLongResponse();
+                ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
+                if (r != null) {
+                    transport.writeResponse(r, session);
+                }
+            } else {
+                if (channel.isActive() && session != null) {
+                    ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
+
+                    Response r = session.newFatalErrorResponse();
+                    if (r != null) {
+                        transport.writeResponse(r, session);
+                    }
+                    transport.writeResponse(Response.DISCONNECT, session);
+                }
+                if (cause instanceof ClosedChannelException) {
+                    LOGGER.info("Channel closed before we could send in flight messages to the users (ClosedChannelException): {}", cause.getMessage());
+                } else {
+                    LOGGER.error("Unable to process request", cause);
+                }
+                ctx.close();
+            }
+        }
+    }
+
+    @Override
+    public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
+        behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
+    }
+
+    @Override
+    public void popLineHandler() {
+        if (!behaviourOverrides.isEmpty()) {
+            behaviourOverrides.removeFirst();
+        }
+    }
+
+}
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 951cdda..1eda6a5 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
@@ -97,7 +97,7 @@ public class NettyServer extends AbstractAsyncServer {
     }
 
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure);
+        return new BasicChannelInboundHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure);
     }
     
     @Override
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 0596813..c51fe75 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
@@ -33,7 +33,7 @@ import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.LineDelimiterBasedChannelHandlerFactory;
 import org.apache.james.protocols.smtp.SMTPProtocol;
-import org.apache.james.smtpserver.netty.SMTPChannelUpstreamHandler;
+import org.apache.james.smtpserver.netty.SMTPChannelInboundHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -142,7 +142,7 @@ public class LMTPServer extends AbstractProtocolAsyncServer implements LMTPServe
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
         SMTPProtocol protocol = new SMTPProtocol(getProtocolHandlerChain(), lmtpConfig);
-        return new SMTPChannelUpstreamHandler(protocol, lmtpMetrics, getExecutorGroup());
+        return new SMTPChannelInboundHandler(protocol, lmtpMetrics, getExecutorGroup());
     }
 
     @Override
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 8d18599..89725cc 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
@@ -25,7 +25,7 @@ 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.AllButStartTlsLineChannelHandlerFactory;
-import org.apache.james.protocols.netty.BasicChannelUpstreamHandler;
+import org.apache.james.protocols.netty.BasicChannelInboundHandler;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ProtocolMDCContextFactory;
 import org.apache.james.protocols.pop3.POP3Protocol;
@@ -86,7 +86,7 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve
 
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, getEncryption());
+        return new BasicChannelInboundHandler(new ProtocolMDCContextFactory.Standard(), protocol, getEncryption());
     }
 
     @Override
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelInboundHandler.java
similarity index 84%
rename from server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
rename to server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelInboundHandler.java
index df984d7..2515226 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelInboundHandler.java
@@ -1,83 +1,83 @@
-/****************************************************************
- * 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.smtpserver.netty;
-
-import org.apache.james.lifecycle.api.LifecycleUtil;
-import org.apache.james.protocols.api.Encryption;
-import org.apache.james.protocols.api.Protocol;
-import org.apache.james.protocols.api.ProtocolSession.State;
-import org.apache.james.protocols.netty.BasicChannelUpstreamHandler;
-import org.apache.james.protocols.smtp.SMTPSession;
-import org.apache.james.protocols.smtp.core.SMTPMDCContextFactory;
-import org.apache.james.smtpserver.SMTPConstants;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.util.concurrent.EventExecutorGroup;
-
-/**
- * {@link BasicChannelUpstreamHandler} which is used by the SMTPServer
- */
-public class SMTPChannelUpstreamHandler extends BasicChannelUpstreamHandler {
-
-    private final SmtpMetrics smtpMetrics;
-
-    public SMTPChannelUpstreamHandler(Protocol protocol, Encryption encryption, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
-        super(new SMTPMDCContextFactory(), protocol, encryption);
-        this.smtpMetrics = smtpMetrics;
-    }
-
-    public SMTPChannelUpstreamHandler(Protocol protocol, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
-        super(new SMTPMDCContextFactory(), protocol);
-        this.smtpMetrics = smtpMetrics;
-    }
-
-    @Override
-    public void channelActive(ChannelHandlerContext ctx) throws Exception {
-        super.channelActive(ctx);
-        smtpMetrics.getConnectionMetric().increment();
-    }
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        super.channelRead(ctx, msg);
-        smtpMetrics.getCommandsMetric().increment();
-    }
-
-    @Override
-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-        super.channelInactive(ctx);
-        smtpMetrics.getConnectionMetric().decrement();
-    }
-
-    /**
-     * Cleanup temporary files
-     */
-    @Override
-    protected void cleanup(ChannelHandlerContext ctx) {
-        // Make sure we dispose everything on exit on session close
-        SMTPSession smtpSession = ctx.channel().attr(SMTPConstants.SMTP_SESSION_ATTRIBUTE_KEY).get();
-
-        if (smtpSession != null) {
-            smtpSession.getAttachment(SMTPConstants.MAIL, State.Transaction).ifPresent(LifecycleUtil::dispose);
-            smtpSession.getAttachment(SMTPConstants.DATA_MIMEMESSAGE_STREAMSOURCE, State.Transaction).ifPresent(LifecycleUtil::dispose);
-        }
-
-        super.cleanup(ctx);
-    }
-}
+/****************************************************************
+ * 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.smtpserver.netty;
+
+import org.apache.james.lifecycle.api.LifecycleUtil;
+import org.apache.james.protocols.api.Encryption;
+import org.apache.james.protocols.api.Protocol;
+import org.apache.james.protocols.api.ProtocolSession.State;
+import org.apache.james.protocols.netty.BasicChannelInboundHandler;
+import org.apache.james.protocols.smtp.SMTPSession;
+import org.apache.james.protocols.smtp.core.SMTPMDCContextFactory;
+import org.apache.james.smtpserver.SMTPConstants;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.util.concurrent.EventExecutorGroup;
+
+/**
+ * {@link BasicChannelInboundHandler} which is used by the SMTPServer
+ */
+public class SMTPChannelInboundHandler extends BasicChannelInboundHandler {
+
+    private final SmtpMetrics smtpMetrics;
+
+    public SMTPChannelInboundHandler(Protocol protocol, Encryption encryption, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
+        super(new SMTPMDCContextFactory(), protocol, encryption);
+        this.smtpMetrics = smtpMetrics;
+    }
+
+    public SMTPChannelInboundHandler(Protocol protocol, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
+        super(new SMTPMDCContextFactory(), protocol);
+        this.smtpMetrics = smtpMetrics;
+    }
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        super.channelActive(ctx);
+        smtpMetrics.getConnectionMetric().increment();
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        super.channelRead(ctx, msg);
+        smtpMetrics.getCommandsMetric().increment();
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        super.channelInactive(ctx);
+        smtpMetrics.getConnectionMetric().decrement();
+    }
+
+    /**
+     * Cleanup temporary files
+     */
+    @Override
+    protected void cleanup(ChannelHandlerContext ctx) {
+        // Make sure we dispose everything on exit on session close
+        SMTPSession smtpSession = ctx.channel().attr(SMTPConstants.SMTP_SESSION_ATTRIBUTE_KEY).get();
+
+        if (smtpSession != null) {
+            smtpSession.getAttachment(SMTPConstants.MAIL, State.Transaction).ifPresent(LifecycleUtil::dispose);
+            smtpSession.getAttachment(SMTPConstants.DATA_MIMEMESSAGE_STREAMSOURCE, State.Transaction).ifPresent(LifecycleUtil::dispose);
+        }
+
+        super.cleanup(ctx);
+    }
+}
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 78dfa59..4f07978 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
@@ -385,7 +385,7 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe
 
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return new SMTPChannelUpstreamHandler(transport, getEncryption(), smtpMetrics, getExecutorGroup());
+        return new SMTPChannelInboundHandler(transport, getEncryption(), smtpMetrics, getExecutorGroup());
     }
 
     @Override

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


[james-project] 17/29: JAMES-3715 ImapRequestFrameDecoder avoid calling ChannelPipeline::get on each request

Posted by bt...@apache.org.
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 98af5c6cf32bafe21e3639da8f7c711a819c4951
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 11 10:01:25 2022 +0700

    JAMES-3715 ImapRequestFrameDecoder avoid calling ChannelPipeline::get on each request
    
    Pipeline get was taking up to 4.25% of IMAP request decoding time. We can
    easily handle state in ImapRequestFrameDecoder to not need this.
---
 .../org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java  | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
index fb5d363..968178c 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.ImapSessionState;
@@ -62,6 +63,7 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
     private final int literalSizeLimit;
     private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
     private final int maxFrameLength;
+    private final AtomicBoolean framingEnabled = new AtomicBoolean(true);
 
     public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit, int maxFrameLength) {
         this.decoder = decoder;
@@ -214,10 +216,12 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
         ctx.channel().config().setAutoRead(false);
         ctx.channel().eventLoop().execute(() -> ctx.channel().pipeline().remove(FRAMER));
         ctx.channel().config().setAutoRead(true);
+        framingEnabled.set(false);
     }
 
     public void enableFraming(ChannelHandlerContext ctx) {
-        if (ctx.channel().pipeline().get(FRAMER) == null) {
+        if (!framingEnabled.get()) {
+            framingEnabled.set(true);
             ctx.channel().config().setAutoRead(false);
             ctx.channel().eventLoop().execute(() ->
                 ctx.channel().pipeline().addBefore(REQUEST_DECODER, FRAMER,

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


[james-project] 25/29: JAMES-3715 ChannelGroups: rely on immediate executor

Posted by bt...@apache.org.
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 27ab3a45bb3e5f354bb1d441804aa8a53d10e088
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 21 10:27:54 2022 +0700

    JAMES-3715 ChannelGroups: rely on immediate executor
    
    'GlobalEventExecutor' states - please note it is not scalable to schedule large number of tasks to this executor; use a dedicated executor.
    
    Projects like Reactor Netty use ImmediateEventExecutor.INSTANCE so I'd potentially recommend changing to;
    
        private final ChannelGroup channels = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
    
    This will then just execute actions against the channel group on the current thread.
---
 .../java/org/apache/james/protocols/netty/AbstractAsyncServer.java   | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index cd95677..eefeff6 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -37,8 +37,7 @@ import io.netty.channel.group.DefaultChannelGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.util.concurrent.GlobalEventExecutor;
-
+import io.netty.util.concurrent.ImmediateEventExecutor;
 
 
 /**
@@ -56,7 +55,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
 
     private volatile boolean started;
     
-    private final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
+    private final ChannelGroup channels = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
 
     private volatile int ioWorker = DEFAULT_IO_WORKER_COUNT;
     

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


[james-project] 07/29: JAMES-3715 Fix SMTP pipelining

Posted by bt...@apache.org.
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 43205f9c2357516d95b8ff4405f9e6746727b14f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 7 14:48:32 2022 +0700

    JAMES-3715 Fix SMTP pipelining
    
    Concurrent modifications of the pipeline are not safe, embed the line handler
    logic into the core handler to avoid bad surprises...
---
 .../james/protocols/api/ProtocolSession.java       |  6 ----
 .../james/protocols/api/ProtocolSessionImpl.java   |  5 ---
 .../james/protocols/api/ProtocolTransport.java     |  5 ---
 .../api/AbstractProtocolTransportTest.java         |  5 ---
 .../netty/BasicChannelUpstreamHandler.java         | 39 ++++++++++++++++------
 .../james/protocols/netty/LineHandlerAware.java    |  7 ++++
 .../protocols/netty/NettyProtocolTransport.java    | 27 ++++-----------
 .../apache/james/protocols/netty/NettyServer.java  | 12 ++-----
 .../protocols/smtp/utils/BaseFakeSMTPSession.java  |  5 ---
 .../apache/james/pop3server/netty/POP3Server.java  |  9 +++--
 .../netty/SMTPChannelUpstreamHandler.java          |  6 ++--
 .../apache/james/smtpserver/netty/SMTPServer.java  | 10 ++----
 testing/base/src/main/resources/logback-test.xml   |  5 +--
 13 files changed, 54 insertions(+), 87 deletions(-)

diff --git a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSession.java b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSession.java
index a9dc57e..9410124 100644
--- a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSession.java
+++ b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSession.java
@@ -231,10 +231,4 @@ public interface ProtocolSession extends CommandDetectionSession {
      * Pop the last command handler 
      */
     void popLineHandler();
-    
-    /**
-     * Return the size of the pushed {@link LineHandler}
-     * @return size of the pushed line handler
-     */
-    int getPushedLineHandlerCount();
 }
diff --git a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSessionImpl.java b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSessionImpl.java
index 1e88275..0750f82 100644
--- a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSessionImpl.java
+++ b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolSessionImpl.java
@@ -213,11 +213,6 @@ public class ProtocolSessionImpl implements ProtocolSession {
     }
 
     @Override
-    public int getPushedLineHandlerCount() {
-        return transport.getPushedLineHandlerCount();
-    }
-
-    @Override
     public <T extends ProtocolSession> void pushLineHandler(LineHandler<T> overrideCommandHandler) {
         transport.pushLineHandler(overrideCommandHandler, this);
     }
diff --git a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolTransport.java b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolTransport.java
index add23e8..09f5377 100644
--- a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolTransport.java
+++ b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolTransport.java
@@ -73,11 +73,6 @@ public interface ProtocolTransport {
      * Push a {@link LineHandler} in.
      */
     void pushLineHandler(LineHandler<? extends ProtocolSession> overrideCommandHandler, ProtocolSession session);
-
-    /**
-     * Return the count of pushed {@link LineHandler}'s
-     */
-    int getPushedLineHandlerCount();
     
     
     /**
diff --git a/protocols/api/src/test/java/org/apache/james/protocols/api/AbstractProtocolTransportTest.java b/protocols/api/src/test/java/org/apache/james/protocols/api/AbstractProtocolTransportTest.java
index 7d6a91a..f6c4933 100644
--- a/protocols/api/src/test/java/org/apache/james/protocols/api/AbstractProtocolTransportTest.java
+++ b/protocols/api/src/test/java/org/apache/james/protocols/api/AbstractProtocolTransportTest.java
@@ -92,11 +92,6 @@ public class AbstractProtocolTransportTest {
             }
             
             @Override
-            public int getPushedLineHandlerCount() {
-                throw new UnsupportedOperationException();
-            }
-            
-            @Override
             public InetSocketAddress getLocalAddress() {
                 throw new UnsupportedOperationException();
             }
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 1cde815..8534a99 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
@@ -22,9 +22,11 @@ import static org.apache.james.protocols.api.ProtocolSession.State.Connection;
 
 import java.io.Closeable;
 import java.nio.channels.ClosedChannelException;
+import java.util.Deque;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.ConcurrentLinkedDeque;
 
 import javax.net.ssl.SSLEngine;
 
@@ -44,21 +46,19 @@ import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Iterables;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler.Sharable;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.codec.TooLongFrameException;
 import io.netty.util.AttributeKey;
-import io.netty.util.concurrent.EventExecutorGroup;
-
 
 /**
  * {@link ChannelInboundHandlerAdapter} which is used by the SMTPServer and other line based protocols
  */
-@Sharable
-public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
+public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter implements LineHandlerAware {
     private static final Logger LOGGER = LoggerFactory.getLogger(BasicChannelUpstreamHandler.class);
     public static final ProtocolSession.AttachmentKey<MDCBuilder> MDC_ATTRIBUTE_KEY = ProtocolSession.AttachmentKey.of("bound_MDC", MDCBuilder.class);
     public static final AttributeKey<CommandDetectionSession> SESSION_ATTRIBUTE_KEY =
@@ -68,18 +68,17 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
     protected final Protocol protocol;
     protected final ProtocolHandlerChain chain;
     protected final Encryption secure;
-    private final EventExecutorGroup eventExecutors;
+    private final Deque<LineHandlerUpstreamHandler> behaviourOverrides = new ConcurrentLinkedDeque<>();
 
-    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, EventExecutorGroup eventExecutors) {
-        this(mdcContextFactory, protocol, null, eventExecutors);
+    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol) {
+        this(mdcContextFactory, protocol, null);
     }
 
-    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, Encryption secure, EventExecutorGroup eventExecutors) {
+    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, Encryption secure) {
         this.mdcContextFactory = mdcContextFactory;
         this.protocol = protocol;
         this.chain = protocol.getProtocolChain();
         this.secure = secure;
-        this.eventExecutors = eventExecutors;
     }
 
 
@@ -151,6 +150,12 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        LineHandlerUpstreamHandler override = Iterables.getFirst(behaviourOverrides, null);
+        if (override != null) {
+            override.channelRead(ctx, msg);
+            return;
+        }
+
         try (Closeable closeable = mdc(ctx).build()) {
             ProtocolSession pSession = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
             LinkedList<LineHandler> lineHandlers = chain.getHandlers(LineHandler.class);
@@ -200,7 +205,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
             engine = secure.createSSLEngine();
         }
 
-        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine, eventExecutors));
+        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine));
     }
 
     @Override
@@ -234,4 +239,16 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
         }
     }
 
+    @Override
+    public void pushLineHandler(LineHandlerUpstreamHandler lineHandlerUpstreamHandler) {
+        behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
+    }
+
+    @Override
+    public void popLineHandler() {
+        if (!behaviourOverrides.isEmpty()) {
+            behaviourOverrides.removeFirst();
+        }
+    }
+
 }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
new file mode 100644
index 0000000..516dadf
--- /dev/null
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
@@ -0,0 +1,7 @@
+package org.apache.james.protocols.netty;
+
+public interface LineHandlerAware {
+    void pushLineHandler(LineHandlerUpstreamHandler lineHandlerUpstreamHandler);
+
+    void popLineHandler();
+}
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
index bdeee67..c5cc824 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
@@ -38,7 +38,6 @@ import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.DefaultFileRegion;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.handler.stream.ChunkedStream;
-import io.netty.util.concurrent.EventExecutorGroup;
 
 
 /**
@@ -48,13 +47,10 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
     
     private final Channel channel;
     private final SSLEngine engine;
-    private final EventExecutorGroup eventExecutors;
-    private int lineHandlerCount = 0;
     
-    public NettyProtocolTransport(Channel channel, SSLEngine engine, EventExecutorGroup eventExecutors) {
+    public NettyProtocolTransport(Channel channel, SSLEngine engine) {
         this.channel = channel;
         this.engine = engine;
-        this.eventExecutors = eventExecutors;
     }
 
     @Override
@@ -80,15 +76,9 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
 
     @Override
     public void popLineHandler() {
-        if (lineHandlerCount > 0) {
-            channel.pipeline().remove("lineHandler" + lineHandlerCount);
-            lineHandlerCount--;
-        }
-    }
-
-    @Override
-    public int getPushedLineHandlerCount() {
-        return lineHandlerCount;
+        LineHandlerAware channelHandler = (LineHandlerAware) channel.pipeline()
+            .get(HandlerConstants.CORE_HANDLER);
+        channelHandler.popLineHandler();
     }
 
     /**
@@ -154,12 +144,9 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
     @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public void pushLineHandler(LineHandler<? extends ProtocolSession> overrideCommandHandler, ProtocolSession session) {
-        lineHandlerCount++;
-        // Add the linehandler in front of the coreHandler so we can be sure 
-        // it is executed with the same ExecutorHandler as the coreHandler (if one exist)
-        // 
-        // See JAMES-1277
-        channel.pipeline().addBefore(eventExecutors, HandlerConstants.CORE_HANDLER, "lineHandler" + lineHandlerCount, new LineHandlerUpstreamHandler(session, overrideCommandHandler));
+        LineHandlerAware channelHandler = (LineHandlerAware) channel.pipeline()
+            .get(HandlerConstants.CORE_HANDLER);
+        channelHandler.pushLineHandler(new LineHandlerUpstreamHandler(session, overrideCommandHandler));
     }
     
    
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 e50a498..82e0e4f 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
@@ -30,16 +30,13 @@ import com.google.common.base.Preconditions;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.DefaultEventLoopGroup;
 import io.netty.channel.group.ChannelGroup;
-import io.netty.util.concurrent.DefaultEventExecutorGroup;
 
 
 /**
  * Generic NettyServer 
  */
 public class NettyServer extends AbstractAsyncServer {
-
     public static class Factory {
-
         private Protocol protocol;
         private Optional<Encryption> secure;
         private Optional<ChannelHandlerFactory> frameHandlerFactory;
@@ -77,11 +74,7 @@ public class NettyServer extends AbstractAsyncServer {
     protected final Encryption secure;
     protected final Protocol protocol;
     private final ChannelHandlerFactory frameHandlerFactory;
-
-    private ChannelInboundHandlerAdapter coreHandler;
-
     private int maxCurConnections;
-
     private int maxCurConnectionsPerIP;
    
     private NettyServer(Protocol protocol, Encryption secure, ChannelHandlerFactory frameHandlerFactory) {
@@ -105,12 +98,11 @@ public class NettyServer extends AbstractAsyncServer {
     }
 
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure, new DefaultEventExecutorGroup(2));
+        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure);
     }
     
     @Override
     public synchronized void bind() throws Exception {
-        coreHandler = createCoreHandler();
         super.bind();
     }
 
@@ -132,7 +124,7 @@ public class NettyServer extends AbstractAsyncServer {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
-                return coreHandler;
+                return createCoreHandler();
             }
         };
 
diff --git a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/utils/BaseFakeSMTPSession.java b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/utils/BaseFakeSMTPSession.java
index 0954de6..b474f32 100644
--- a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/utils/BaseFakeSMTPSession.java
+++ b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/utils/BaseFakeSMTPSession.java
@@ -123,11 +123,6 @@ public class BaseFakeSMTPSession implements SMTPSession {
     }
 
     @Override
-    public int getPushedLineHandlerCount() {
-        throw new UnsupportedOperationException("Unimplemented Stub Method");
-    }
-
-    @Override
     public Response newLineTooLongResponse() {
         throw new UnsupportedOperationException("Unimplemented Stub Method");
     }
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 f05ec6c..8d18599 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
@@ -41,8 +41,8 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve
      * The configuration data to be passed to the handler
      */
     private final ProtocolConfiguration theConfigData = new POP3Configuration();
-    private BasicChannelUpstreamHandler coreHandler;
-    
+    private POP3Protocol protocol;
+
     @Override
     protected int getDefaultPort() {
         return 110;
@@ -76,8 +76,7 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve
     @Override
     protected void preInit() throws Exception {
         super.preInit();
-        POP3Protocol protocol = new POP3Protocol(getProtocolHandlerChain(), theConfigData);
-        coreHandler = new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, getEncryption(), getExecutorGroup());
+        protocol = new POP3Protocol(getProtocolHandlerChain(), theConfigData);
     }
 
     @Override
@@ -87,7 +86,7 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve
 
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return coreHandler; 
+        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, getEncryption());
     }
 
     @Override
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
index 5379db5..df984d7 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
@@ -27,25 +27,23 @@ import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.core.SMTPMDCContextFactory;
 import org.apache.james.smtpserver.SMTPConstants;
 
-import io.netty.channel.ChannelHandler.Sharable;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.util.concurrent.EventExecutorGroup;
 
 /**
  * {@link BasicChannelUpstreamHandler} which is used by the SMTPServer
  */
-@Sharable
 public class SMTPChannelUpstreamHandler extends BasicChannelUpstreamHandler {
 
     private final SmtpMetrics smtpMetrics;
 
     public SMTPChannelUpstreamHandler(Protocol protocol, Encryption encryption, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
-        super(new SMTPMDCContextFactory(), protocol, encryption, eventExecutorGroup);
+        super(new SMTPMDCContextFactory(), protocol, encryption);
         this.smtpMetrics = smtpMetrics;
     }
 
     public SMTPChannelUpstreamHandler(Protocol protocol, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
-        super(new SMTPMDCContextFactory(), protocol, eventExecutorGroup);
+        super(new SMTPMDCContextFactory(), protocol);
         this.smtpMetrics = smtpMetrics;
     }
 
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 83f1534..78dfa59 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
@@ -56,6 +56,7 @@ import io.netty.channel.ChannelInboundHandlerAdapter;
  */
 public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServerMBean {
     private static final Logger LOGGER = LoggerFactory.getLogger(SMTPServer.class);
+    private SMTPProtocol transport;
 
     public enum AuthenticationAnnounceMode {
         NEVER,
@@ -186,8 +187,6 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe
 
     private DNSService dns;
     private String authorizedAddresses;
-    
-    private SMTPChannelUpstreamHandler coreHandler;
 
     public SMTPServer(SmtpMetrics smtpMetrics) {
         this.smtpMetrics = smtpMetrics;
@@ -211,15 +210,12 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe
             authorizedNetworks = new NetMatcher(networks, dns);
             LOGGER.info("Authorized addresses: {}", authorizedNetworks);
         }
-        SMTPProtocol transport = new SMTPProtocol(getProtocolHandlerChain(), theConfigData) {
-
+        transport = new SMTPProtocol(getProtocolHandlerChain(), theConfigData) {
             @Override
             public ProtocolSession newSession(ProtocolTransport transport) {
                 return new ExtendedSMTPSession(theConfigData, transport);
             }
-            
         };
-        coreHandler = new SMTPChannelUpstreamHandler(transport, getEncryption(), smtpMetrics, getExecutorGroup());
     }
 
     @Override
@@ -389,7 +385,7 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe
 
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return coreHandler;
+        return new SMTPChannelUpstreamHandler(transport, getEncryption(), smtpMetrics, getExecutorGroup());
     }
 
     @Override
diff --git a/testing/base/src/main/resources/logback-test.xml b/testing/base/src/main/resources/logback-test.xml
index ddcf72c..a09363d 100644
--- a/testing/base/src/main/resources/logback-test.xml
+++ b/testing/base/src/main/resources/logback-test.xml
@@ -17,10 +17,7 @@
                 <encoder>
                         <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
                 </encoder>
-                <immediateFlush>false</immediateFlush>
-                <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
-                        <level>ERROR</level>
-                </filter>
+                <immediateFlush>true</immediateFlush>
         </appender>
 
         <root level="WARN">

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


[james-project] 23/29: JAMES-3715 Add missing license

Posted by bt...@apache.org.
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 354fb766b43affab8e464802be071f74cb4c494d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 18 10:56:47 2022 +0700

    JAMES-3715 Add missing license
---
 .../james/protocols/netty/LineHandlerAware.java       | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
index 355d1c8..85df4e2 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
@@ -1,3 +1,22 @@
+/****************************************************************
+ * 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 io.netty.channel.ChannelInboundHandlerAdapter;

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


[james-project] 21/29: JAMES-3715 Cap boss threads to 2

Posted by bt...@apache.org.
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 5e685fa95ff2a1d596cfaa32ba10b8c01d9d2dbf
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 17 14:12:18 2022 +0700

    JAMES-3715 Cap boss threads to 2
    
    We are not seeing a strong connection churn thus accepting new connections is
    done quickly enough
---
 .../main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index a2f8e93..22e1471 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -93,7 +93,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
         ServerBootstrap bootstrap = new ServerBootstrap();
         bootstrap.channel(NioServerSocketChannel.class);
 
-        bossGroup = new NioEventLoopGroup(NamedThreadFactory.withName(jmxName + "-boss"));
+        bossGroup = new NioEventLoopGroup(2, NamedThreadFactory.withName(jmxName + "-boss"));
         workerGroup = new NioEventLoopGroup(ioWorker, NamedThreadFactory.withName(jmxName + "-io"));
 
         bootstrap.group(bossGroup, workerGroup);

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


[james-project] 03/29: JAMES-3715 Remove no longer use methods

Posted by bt...@apache.org.
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 130c5481f05b88375adae6f9dcdb6191318e7ee5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Feb 27 20:27:50 2022 +0700

    JAMES-3715 Remove no longer use methods
    
    Netty 4 no longer allows setting internal threads and instead relies
    on event loop groups.
    
    Removing unused methods...
---
 .../james/protocols/netty/AbstractAsyncServer.java | 22 ----------------------
 .../lib/netty/AbstractConfigurableAsyncServer.java | 15 ---------------
 2 files changed, 37 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index d0997cc..52371d8 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -21,12 +21,8 @@ package org.apache.james.protocols.netty;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
 
 import org.apache.james.protocols.api.ProtocolServer;
-import org.apache.james.util.concurrent.NamedThreadFactory;
 
 import com.google.common.collect.ImmutableList;
 
@@ -191,24 +187,6 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     public int getTimeout() {
         return timeout;
     }
-    
-    /**
-     * Create a new {@link Executor} used for dispatch messages to the workers. One Thread will be used per port which is bound.
-     * This can get overridden if needed, by default it use a {@link Executors#newCachedThreadPool()}
-     */
-    protected Executor createBossExecutor() {
-        ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
-        return Executors.newCachedThreadPool(threadFactory);
-    }
-
-    /**
-     * Create a new {@link Executor} used for workers. This can get overridden if needed, by default it use a {@link Executors#newCachedThreadPool()}
-     */
-    protected Executor createWorkerExecutor() {
-        ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
-        return Executors.newCachedThreadPool(threadFactory);
-    }
-    
 
     @Override
     public boolean isBound() {
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 5d5df1a..c85cf5d 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
@@ -26,7 +26,6 @@ import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
-import java.util.concurrent.Executor;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -49,7 +48,6 @@ import org.apache.james.protocols.lib.jmx.ServerMBean;
 import org.apache.james.protocols.netty.AbstractAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
-import org.apache.james.util.concurrent.JMXEnabledThreadPoolExecutor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -484,19 +482,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
         return connectionLimit;
     }
 
-    protected String getThreadPoolJMXPath() {
-        return "org.apache.james:type=server,name=" + jmxName + ",sub-type=threadpool";
-    }
-    
-    @Override
-    protected Executor createBossExecutor() {
-        return JMXEnabledThreadPoolExecutor.newCachedThreadPool(getThreadPoolJMXPath(), getDefaultJMXName() + "-boss");
-    }
-
-    @Override
-    protected Executor createWorkerExecutor() {
-        return JMXEnabledThreadPoolExecutor.newCachedThreadPool(getThreadPoolJMXPath(), getDefaultJMXName() + "-worker");
-    }
 
     /**
      * Return the default name of the the server in JMX if none is configured

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


[james-project] 19/29: JAMES-3715 Writing on the first context bypasses the SSL encoder

Posted by bt...@apache.org.
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 98fc22177e69558b1821064d9d4a6d27c1054d44
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Mar 16 15:33:19 2022 +0700

    JAMES-3715 Writing on the first context bypasses the SSL encoder
---
 .../java/org/apache/james/imapserver/netty/NettyImapSession.java  | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index d92ff14..2a5cb0d 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -157,7 +157,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
             return false;
         }
         channel.config().setAutoRead(false);
-        writeOnTheEventLoop(statusResponse);
+        write(statusResponse);
 
         SslHandler filter = new SslHandler(secure.createSSLEngine(), false);
 
@@ -169,7 +169,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
         return true;
     }
 
-    private void writeOnTheEventLoop(ImmutableStatusResponse statusResponse) {
+    private void write(ImmutableStatusResponse statusResponse) {
         try {
             new StatusResponseEncoder(new DefaultLocalizer()).encode(statusResponse,
                 new ImapResponseComposerImpl(new EventLoopImapResponseWriter(channel), BUFFER_SIZE));
@@ -188,7 +188,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
         @Override
         public void write(byte[] buffer) {
             if (channel.isActive()) {
-                channel.pipeline().firstContext().writeAndFlush(Unpooled.wrappedBuffer(buffer));
+                channel.writeAndFlush(Unpooled.wrappedBuffer(buffer));
             }
         }
 
@@ -216,7 +216,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
         }
 
         channel.config().setAutoRead(false);
-        writeOnTheEventLoop(response);
+        write(response);
         ZlibDecoder decoder = new JZlibDecoder(ZlibWrapper.NONE);
         ZlibEncoder encoder = new JZlibEncoder(ZlibWrapper.NONE, 5);
 

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


[james-project] 02/29: JAMES-3715 Carry over `ioWorkerCount` configuration parameter

Posted by bt...@apache.org.
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 7fd6eb0622aaa843a03ee9a219b4907c413cd6c6
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Feb 27 20:22:34 2022 +0700

    JAMES-3715 Carry over `ioWorkerCount` configuration parameter
    
    Before this parameter was ignored, we can use it to size Netty server
    child executor instead.
---
 .../main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index f11ea48..d0997cc 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -97,7 +97,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
         bootstrap.channel(NioServerSocketChannel.class);
 
         bossGroup = new NioEventLoopGroup();
-        workerGroup = new NioEventLoopGroup();
+        workerGroup = new NioEventLoopGroup(ioWorker);
 
         bootstrap.group(bossGroup, workerGroup);
 

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


[james-project] 01/29: JAMES-3715 Upgrade to netty 4

Posted by bt...@apache.org.
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 f1ed7533fb2fe6db0d7799bb65a1247c4969e6b7
Author: Franz Fangmeyer <fr...@worldline.com>
AuthorDate: Wed Feb 9 09:38:31 2022 +0100

    JAMES-3715 Upgrade to netty 4
---
 pom.xml                                            |   9 +-
 .../processor/fetch/PartialFetchBodyElement.java   |   5 +-
 .../protocols/lmtp/netty/NettyLMTPSServerTest.java |  17 +--
 .../protocols/lmtp/netty/NettyLMTPServerTest.java  |  14 +-
 protocols/netty/pom.xml                            |   3 +-
 .../james/protocols/netty/AbstractAsyncServer.java |  77 ++++++-----
 .../netty/AbstractChannelPipelineFactory.java      |  52 ++++----
 .../AbstractSSLAwareChannelPipelineFactory.java    |  33 ++---
 .../AllButStartTlsLineBasedChannelHandler.java     |  27 ++--
 .../AllButStartTlsLineChannelHandlerFactory.java   |   4 +-
 .../netty/BasicChannelUpstreamHandler.java         | 122 ++++++++----------
 .../james/protocols/netty/ChannelGroupHandler.java |  19 +--
 .../protocols/netty/ChannelHandlerFactory.java     |   4 +-
 .../netty/ConnectionLimitUpstreamHandler.java      |  24 ++--
 .../netty/ConnectionPerIpLimitUpstreamHandler.java |  28 ++--
 .../james/protocols/netty/HandlerConstants.java    |   6 +-
 .../LineDelimiterBasedChannelHandlerFactory.java   |   6 +-
 .../netty/LineHandlerUpstreamHandler.java          |  23 ++--
 .../protocols/netty/NettyProtocolTransport.java    |  47 +++----
 .../apache/james/protocols/netty/NettyServer.java  |  49 +++----
 .../protocols/netty/ProtocolMDCContextFactory.java |   8 +-
 .../james/protocols/netty/TimeoutHandler.java      |  21 +--
 .../james/protocols/netty/NettyServerTest.java     |  21 +--
 .../pop3/core/CRLFTerminatedInputStream.java       |  17 ++-
 .../protocols/pop3/AbstractPOP3ServerTest.java     |   2 +-
 .../protocols/pop3/netty/NettyPOP3SServerTest.java |  15 +--
 .../protocols/pop3/netty/NettyPOP3ServerTest.java  |  18 +--
 .../pop3/netty/NettyStartTlsPOP3ServerTest.java    |  18 +--
 protocols/smtp/pom.xml                             |   2 +-
 .../protocols/smtp/core/SMTPMDCContextFactory.java |   3 +-
 .../protocols/smtp/netty/NettySMTPSServerTest.java |  17 +--
 .../protocols/smtp/netty/NettySMTPServerTest.java  |  16 +--
 .../smtp/netty/NettyStartTlsSMTPServerTest.java    |  11 +-
 server/blob/blob-s3/pom.xml                        |   1 -
 .../modules/protocols/ProtocolHandlerModule.java   |   1 -
 .../james/modules/protocols/IMAPServerModule.java  |   2 -
 .../james/modules/protocols/LMTPServerModule.java  |   2 -
 .../james/modules/protocols/NettyServerModule.java |  45 -------
 .../james/modules/protocols/POP3ServerModule.java  |   2 -
 .../james/modules/protocols/SMTPServerModule.java  |   2 -
 .../META-INF/org/apache/james/spring-server.xml    |   2 -
 .../james/mock/smtp/server/MockSMTPServerTest.java |   2 +-
 ...eJmapRFC8621AuthenticationStrategyContract.java |   2 +-
 server/protocols/protocols-imap4/pom.xml           |  11 +-
 .../netty/AbstractNettyImapRequestLineReader.java  |  11 +-
 .../netty/ChannelImapResponseWriter.java           |  34 ++---
 .../james/imapserver/netty/IMAPMDCContext.java     |   7 +-
 .../apache/james/imapserver/netty/IMAPServer.java  |  54 ++++----
 .../james/imapserver/netty/IMAPServerFactory.java  |   6 +-
 .../netty/ImapChannelUpstreamHandler.java          | 106 ++++++++--------
 .../imapserver/netty/ImapHeartbeatHandler.java     |  28 ++--
 .../imapserver/netty/ImapIdleStateHandler.java     |  31 +++--
 .../imapserver/netty/ImapLineHandlerAdapter.java   |  20 +--
 .../imapserver/netty/ImapRequestFrameDecoder.java  | 102 ++++++---------
 .../james/imapserver/netty/NettyConstants.java     |  12 +-
 .../netty/NettyImapRequestLineReader.java          |  27 ++--
 .../james/imapserver/netty/NettyImapSession.java   |  55 ++++----
 .../netty/NettyStreamImapRequestLineReader.java    |   3 +-
 .../james/imapserver/netty/OioIMAPServer.java      |  51 --------
 .../imapserver/netty/OioIMAPServerFactory.java     |  43 -------
 .../netty/SwitchableLineBasedFrameDecoder.java     |  30 ++---
 .../SwitchableLineBasedFrameDecoderFactory.java    |   5 +-
 .../netty/ImapRequestFrameDecoderTest.java         |  80 ------------
 server/protocols/protocols-library/pom.xml         |   2 +-
 .../lib/netty/AbstractConfigurableAsyncServer.java |  52 ++------
 ...bstractExecutorAwareChannelPipelineFactory.java |  22 +---
 .../lib/netty/ConnectionCountHandler.java          |  17 +--
 ...nabledOrderedMemoryAwareThreadPoolExecutor.java | 141 ---------------------
 .../lib/AbstractConfigurableAsyncServerTest.java   |   4 +-
 server/protocols/protocols-lmtp/pom.xml            |   2 +-
 .../apache/james/lmtpserver/netty/LMTPServer.java  |   5 +-
 .../james/lmtpserver/netty/LMTPServerFactory.java  |   7 +-
 .../james/lmtpserver/netty/OioLMTPServer.java      |  50 --------
 .../lmtpserver/netty/OioLMTPServerFactory.java     |  41 ------
 .../apache/james/lmtpserver/LmtpServerTest.java    |   3 +-
 server/protocols/protocols-managesieve/pom.xml     |   2 +-
 .../netty/ChannelManageSieveResponseWriter.java    |   9 +-
 .../netty/ManageSieveChannelUpstreamHandler.java   |  91 +++++++------
 .../netty/ManageSieveMDCContext.java               |  14 +-
 .../managesieveserver/netty/ManageSieveServer.java |  44 +++----
 .../netty/ManageSieveServerFactory.java            |   8 --
 .../managesieveserver/netty/NettyConstants.java}   |  17 +--
 server/protocols/protocols-pop3/pom.xml            |   2 +-
 .../james/pop3server/netty/OioPOP3Server.java      |  44 -------
 .../pop3server/netty/OioPOP3ServerFactory.java     |  29 -----
 .../apache/james/pop3server/netty/POP3Server.java  |   5 +-
 .../james/pop3server/netty/POP3ServerFactory.java  |   8 --
 .../apache/james/pop3server/POP3ServerTest.java    |   5 -
 server/protocols/protocols-smtp/pom.xml            |   2 +-
 .../org/apache/james/smtpserver/SMTPConstants.java |   5 +
 .../james/smtpserver/netty/OioSMTPServer.java      |  47 -------
 .../smtpserver/netty/OioSMTPServerFactory.java     |  43 -------
 .../netty/SMTPChannelUpstreamHandler.java          |  24 ++--
 .../apache/james/smtpserver/netty/SMTPServer.java  |   5 +-
 .../james/smtpserver/netty/SMTPServerFactory.java  |   6 +-
 .../apache/james/smtpserver/AuthAnnounceTest.java  |   5 -
 .../java/org/apache/james/smtpserver/DSNTest.java  |   5 -
 .../apache/james/smtpserver/OioSMTPServerTest.java |  31 -----
 .../org/apache/james/smtpserver/SMTPSaslTest.java  |   5 -
 .../apache/james/smtpserver/SMTPServerTest.java    |   5 -
 100 files changed, 739 insertions(+), 1583 deletions(-)

diff --git a/pom.xml b/pom.xml
index 35837a5..162efbd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -610,7 +610,7 @@
         <junit.vintage.version>5.7.0</junit.vintage.version>
         <concurrent.version>1.3.4</concurrent.version>
         <xbean-spring.version>4.18</xbean-spring.version>
-        <netty.version>3.10.6.Final</netty.version>
+        <netty.version>4.1.72.Final</netty.version>
         <cucumber.version>2.4.0</cucumber.version>
 
         <pax-logging-api.version>1.6.4</pax-logging-api.version>
@@ -2170,6 +2170,11 @@
                 <version>2.6.0</version>
             </dependency>
             <dependency>
+                <groupId>com.jcraft</groupId>
+                <artifactId>jzlib</artifactId>
+                <version>1.1.3</version>
+            </dependency>
+            <dependency>
                 <groupId>com.linagora</groupId>
                 <artifactId>metrics-elasticsearch-reporter</artifactId>
                 <version>${es-reporter.version}</version>
@@ -2360,7 +2365,7 @@
             </dependency>
             <dependency>
                 <groupId>io.netty</groupId>
-                <artifactId>netty</artifactId>
+                <artifactId>netty-handler</artifactId>
                 <version>${netty.version}</version>
             </dependency>
             <dependency>
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/PartialFetchBodyElement.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/PartialFetchBodyElement.java
index 9d33e1f..2de3eb8 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/PartialFetchBodyElement.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/PartialFetchBodyElement.java
@@ -145,9 +145,12 @@ final class PartialFetchBodyElement implements BodyElement {
             // Correctly calculate in available bytes.
             // See IMAP-295
             checkOffset();
+            if (pos >= length) {
+                return 0;
+            }
             int i = in.available();
             if (i == -1) {
-                return -1;
+                return 0;
             } else {
                 if (i >= length) {
                     return (int) length - (int) pos;
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 95e58b3..43725d0 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
@@ -8,30 +8,15 @@ import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.api.utils.BogusSslContextFactory;
 import org.apache.james.protocols.lmtp.AbstractLMTPSServerTest;
 import org.apache.james.protocols.netty.NettyServer;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 
 public class NettyLMTPSServerTest extends AbstractLMTPSServerTest {
 
     private static final String LOCALHOST_IP = "127.0.0.1";
     private static final int RANDOM_PORT = 0;
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    public void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    public void teardown() {
-        hashedWheelTimer.stop();
-    }
-
     @Override
     protected ProtocolServer createServer(Protocol protocol) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .secure(Encryption.createTls(BogusSslContextFactory.getServerContext()))
                 .build();
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 8a75e71..69b0127 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
@@ -24,7 +24,6 @@ import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.lmtp.AbstractLMTPServerTest;
 import org.apache.james.protocols.netty.NettyServer;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 
@@ -33,21 +32,10 @@ public class NettyLMTPServerTest extends AbstractLMTPServerTest {
     private static final String LOCALHOST_IP = "127.0.0.1";
     private static final int RANDOM_PORT = 0;
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    public void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    public void teardown() {
-        hashedWheelTimer.stop();
-    }
 
     @Override
     protected ProtocolServer createServer(Protocol protocol) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .build();
         server.setListenAddresses(new InetSocketAddress(LOCALHOST_IP, RANDOM_PORT));
diff --git a/protocols/netty/pom.xml b/protocols/netty/pom.xml
index 2d07a1e..84de57f 100644
--- a/protocols/netty/pom.xml
+++ b/protocols/netty/pom.xml
@@ -52,7 +52,8 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
+            <version>4.1.72.Final</version>
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
index 036699e..f11ea48 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractAsyncServer.java
@@ -27,17 +27,23 @@ import java.util.concurrent.ThreadFactory;
 
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.util.concurrent.NamedThreadFactory;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.ServerSocketChannelFactory;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.util.ExternalResourceReleasable;
 
 import com.google.common.collect.ImmutableList;
 
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.channel.group.DefaultChannelGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.util.concurrent.GlobalEventExecutor;
+
+
+
 /**
  * Abstract base class for Servers which want to use async io
  */
@@ -49,10 +55,12 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     private volatile int timeout = 120;
 
     private ServerBootstrap bootstrap;
+    private EventLoopGroup bossGroup;
+    private EventLoopGroup workerGroup;
 
     private volatile boolean started;
     
-    private final ChannelGroup channels = new DefaultChannelGroup();
+    private final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
 
     private volatile int ioWorker = DEFAULT_IO_WORKER_COUNT;
     
@@ -85,18 +93,27 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
             throw new RuntimeException("Please specify at least on socketaddress to which the server should get bound!");
         }
 
-        bootstrap = new ServerBootstrap(createSocketChannelFactory());
-        ChannelPipelineFactory factory = createPipelineFactory(channels);
-        
+        bootstrap = new ServerBootstrap();
+        bootstrap.channel(NioServerSocketChannel.class);
+
+        bossGroup = new NioEventLoopGroup();
+        workerGroup = new NioEventLoopGroup();
+
+        bootstrap.group(bossGroup, workerGroup);
+
+        ChannelInitializer<SocketChannel> factory = createPipelineFactory(channels);
+
         // Configure the pipeline factory.
-        bootstrap.setPipelineFactory(factory);
-        configureBootstrap(bootstrap);
+        bootstrap.childHandler(factory);
 
         for (InetSocketAddress address : addresses) {
-            channels.add(bootstrap.bind(address));
+            Channel channel = bootstrap.bind(address).sync().channel();
+            channels.add(channel);
         }
-        started = true;
 
+        configureBootstrap(bootstrap);
+
+        started = true;
     }
 
     /**
@@ -104,27 +121,25 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
      */
     protected void configureBootstrap(ServerBootstrap bootstrap) {
         // Bind and start to accept incoming connections.
-        bootstrap.setOption("backlog", backlog);
-        bootstrap.setOption("reuseAddress", true);
-        bootstrap.setOption("child.tcpNoDelay", true);
+        bootstrap.option(ChannelOption.SO_BACKLOG, backlog);
+        bootstrap.option(ChannelOption.SO_REUSEADDR, true);
+        bootstrap.option(ChannelOption.TCP_NODELAY, true);
     }
     
-    protected ServerSocketChannelFactory createSocketChannelFactory() {
-        return new NioServerSocketChannelFactory(createBossExecutor(), createWorkerExecutor(), ioWorker);
-    }
-    
-
     @Override
     public synchronized void unbind() {
         if (started == false) {
             return;
         }
-        ChannelPipelineFactory factory = bootstrap.getPipelineFactory();
-        if (factory instanceof ExternalResourceReleasable) {
-            ((ExternalResourceReleasable) factory).releaseExternalResources();
+
+        if (bossGroup != null) {
+            bossGroup.shutdownGracefully();
+        }
+
+        if (workerGroup != null) {
+            workerGroup.shutdownGracefully();
         }
-        channels.close().awaitUninterruptibly();
-        bootstrap.releaseExternalResources();
+
         started = false;
     }
 
@@ -132,7 +147,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     public synchronized List<InetSocketAddress> getListenAddresses() {
         ImmutableList.Builder<InetSocketAddress> builder = ImmutableList.builder();
         for (Channel channel : ImmutableList.copyOf(channels.iterator())) {
-            builder.add((InetSocketAddress) channel.getLocalAddress());
+            builder.add((InetSocketAddress) channel.localAddress());
         }
         return builder.build();
     }
@@ -141,7 +156,7 @@ public abstract class AbstractAsyncServer implements ProtocolServer {
     /**
      * Create ChannelPipelineFactory to use by this Server implementation
      */
-    protected abstract ChannelPipelineFactory createPipelineFactory(ChannelGroup group);
+    protected abstract ChannelInitializer<SocketChannel> createPipelineFactory(ChannelGroup group);
 
     /**
      * Set the read/write timeout for the server. This will throw a {@link IllegalStateException} if the
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 fb3554f..32049af 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
@@ -18,47 +18,46 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-import static org.jboss.netty.channel.Channels.pipeline;
-
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.handler.stream.ChunkedWriteHandler;
-import org.jboss.netty.util.HashedWheelTimer;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.stream.ChunkedWriteHandler;
 
 /**
- * Abstract base class for {@link ChannelPipelineFactory} implementations
+ * Abstract base class for {@link ChannelInitializer} implementations
  */
-public abstract class AbstractChannelPipelineFactory implements ChannelPipelineFactory {
+@ChannelHandler.Sharable
+public abstract class AbstractChannelPipelineFactory<C extends SocketChannel> extends ChannelInitializer<C> {
     public static final int MAX_LINE_LENGTH = 8192;
 
     protected final ConnectionLimitUpstreamHandler connectionLimitHandler;
     protected final ConnectionPerIpLimitUpstreamHandler connectionPerIpLimitHandler;
-    private final HashedWheelTimer timer;
     private final ChannelGroupHandler groupHandler;
     private final int timeout;
-    private final ExecutionHandler eHandler;
     private final ChannelHandlerFactory frameHandlerFactory;
-    
+
+    public AbstractChannelPipelineFactory(ChannelGroup channels,
+                                          ChannelHandlerFactory frameHandlerFactory) {
+        this(0, 0, 0, channels, frameHandlerFactory);
+    }
+
     public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup channels,
-                                          ExecutionHandler eHandler, ChannelHandlerFactory frameHandlerFactory,
-                                          HashedWheelTimer hashedWheelTimer) {
+                                          ChannelHandlerFactory frameHandlerFactory) {
         this.connectionLimitHandler = new ConnectionLimitUpstreamHandler(maxConnections);
         this.connectionPerIpLimitHandler = new ConnectionPerIpLimitUpstreamHandler(maxConnectsPerIp);
         this.groupHandler = new ChannelGroupHandler(channels);
         this.timeout = timeout;
-        this.eHandler = eHandler;
         this.frameHandlerFactory = frameHandlerFactory;
-        this.timer = hashedWheelTimer;
     }
     
     
     @Override
-    public ChannelPipeline getPipeline() throws Exception {
+    protected void initChannel(C channel) throws Exception {
         // Create a default pipeline implementation.
-        ChannelPipeline pipeline = pipeline();
+        ChannelPipeline pipeline = channel.pipeline();
         pipeline.addLast(HandlerConstants.GROUP_HANDLER, groupHandler);
 
         pipeline.addLast(HandlerConstants.CONNECTION_LIMIT_HANDLER, connectionLimitHandler);
@@ -71,24 +70,17 @@ public abstract class AbstractChannelPipelineFactory implements ChannelPipelineF
        
         // Add the ChunkedWriteHandler to be able to write ChunkInput
         pipeline.addLast(HandlerConstants.CHUNK_HANDLER, new ChunkedWriteHandler());
-        pipeline.addLast(HandlerConstants.TIMEOUT_HANDLER, new TimeoutHandler(timer, timeout));
+        pipeline.addLast(HandlerConstants.TIMEOUT_HANDLER, new TimeoutHandler(timeout));
 
-        if (eHandler != null) {
-            pipeline.addLast(HandlerConstants.EXECUTION_HANDLER, eHandler);
-        }
-        
         pipeline.addLast(HandlerConstants.CORE_HANDLER, createHandler());
-
-
-        return pipeline;
     }
 
     
     /**
-     * Create the core {@link ChannelUpstreamHandler} to use
+     * Create the core {@link ChannelInboundHandlerAdapter} to use
      *
      * @return coreHandler
      */
-    protected abstract ChannelUpstreamHandler createHandler();
+    protected abstract ChannelInboundHandlerAdapter createHandler();
 
 }
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 0af923d..e509ee0 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
@@ -18,40 +18,44 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-
 import javax.net.ssl.SSLEngine;
 
 import org.apache.james.protocols.api.Encryption;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.util.HashedWheelTimer;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.ssl.SslHandler;
+
 
 /**
  * Abstract base class for {@link ChannelPipeline} implementations which use TLS
  */
-public abstract class AbstractSSLAwareChannelPipelineFactory extends AbstractChannelPipelineFactory {
+@ChannelHandler.Sharable
+public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketChannel> extends AbstractChannelPipelineFactory<C> {
 
     private Encryption secure;
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
-                                                  int maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler eHandler,
-                                                  ChannelHandlerFactory frameHandlerFactory, HashedWheelTimer hashedWheelTimer) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, frameHandlerFactory, hashedWheelTimer);
+                                                  int maxConnections, int maxConnectsPerIp, ChannelGroup group,
+                                                  ChannelHandlerFactory frameHandlerFactory) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory);
     }
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
             int maxConnections, int maxConnectsPerIp, ChannelGroup group, Encryption secure,
-            ExecutionHandler eHandler, ChannelHandlerFactory frameHandlerFactory, HashedWheelTimer hashedWheelTimer) {
-        this(timeout, maxConnections, maxConnectsPerIp, group, eHandler, frameHandlerFactory, hashedWheelTimer);
+            ChannelHandlerFactory frameHandlerFactory) {
+        this(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory);
 
         this.secure = secure;
     }
 
     @Override
-    public ChannelPipeline getPipeline() throws Exception {
-        ChannelPipeline pipeline =  super.getPipeline();
+    public void initChannel(C channel) throws Exception {
+        super.initChannel(channel);
+
+        ChannelPipeline pipeline = channel.pipeline();
 
         if (isSSLSocket()) {
             // We need to set clientMode to false.
@@ -60,7 +64,6 @@ public abstract class AbstractSSLAwareChannelPipelineFactory extends AbstractCha
             engine.setUseClientMode(false);
             pipeline.addFirst(HandlerConstants.SSL_HANDLER, new SslHandler(engine));
         }
-        return pipeline;
     }
 
     /**
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineBasedChannelHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineBasedChannelHandler.java
index fa3f127..82b843e 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineBasedChannelHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineBasedChannelHandler.java
@@ -23,20 +23,25 @@ import java.util.List;
 import java.util.Locale;
 
 import org.apache.james.protocols.api.CommandDetectionSession;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
 
 import com.google.common.base.CharMatcher;
 import com.google.common.base.Splitter;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPipeline;
+import io.netty.handler.codec.LineBasedFrameDecoder;
+import io.netty.util.AttributeKey;
+
+
 public class AllButStartTlsLineBasedChannelHandler extends LineBasedFrameDecoder {
     private static final Boolean FAIL_FAST = true;
     private final ChannelPipeline pipeline;
     private final String pattern;
 
+    private static final AttributeKey<CommandDetectionSession> sessionAttributeKey =
+            AttributeKey.valueOf("session");
+
     public AllButStartTlsLineBasedChannelHandler(ChannelPipeline pipeline, int maxFrameLength, boolean stripDelimiter, String pattern) {
         super(maxFrameLength, stripDelimiter, !FAIL_FAST);
         this.pipeline = pipeline;
@@ -44,8 +49,8 @@ public class AllButStartTlsLineBasedChannelHandler extends LineBasedFrameDecoder
     }
 
     @Override
-    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
-        CommandDetectionSession session = retrieveSession(ctx, channel);
+    protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
+        CommandDetectionSession session = retrieveSession(ctx);
 
         if (session == null || session.needsCommandInjectionDetection()) {
             String trimedLowerCasedInput = readAll(buffer).trim().toLowerCase(Locale.US);
@@ -53,14 +58,14 @@ public class AllButStartTlsLineBasedChannelHandler extends LineBasedFrameDecoder
                 throw new CommandInjectionDetectedException();
             }
         }
-        return super.decode(ctx, channel, buffer);
+        return super.decode(ctx, buffer);
     }
 
-    protected CommandDetectionSession retrieveSession(ChannelHandlerContext ctx, Channel channel) {
-        return (CommandDetectionSession) pipeline.getContext(HandlerConstants.CORE_HANDLER).getAttachment();
+    protected CommandDetectionSession retrieveSession(ChannelHandlerContext ctx) {
+        return pipeline.context(HandlerConstants.CORE_HANDLER).channel().attr(sessionAttributeKey).get();
     }
 
-    private String readAll(ChannelBuffer buffer) {
+    private String readAll(ByteBuf buffer) {
         return buffer.toString(StandardCharsets.US_ASCII);
     }
 
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineChannelHandlerFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineChannelHandlerFactory.java
index 6588616..884c6bb 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineChannelHandlerFactory.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AllButStartTlsLineChannelHandlerFactory.java
@@ -18,8 +18,8 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelPipeline;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
 
 public class AllButStartTlsLineChannelHandlerFactory implements ChannelHandlerFactory {
     private final String pattern;
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 eef4a30..08086a6 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
@@ -28,6 +28,7 @@ import java.util.Optional;
 
 import javax.net.ssl.SSLEngine;
 
+import org.apache.james.protocols.api.CommandDetectionSession;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolSession;
@@ -40,26 +41,27 @@ 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.util.MDCBuilder;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandler.Sharable;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.frame.TooLongFrameException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.codec.TooLongFrameException;
+import io.netty.util.AttributeKey;
+
+
 /**
- * {@link ChannelUpstreamHandler} which is used by the SMTPServer and other line based protocols
+ * {@link ChannelInboundHandlerAdapter} which is used by the SMTPServer and other line based protocols
  */
 @Sharable
-public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
+public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
     private static final Logger LOGGER = LoggerFactory.getLogger(BasicChannelUpstreamHandler.class);
-    private static final ProtocolSession.AttachmentKey<MDCBuilder> MDC_KEY = ProtocolSession.AttachmentKey.of("bound_MDC", MDCBuilder.class);
+    public static final ProtocolSession.AttachmentKey<MDCBuilder> MDC_ATTRIBUTE_KEY = ProtocolSession.AttachmentKey.of("bound_MDC", MDCBuilder.class);
+    public static final AttributeKey<CommandDetectionSession> SESSION_ATTRIBUTE_KEY =
+            AttributeKey.valueOf("session");
 
     private final ProtocolMDCContextFactory mdcContextFactory;
     protected final Protocol protocol;
@@ -78,37 +80,18 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
     }
 
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Override
-    public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
         MDCBuilder boundMDC = mdcContextFactory.onBound(protocol, ctx);
         try (Closeable closeable = boundMDC.build()) {
             ProtocolSession session = createSession(ctx);
-            session.setAttachment(MDC_KEY, boundMDC, Connection);
-            ctx.setAttachment(session);
-            super.channelBound(ctx, e);
-        }
-    }
-
-    private MDCBuilder mdc(ChannelHandlerContext ctx) {
-        ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-
-        return Optional.ofNullable(session)
-            .flatMap(s -> s.getAttachment(MDC_KEY, Connection))
-            .map(mdc -> mdcContextFactory.withContext(session)
-                .addToContext(mdc))
-            .orElseGet(MDCBuilder::create);
-    }
+            session.setAttachment(MDC_ATTRIBUTE_KEY, boundMDC, Connection);
+            ctx.channel().attr(SESSION_ATTRIBUTE_KEY).set(session);
 
-    /**
-     * Call the {@link ConnectHandler} instances which are stored in the {@link ProtocolHandlerChain}
-     */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Override
-    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        try (Closeable closeable = mdc(ctx).build()) {
             List<ConnectHandler> connectHandlers = chain.getHandlers(ConnectHandler.class);
             List<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
-            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+
             LOGGER.info("Connection established from {}", session.getRemoteAddress().getAddress().getHostAddress());
             if (connectHandlers != null) {
                 for (ConnectHandler cHandler : connectHandlers) {
@@ -126,24 +109,35 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
 
                 }
             }
-            super.channelConnected(ctx, e);
+
+            super.channelActive(ctx);
         }
     }
 
+    private MDCBuilder mdc(ChannelHandlerContext ctx) {
+        ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
 
+        return Optional.ofNullable(session)
+            .flatMap(s -> s.getAttachment(MDC_ATTRIBUTE_KEY, Connection))
+            .map(mdc -> mdcContextFactory.withContext(session)
+                .addToContext(mdc))
+            .orElseGet(MDCBuilder::create);
+    }
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Override
-    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         try (Closeable closeable = mdc(ctx).build()) {
             List<DisconnectHandler> connectHandlers = chain.getHandlers(DisconnectHandler.class);
-            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+            ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
             if (connectHandlers != null) {
                 for (DisconnectHandler connectHandler : connectHandlers) {
                     connectHandler.onDisconnect(session);
                 }
             }
-            super.channelDisconnected(ctx, e);
+            LOGGER.info("Connection closed for {}", session.getRemoteAddress().getAddress().getHostAddress());
+            cleanup(ctx);
+            super.channelInactive(ctx);
         }
     }
 
@@ -153,19 +147,19 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
      */
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         try (Closeable closeable = mdc(ctx).build()) {
-            ProtocolSession pSession = (ProtocolSession) ctx.getAttachment();
+            ProtocolSession pSession = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
             LinkedList<LineHandler> lineHandlers = chain.getHandlers(LineHandler.class);
             LinkedList<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
 
 
             if (lineHandlers.size() > 0) {
 
-                ChannelBuffer buf = (ChannelBuffer) e.getMessage();
+                ByteBuf buf = (ByteBuf) msg;
                 LineHandler lHandler = (LineHandler) lineHandlers.getLast();
                 long start = System.currentTimeMillis();
-                Response response = lHandler.onLine(pSession, buf.toByteBuffer());
+                Response response = lHandler.onLine(pSession, buf.nioBuffer());
                 long executionTime = System.currentTimeMillis() - start;
 
                 for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
@@ -178,31 +172,21 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
 
             }
 
-            super.messageReceived(ctx, e);
+            ((ByteBuf) msg).release();
+            super.channelReadComplete(ctx);
         }
     }
 
 
-    @Override
-    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        try (Closeable closeable = mdc(ctx).build()) {
-            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-            LOGGER.info("Connection closed for {}", session.getRemoteAddress().getAddress().getHostAddress());
-            cleanup(ctx);
-
-            super.channelClosed(ctx, e);
-        }
-    }
-
     /**
      * Cleanup the channel
      */
     protected void cleanup(ChannelHandlerContext ctx) {
-        ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+        ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).getAndRemove();
         if (session != null) {
             session.resetState();
-            session = null;
         }
+        ctx.close();
     }
 
     
@@ -213,22 +197,22 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
             engine = secure.createSSLEngine();
         }
 
-        return protocol.newSession(new NettyProtocolTransport(ctx.getChannel(), engine));
+        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine));
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
         try (Closeable closeable = mdc(ctx).build()) {
-            Channel channel = ctx.getChannel();
-            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-            if (e.getCause() instanceof TooLongFrameException && session != null) {
+            Channel channel = ctx.channel();
+            ProtocolSession session = (ProtocolSession) ctx.channel().attr(SESSION_ATTRIBUTE_KEY).get();
+            if (cause instanceof TooLongFrameException && session != null) {
                 Response r = session.newLineTooLongResponse();
                 ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
                 if (r != null) {
                     transport.writeResponse(r, session);
                 }
             } else {
-                if (channel.isConnected() && session != null) {
+                if (channel.isActive() && session != null) {
                     ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
 
                     Response r = session.newFatalErrorResponse();
@@ -237,12 +221,12 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
                     }
                     transport.writeResponse(Response.DISCONNECT, session);
                 }
-                if (e.getCause() instanceof ClosedChannelException) {
-                    LOGGER.info("Channel closed before we could send in flight messages to the users (ClosedChannelException): {}", e.getCause().getMessage());
+                if (cause instanceof ClosedChannelException) {
+                    LOGGER.info("Channel closed before we could send in flight messages to the users (ClosedChannelException): {}", cause.getMessage());
                 } else {
-                    LOGGER.error("Unable to process request", e.getCause());
+                    LOGGER.error("Unable to process request", cause);
                 }
-                cleanup(ctx);
+                ctx.close();
             }
         }
     }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java
index 74d1431..152f888 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelGroupHandler.java
@@ -19,31 +19,22 @@
 
 package org.apache.james.protocols.netty;
 
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.channel.group.ChannelGroup;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.group.ChannelGroup;
 
 /**
  * Add channels to the channel group after the channel was opened.
  * 
  * This handler is thread-safe and thus can be shared across pipelines
  */
-public final class ChannelGroupHandler extends SimpleChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public final class ChannelGroupHandler extends ChannelInboundHandlerAdapter {
     private final ChannelGroup channels;
     
     public ChannelGroupHandler(ChannelGroup channels) {
         this.channels = channels;
     }
    
-    @Override
-    public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        // Add all open channels to the global group so that they are
-        // closed on shutdown.
-        channels.add(e.getChannel());
-        
-        // call the next handler in the chain
-        super.channelOpen(ctx, e);
-    }
 
 }
\ No newline at end of file
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
index 771ddb2..1876a74 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
@@ -18,8 +18,8 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelPipeline;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
 
 public interface ChannelHandlerFactory {
     ChannelHandler create(ChannelPipeline pipeline);
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionLimitUpstreamHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionLimitUpstreamHandler.java
index 9478a1d..cd001ba 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionLimitUpstreamHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionLimitUpstreamHandler.java
@@ -20,21 +20,21 @@ package org.apache.james.protocols.netty;
 
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelPipeline;
 
 /**
- * {@link ChannelUpstreamHandler} which limit the concurrent connection. 
+ * {@link ChannelInboundHandlerAdapter} which limit the concurrent connection.
  * 
  * This handler must be used as singleton when adding it to the {@link ChannelPipeline} to work correctly
  *
  * TODO: Remove when its committed to NETTY. 
  *       https://jira.jboss.org/jira/browse/NETTY-311
  */
-public class ConnectionLimitUpstreamHandler extends SimpleChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public class ConnectionLimitUpstreamHandler extends ChannelInboundHandlerAdapter {
 
     private final AtomicInteger connections = new AtomicInteger(0);
     private volatile int maxConnections = -1;
@@ -44,23 +44,23 @@ public class ConnectionLimitUpstreamHandler extends SimpleChannelUpstreamHandler
     }
 
     @Override
-    public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
         if (maxConnections > 0) {
             int currentCount = connections.incrementAndGet();
             
             if (currentCount > maxConnections) {
-                ctx.getChannel().close();
+                ctx.close();
             }
         }
         
-        super.channelOpen(ctx, e);
+        super.channelActive(ctx);
     }
 
     @Override
-    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         if (maxConnections > 0) {
             connections.decrementAndGet();
         }
-        super.channelClosed(ctx, e);
+        super.channelInactive(ctx);
     }
 }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionPerIpLimitUpstreamHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionPerIpLimitUpstreamHandler.java
index 191493d..9e26105 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionPerIpLimitUpstreamHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ConnectionPerIpLimitUpstreamHandler.java
@@ -23,21 +23,21 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelPipeline;
 
 /**
- * {@link ChannelUpstreamHandler} which limit connections per IP
+ * {@link ChannelInboundHandlerAdapter} which limit connections per IP
  * 
  * This handler must be used as singleton when adding it to the {@link ChannelPipeline} to work correctly
  *
  * TODO: Remove when its committed to NETTY. 
  *       https://jira.jboss.org/jira/browse/NETTY-311
  */
-public class ConnectionPerIpLimitUpstreamHandler extends SimpleChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public class ConnectionPerIpLimitUpstreamHandler extends ChannelInboundHandlerAdapter {
 
     private final ConcurrentMap<String, AtomicInteger> connections = new ConcurrentHashMap<>();
     private final int maxConnectionsPerIp;
@@ -47,9 +47,9 @@ public class ConnectionPerIpLimitUpstreamHandler extends SimpleChannelUpstreamHa
     }
 
     @Override
-    public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
         if (maxConnectionsPerIp > 0) {
-            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
+            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
             String remoteIp = remoteAddress.getAddress().getHostAddress();
             
             AtomicInteger atomicCount = connections.get(remoteIp);
@@ -64,18 +64,18 @@ public class ConnectionPerIpLimitUpstreamHandler extends SimpleChannelUpstreamHa
             } else {
                 Integer count = atomicCount.incrementAndGet();
                 if (count > maxConnectionsPerIp) {
-                    ctx.getChannel().close();
+                    ctx.channel().close();
                 }
             }
         }
         
-        super.channelOpen(ctx, e);
+        super.channelActive(ctx);
     }
     
     @Override
-    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         if (maxConnectionsPerIp > 0) {
-            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
+            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
             String remoteIp = remoteAddress.getAddress().getHostAddress();
             
             AtomicInteger atomicCount = connections.get(remoteIp);
@@ -84,6 +84,6 @@ public class ConnectionPerIpLimitUpstreamHandler extends SimpleChannelUpstreamHa
             }              
             
         }
-        super.channelClosed(ctx, e);
+        super.channelInactive(ctx);
     }
 }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/HandlerConstants.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/HandlerConstants.java
index f9c7b4f..3464ba1 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/HandlerConstants.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/HandlerConstants.java
@@ -18,8 +18,8 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelPipeline;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
 
 /**
  * Provide the keys under which the {@link ChannelHandler}'s are stored in the
@@ -37,8 +37,6 @@ public interface HandlerConstants {
 
     String FRAMER = "framer";
 
-    String EXECUTION_HANDLER = "executionHandler";
-
     String TIMEOUT_HANDLER = "timeoutHandler";
 
     String CORE_HANDLER = "coreHandler";
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
index ca3ead7..1eff6b0 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
@@ -18,9 +18,9 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
+import io.netty.handler.codec.LineBasedFrameDecoder;
 
 public class LineDelimiterBasedChannelHandlerFactory implements ChannelHandlerFactory {
     private static final Boolean FAIL_FAST = true;
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerUpstreamHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerUpstreamHandler.java
index dcccf7b..36ab1cd 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerUpstreamHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerUpstreamHandler.java
@@ -22,18 +22,19 @@ import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.protocols.api.ProtocolSessionImpl;
 import org.apache.james.protocols.api.Response;
 import org.apache.james.protocols.api.handler.LineHandler;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
 
 /**
- * {@link ChannelUpstreamHandler} implementation which will call a given {@link LineHandler} implementation
+ * {@link ChannelInboundHandlerAdapter} implementation which will call a given {@link LineHandler} implementation
  *
  * @param <S>
  */
-public class LineHandlerUpstreamHandler<S extends ProtocolSession> extends SimpleChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public class LineHandlerUpstreamHandler<S extends ProtocolSession> extends ChannelInboundHandlerAdapter {
 
     private final LineHandler<S> handler;
     private final S session;
@@ -44,14 +45,16 @@ public class LineHandlerUpstreamHandler<S extends ProtocolSession> extends Simpl
     }
     
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {        
-        ChannelBuffer buf = (ChannelBuffer) e.getMessage();      
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf buf = (ByteBuf) msg;
 
-        Response response = handler.onLine(session, buf.toByteBuffer()); 
+        Response response = handler.onLine(session, buf.nioBuffer());
         if (response != null) {
             // TODO: This kind of sucks but I was not able to come up with something more elegant here
             ((ProtocolSessionImpl)session).getProtocolTransport().writeResponse(response, session);
         }
+
+        ((ByteBuf) msg).release();
     }
 
 }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
index 6d0b3b4..36d5ab8 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
@@ -30,12 +30,15 @@ import javax.net.ssl.SSLEngine;
 import org.apache.james.protocols.api.AbstractProtocolTransport;
 import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.protocols.api.handler.LineHandler;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFutureListener;
-import org.jboss.netty.channel.DefaultFileRegion;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.handler.stream.ChunkedStream;
+
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.DefaultFileRegion;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedStream;
+
 
 /**
  * A Netty implementation of a ProtocolTransport
@@ -53,17 +56,17 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
 
     @Override
     public InetSocketAddress getRemoteAddress() {
-        return (InetSocketAddress) channel.getRemoteAddress();
+        return (InetSocketAddress) channel.remoteAddress();
     }
 
     @Override
     public String getId() {
-        return Integer.toString(channel.getId());
+        return channel.id().toString();
     }
 
     @Override
     public boolean isTLSStarted() {
-        return channel.getPipeline().get(SslHandler.class) != null;
+        return channel.pipeline().get(SslHandler.class) != null;
     }
 
     @Override
@@ -75,7 +78,7 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
     @Override
     public void popLineHandler() {
         if (lineHandlerCount > 0) {
-            channel.getPipeline().remove("lineHandler" + lineHandlerCount);
+            channel.pipeline().remove("lineHandler" + lineHandlerCount);
             lineHandlerCount--;
         }
     }
@@ -90,8 +93,8 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
      */
     private void prepareStartTLS() {
         SslHandler filter = new SslHandler(engine, true);
-        filter.getEngine().setUseClientMode(false);
-        channel.getPipeline().addFirst(HandlerConstants.SSL_HANDLER, filter);
+        filter.engine().setUseClientMode(false);
+        channel.pipeline().addFirst(HandlerConstants.SSL_HANDLER, filter);
     }
 
     @Override
@@ -99,13 +102,13 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
         if (startTLS) {
             prepareStartTLS();
         }
-        channel.write(ChannelBuffers.wrappedBuffer(bytes));
-        
+
+        ChannelFuture future = channel.writeAndFlush(Unpooled.wrappedBuffer(bytes));
     }
 
     @Override
     protected void close() {
-        channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
+        channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
     }
 
 
@@ -118,31 +121,31 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
             if (in instanceof FileInputStream) {
                 FileChannel fChannel = ((FileInputStream) in).getChannel();
                 try {
-                    channel.write(new DefaultFileRegion(fChannel, 0, fChannel.size(), true));
+                    channel.writeAndFlush(new DefaultFileRegion(fChannel, 0, fChannel.size()));
 
                 } catch (IOException e) {
                     // We handle this later
-                    channel.write(new ChunkedStream(new ExceptionInputStream(e)));
+                    channel.writeAndFlush(new ChunkedStream(new ExceptionInputStream(e)));
                 }
                 return;
             }
         }
-        channel.write(new ChunkedStream(in));
+        channel.writeAndFlush(new ChunkedStream(in));
     }
 
     @Override
     public void setReadable(boolean readable) {
-        channel.setReadable(readable);
+        channel.config().setAutoRead(readable);
     }
 
     @Override
     public boolean isReadable() {
-        return channel.isReadable();
+        return channel.config().isAutoRead();
     }
 
     @Override
     public InetSocketAddress getLocalAddress() {
-        return (InetSocketAddress) channel.getLocalAddress();
+        return (InetSocketAddress) channel.localAddress();
     }
 
     @Override
@@ -153,7 +156,7 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
         // it is executed with the same ExecutorHandler as the coreHandler (if one exist)
         // 
         // See JAMES-1277
-        channel.getPipeline().addBefore(HandlerConstants.CORE_HANDLER, "lineHandler" + lineHandlerCount, new LineHandlerUpstreamHandler(session, overrideCommandHandler));
+        channel.pipeline().addBefore(HandlerConstants.CORE_HANDLER, "lineHandler" + lineHandlerCount, new LineHandlerUpstreamHandler(session, overrideCommandHandler));
     }
     
    
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 ab80c96..35da9a9 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
@@ -24,14 +24,13 @@ import javax.inject.Inject;
 
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.Protocol;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.util.HashedWheelTimer;
 
 import com.google.common.base.Preconditions;
 
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.group.ChannelGroup;
+
+
 
 /**
  * Generic NettyServer 
@@ -40,15 +39,12 @@ public class NettyServer extends AbstractAsyncServer {
 
     public static class Factory {
 
-        private final HashedWheelTimer hashedWheelTimer;
-
         private Protocol protocol;
         private Optional<Encryption> secure;
         private Optional<ChannelHandlerFactory> frameHandlerFactory;
 
         @Inject
-        public Factory(HashedWheelTimer hashedWheelTimer) {
-            this.hashedWheelTimer = hashedWheelTimer;
+        public Factory() {
             secure = Optional.empty();
             frameHandlerFactory = Optional.empty();
         }
@@ -73,32 +69,41 @@ public class NettyServer extends AbstractAsyncServer {
             Preconditions.checkState(protocol != null, "'protocol' is mandatory");
             return new NettyServer(protocol, 
                     secure.orElse(null),
-                    frameHandlerFactory.orElse(new LineDelimiterBasedChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH)),
-                    hashedWheelTimer);
+                    frameHandlerFactory.orElse(new LineDelimiterBasedChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH)));
         }
     }
 
     protected final Encryption secure;
     protected final Protocol protocol;
     private final ChannelHandlerFactory frameHandlerFactory;
-    private final HashedWheelTimer hashedWheelTimer;
 
-    private ExecutionHandler eHandler;
-    
-    private ChannelUpstreamHandler coreHandler;
+    private ChannelInboundHandlerAdapter coreHandler;
 
     private int maxCurConnections;
 
     private int maxCurConnectionsPerIP;
    
-    private NettyServer(Protocol protocol, Encryption secure, ChannelHandlerFactory frameHandlerFactory, HashedWheelTimer hashedWheelTimer) {
+    private NettyServer(Protocol protocol, Encryption secure, ChannelHandlerFactory frameHandlerFactory) {
         this.protocol = protocol;
         this.secure = secure;
         this.frameHandlerFactory = frameHandlerFactory;
-        this.hashedWheelTimer = hashedWheelTimer;
     }
     
-    protected ChannelUpstreamHandler createCoreHandler() {
+    public void setMaxConcurrentConnections(int maxCurConnections) {
+        if (isBound()) {
+            throw new IllegalStateException("Server running already");
+        }
+        this.maxCurConnections = maxCurConnections;
+    }
+
+    public void setMaxConcurrentConnectionsPerIP(int maxCurConnectionsPerIP) {
+        if (isBound()) {
+            throw new IllegalStateException("Server running already");
+        }
+        this.maxCurConnectionsPerIP = maxCurConnectionsPerIP;
+    }
+
+    protected ChannelInboundHandlerAdapter createCoreHandler() {
         return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure);
     }
     
@@ -113,7 +118,7 @@ public class NettyServer extends AbstractAsyncServer {
     }
 
     @Override
-    protected ChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
 
         return new AbstractSSLAwareChannelPipelineFactory(
             getTimeout(),
@@ -121,12 +126,10 @@ public class NettyServer extends AbstractAsyncServer {
             maxCurConnectionsPerIP,
             group,
             secure,
-            eHandler,
-            getFrameHandlerFactory(),
-            hashedWheelTimer) {
+            getFrameHandlerFactory()) {
 
             @Override
-            protected ChannelUpstreamHandler createHandler() {
+            protected ChannelInboundHandlerAdapter createHandler() {
                 return coreHandler;
             }
         };
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java
index c308441..edb0b66 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java
@@ -27,7 +27,9 @@ import org.apache.james.core.Username;
 import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.util.MDCBuilder;
-import org.jboss.netty.channel.ChannelHandlerContext;
+
+import io.netty.channel.ChannelHandlerContext;
+
 
 public interface ProtocolMDCContextFactory {
     class Standard implements ProtocolMDCContextFactory {
@@ -54,7 +56,7 @@ public interface ProtocolMDCContextFactory {
     }
 
     private static String retrieveIp(ChannelHandlerContext ctx) {
-        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
             InetSocketAddress address = (InetSocketAddress) remoteAddress;
             return address.getAddress().getHostAddress();
@@ -63,7 +65,7 @@ public interface ProtocolMDCContextFactory {
     }
 
     private static String retrieveHost(ChannelHandlerContext ctx) {
-        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
             InetSocketAddress address = (InetSocketAddress) remoteAddress;
             return address.getHostName();
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/TimeoutHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/TimeoutHandler.java
index 46c1568..dbaed8c 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/TimeoutHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/TimeoutHandler.java
@@ -18,26 +18,27 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.timeout.IdleState;
-import org.jboss.netty.handler.timeout.IdleStateHandler;
-import org.jboss.netty.util.Timer;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.handler.timeout.IdleStateHandler;
 
 /**
  * {@link IdleStateHandler} implementation which disconnect the {@link Channel} after a configured
  * idle timeout. Be aware that this handle is not thread safe so it can't be shared across pipelines
  */
+@ChannelHandler.Sharable
 public class TimeoutHandler extends IdleStateHandler {
 
-    public TimeoutHandler(Timer timer, int readerIdleTimeSeconds) {
-        super(timer, readerIdleTimeSeconds, 0, 0);
+    public TimeoutHandler(int readerIdleTimeSeconds) {
+        super(readerIdleTimeSeconds, 0, 0);
     }
 
     @Override
-    protected void channelIdle(ChannelHandlerContext ctx, IdleState state, long lastActivityTimeMillis) throws Exception {
-        if (state.equals(IdleState.READER_IDLE)) {
-            ctx.getChannel().close();
+    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
+        if (evt.equals(IdleStateEvent.READER_IDLE_STATE_EVENT)) {
+            ctx.channel().close();
         }
     }
 
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
index 82e0ab1..6e8d2c5 100644
--- 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
@@ -26,33 +26,20 @@ import javax.net.ssl.SSLContext;
 
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.Protocol;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class NettyServerTest {
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    void teardown() {
-        hashedWheelTimer.stop();
-    }
-
     @Test
     void protocolShouldThrowWhenProtocolIsNull() {
-        assertThatThrownBy(() -> new NettyServer.Factory(hashedWheelTimer).protocol(null))
+        assertThatThrownBy(() -> new NettyServer.Factory().protocol(null))
             .isInstanceOf(NullPointerException.class);
     }
 
     @Test
     void buildShouldThrowWhenProtocolIsNotGiven() {
-        assertThatThrownBy(() -> new NettyServer.Factory(hashedWheelTimer)
+        assertThatThrownBy(() -> new NettyServer.Factory()
             .build())
             .isInstanceOf(IllegalStateException.class);
     }
@@ -60,7 +47,7 @@ class NettyServerTest {
     @Test
     void buildShouldWorkWhenProtocolIsGiven() {
         Protocol protocol = mock(Protocol.class);
-        new NettyServer.Factory(hashedWheelTimer)
+        new NettyServer.Factory()
             .protocol(protocol)
             .build();
     }
@@ -70,7 +57,7 @@ class NettyServerTest {
         Protocol protocol = mock(Protocol.class);
         Encryption encryption = Encryption.createStartTls(SSLContext.getDefault());
         ChannelHandlerFactory channelHandlerFactory = mock(ChannelHandlerFactory.class);
-        new NettyServer.Factory(hashedWheelTimer)
+        new NettyServer.Factory()
             .protocol(protocol)
             .secure(encryption)
             .frameHandlerFactory(channelHandlerFactory)
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CRLFTerminatedInputStream.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CRLFTerminatedInputStream.java
index 0f97d14..7d30383 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CRLFTerminatedInputStream.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CRLFTerminatedInputStream.java
@@ -54,13 +54,18 @@ public class CRLFTerminatedInputStream extends FilterInputStream {
 
                 return fillArray(b, off, len);
             } else {
-                // Make sure we respect the offset. Otherwise it could let the RETRCmdHandler
-                // hang forever. See JAMES-1222
-                last = b[off + r - 1];
-                if (off + r - 2 >= 0) {
-                    previousLast = b[off + r - 2];
+                if (r == 1) {
+                    previousLast = last;
+                    last = b[off + r - 1];
                 } else {
-                    previousLast = -1;
+                    // Make sure we respect the offset. Otherwise it could let the RETRCmdHandler
+                    // hang forever. See JAMES-1222
+                    last = b[off + r - 1];
+                    if (off + r - 2 >= 0) {
+                        previousLast = b[off + r - 2];
+                    } else {
+                        previousLast = -1;
+                    }
                 }
                 return r;
             }
diff --git a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/AbstractPOP3ServerTest.java b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/AbstractPOP3ServerTest.java
index a9b0212..a23cead 100644
--- a/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/AbstractPOP3ServerTest.java
+++ b/protocols/pop3/src/test/java/org/apache/james/protocols/pop3/AbstractPOP3ServerTest.java
@@ -463,7 +463,7 @@ public abstract class AbstractPOP3ServerTest {
             String welcomeMessage = client.getReplyString();
             
             // check for valid syntax that include all info needed for APOP
-            assertThat(welcomeMessage.trim()).matches(Pattern.compile("\\+OK \\<-?\\d+\\.\\d+@.+\\> .+"));
+            assertThat(welcomeMessage.trim()).matches(Pattern.compile("\\+OK \\<-?[0-9A-Fa-f]+\\.\\d+@.+\\> .+"));
             
             assertThat(client.sendCommand("APOP invalid invalid")).isEqualTo(POP3Reply.ERROR);
             
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 26e8e70..590381e 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
@@ -25,7 +25,6 @@ import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.netty.NettyServer;
 import org.apache.james.protocols.pop3.AbstractPOP3SServerTest;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 
@@ -33,21 +32,9 @@ public class NettyPOP3SServerTest extends AbstractPOP3SServerTest {
     private static final String LOCALHOST_IP = "127.0.0.1";
     private static final int RANDOM_PORT = 0;
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    public void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    public void teardown() {
-        hashedWheelTimer.stop();
-    }
-
     @Override
     protected ProtocolServer createEncryptedServer(Protocol protocol, Encryption enc) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .secure(enc)
                 .build();
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 4299e44..926e25f 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
@@ -24,30 +24,14 @@ import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.netty.NettyServer;
 import org.apache.james.protocols.pop3.AbstractPOP3ServerTest;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 
 public class NettyPOP3ServerTest extends AbstractPOP3ServerTest {
     private static final String LOCALHOST_IP = "127.0.0.1";
     private static final int RANDOM_PORT = 0;
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    public void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    public void teardown() {
-        hashedWheelTimer.stop();
-    }
-
-
     @Override
     protected ProtocolServer createServer(Protocol protocol) {
-        NettyServer server =  new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server =  new NettyServer.Factory()
                 .protocol(protocol)
                 .build();
         server.setListenAddresses(new InetSocketAddress(LOCALHOST_IP, RANDOM_PORT));
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 bd7e5d7..2bcbd72 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
@@ -25,28 +25,12 @@ import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.netty.NettyServer;
 import org.apache.james.protocols.pop3.AbstractStartTlsPOP3ServerTest;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 
 public class NettyStartTlsPOP3ServerTest extends AbstractStartTlsPOP3ServerTest {
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    public void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    public void teardown() {
-        hashedWheelTimer.stop();
-    }
-
-
     @Override
     protected ProtocolServer createServer(Protocol protocol, InetSocketAddress address, Encryption enc) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .secure(enc)
                 .build();
diff --git a/protocols/smtp/pom.xml b/protocols/smtp/pom.xml
index 4ad3b43..6810f4e 100644
--- a/protocols/smtp/pom.xml
+++ b/protocols/smtp/pom.xml
@@ -84,7 +84,7 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.inject</groupId>
diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java
index 38322da..37f6b2b 100644
--- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java
+++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java
@@ -28,7 +28,8 @@ import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.protocols.netty.ProtocolMDCContextFactory;
 import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.util.MDCBuilder;
-import org.jboss.netty.channel.ChannelHandlerContext;
+
+import io.netty.channel.ChannelHandlerContext;
 
 public class SMTPMDCContextFactory implements ProtocolMDCContextFactory {
 
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 0289b32..36eb453 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
@@ -25,9 +25,6 @@ import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.netty.NettyServer;
 import org.apache.james.protocols.smtp.AbstractSMTPSServerTest;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 
 /**
  * Integration tests which use netty implementation
@@ -39,21 +36,9 @@ public class NettySMTPSServerTest extends AbstractSMTPSServerTest {
     private static final String LOCALHOST_IP = "127.0.0.1";
     private static final int RANDOM_PORT = 0;
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    void teardown() {
-        hashedWheelTimer.stop();
-    }
-
     @Override
     protected ProtocolServer createEncryptedServer(Protocol protocol, Encryption enc) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .secure(enc)
                 .build();
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 d1bc8c5..25c63ed 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
@@ -24,7 +24,6 @@ import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.ProtocolServer;
 import org.apache.james.protocols.netty.NettyServer;
 import org.apache.james.protocols.smtp.AbstractSMTPServerTest;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 
@@ -38,22 +37,9 @@ public class NettySMTPServerTest extends AbstractSMTPServerTest {
     private static final String LOCALHOST_IP = "127.0.0.1";
     private static final int RANDOM_PORT = 0;
 
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
-
-    @AfterEach
-    void teardown() {
-        hashedWheelTimer.stop();
-    }
-
-
     @Override
     protected ProtocolServer createServer(Protocol protocol) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .build();
         server.setListenAddresses(new InetSocketAddress(LOCALHOST_IP, RANDOM_PORT));
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 a97528c..8cfaf77 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
@@ -52,9 +52,7 @@ 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.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import com.sun.mail.smtp.SMTPTransport;
@@ -66,12 +64,6 @@ public class NettyStartTlsSMTPServerTest {
 
     private SMTPSClient smtpsClient = null;
     private ProtocolServer server = null;
-    private HashedWheelTimer hashedWheelTimer;
-
-    @BeforeEach
-    void setup() {
-        hashedWheelTimer = new HashedWheelTimer();
-    }
 
     @AfterEach
     void tearDown() throws Exception {
@@ -81,11 +73,10 @@ public class NettyStartTlsSMTPServerTest {
         if (server != null) {
             server.unbind();
         }
-        hashedWheelTimer.stop();
     }
 
     private ProtocolServer createServer(Protocol protocol, Encryption enc) {
-        NettyServer server = new NettyServer.Factory(hashedWheelTimer)
+        NettyServer server = new NettyServer.Factory()
                 .protocol(protocol)
                 .secure(enc)
                 .frameHandlerFactory(new AllButStartTlsLineChannelHandlerFactory("starttls", AbstractChannelPipelineFactory.MAX_LINE_LENGTH))
diff --git a/server/blob/blob-s3/pom.xml b/server/blob/blob-s3/pom.xml
index 7440ade..e7a71c5 100644
--- a/server/blob/blob-s3/pom.xml
+++ b/server/blob/blob-s3/pom.xml
@@ -34,7 +34,6 @@
 
     <properties>
         <s3-sdk.version>2.17.107</s3-sdk.version>
-        <netty.version>4.1.72.Final</netty.version>
     </properties>
 
     <dependencies>
diff --git a/server/container/guice/common/src/main/java/org/apache/james/modules/protocols/ProtocolHandlerModule.java b/server/container/guice/common/src/main/java/org/apache/james/modules/protocols/ProtocolHandlerModule.java
index 51f5bf9..10d20d2 100644
--- a/server/container/guice/common/src/main/java/org/apache/james/modules/protocols/ProtocolHandlerModule.java
+++ b/server/container/guice/common/src/main/java/org/apache/james/modules/protocols/ProtocolHandlerModule.java
@@ -28,7 +28,6 @@ public class ProtocolHandlerModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        install(new NettyServerModule());
         bind(ProtocolHandlerLoader.class).to(GuiceProtocolHandlerLoader.class);
     }
 
diff --git a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
index e15d411..e8620d2 100644
--- a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
+++ b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
@@ -26,7 +26,6 @@ import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
 import org.apache.james.imapserver.netty.IMAPServerFactory;
-import org.apache.james.imapserver.netty.OioIMAPServerFactory;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.quota.QuotaManager;
@@ -49,7 +48,6 @@ public class IMAPServerModule extends AbstractModule {
     @Override
     protected void configure() {
         bind(IMAPServerFactory.class).in(Scopes.SINGLETON);
-        bind(OioIMAPServerFactory.class).in(Scopes.SINGLETON);
 
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(ImapGuiceProbe.class);
     }
diff --git a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
index 4d40003..f2a3308 100644
--- a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
+++ b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
@@ -20,7 +20,6 @@
 package org.apache.james.modules.protocols;
 
 import org.apache.james.lmtpserver.netty.LMTPServerFactory;
-import org.apache.james.lmtpserver.netty.OioLMTPServerFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.util.LoggingLevel;
 import org.apache.james.utils.GuiceProbe;
@@ -36,7 +35,6 @@ public class LMTPServerModule extends AbstractModule {
     @Override
     protected void configure() {
         bind(LMTPServerFactory.class).in(Scopes.SINGLETON);
-        bind(OioLMTPServerFactory.class).in(Scopes.SINGLETON);
 
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(LmtpGuiceProbe.class);
     }
diff --git a/server/container/guice/protocols/netty/src/main/java/org/apache/james/modules/protocols/NettyServerModule.java b/server/container/guice/protocols/netty/src/main/java/org/apache/james/modules/protocols/NettyServerModule.java
deleted file mode 100644
index 92a12e9..0000000
--- a/server/container/guice/protocols/netty/src/main/java/org/apache/james/modules/protocols/NettyServerModule.java
+++ /dev/null
@@ -1,45 +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.modules.protocols;
-
-import javax.annotation.PreDestroy;
-
-import org.jboss.netty.util.HashedWheelTimer;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.Singleton;
-
-public class NettyServerModule extends AbstractModule {
-
-    @Override
-    protected void configure() {
-        bind(HashedWheelTimer.class).to(DisposableHashedWheelTimer.class);
-    }
-
-    @Singleton
-    static class DisposableHashedWheelTimer extends HashedWheelTimer {
-
-        @PreDestroy
-        public void dispose() {
-            stop();
-        }
-    }
-
-}
diff --git a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
index a48bd64..98161a9 100644
--- a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
+++ b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
@@ -21,7 +21,6 @@ package org.apache.james.modules.protocols;
 
 import org.apache.james.pop3server.mailbox.DefaultMailboxAdapterFactory;
 import org.apache.james.pop3server.mailbox.MailboxAdapterFactory;
-import org.apache.james.pop3server.netty.OioPOP3ServerFactory;
 import org.apache.james.pop3server.netty.POP3ServerFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
@@ -37,7 +36,6 @@ public class POP3ServerModule extends AbstractModule {
     @Override
     protected void configure() {
         bind(POP3ServerFactory.class).in(Scopes.SINGLETON);
-        bind(OioPOP3ServerFactory.class).in(Scopes.SINGLETON);
         bind(DefaultMailboxAdapterFactory.class).in(Scopes.SINGLETON);
 
         bind(MailboxAdapterFactory.class).to(DefaultMailboxAdapterFactory.class);
diff --git a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
index 58b2e96..626d8b4 100644
--- a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
+++ b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
@@ -21,7 +21,6 @@ package org.apache.james.modules.protocols;
 
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.smtpserver.SendMailHandler;
-import org.apache.james.smtpserver.netty.OioSMTPServerFactory;
 import org.apache.james.smtpserver.netty.SMTPServerFactory;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
@@ -37,7 +36,6 @@ public class SMTPServerModule extends AbstractModule {
     protected void configure() {
         install(new JSPFModule());
         bind(SMTPServerFactory.class).in(Scopes.SINGLETON);
-        bind(OioSMTPServerFactory.class).in(Scopes.SINGLETON);
 
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SmtpGuiceProbe.class);
     }
diff --git a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
index 4d4168f..2e48c27 100644
--- a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
+++ b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
@@ -91,8 +91,6 @@
     ===========================================================================
     -->
 
-    <bean class="org.jboss.netty.util.HashedWheelTimer"/>
-
     <!-- SMTP Server -->
     <import resource="classpath:META-INF/spring/smtpserver-context.xml"/>
 
diff --git a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java
index cc02f54..703446c 100644
--- a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java
+++ b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java
@@ -549,7 +549,7 @@ class MockSMTPServerTest {
         assertThatThrownBy(() -> new SMTPMessageSender(DOMAIN)
                 .connect("localhost", port))
             .isInstanceOf(ConnectException.class)
-            .hasMessageContaining("(Connection refused)");
+            .hasMessageContaining("Connection refused");
     }
 
     @Test
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java
index b2cfa54..3937856 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.jmap.rfc8621.contract.custom.authentication.strategy;
 
+import static io.netty.handler.codec.http.HttpHeaders.Names.ACCEPT;
 import static io.restassured.RestAssured.given;
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
 import static org.apache.http.HttpStatus.SC_OK;
@@ -39,7 +40,6 @@ import static org.apache.james.jmap.rfc8621.contract.Fixture.USER_TOKEN;
 import static org.apache.james.jmap.rfc8621.contract.Fixture.getHeadersWith;
 import static org.apache.james.jmap.rfc8621.contract.Fixture.toBase64;
 import static org.hamcrest.Matchers.equalTo;
-import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.ACCEPT;
 
 import java.util.List;
 import java.util.Optional;
diff --git a/server/protocols/protocols-imap4/pom.xml b/server/protocols/protocols-imap4/pom.xml
index 1e56e4f..ad3c82b 100644
--- a/server/protocols/protocols-imap4/pom.xml
+++ b/server/protocols/protocols-imap4/pom.xml
@@ -119,6 +119,10 @@
             <artifactId>protocols-netty</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jzlib</artifactId>
+        </dependency>
+        <dependency>
             <groupId>commons-beanutils</groupId>
             <artifactId>commons-beanutils</artifactId>
             <scope>test</scope>
@@ -128,8 +132,13 @@
             <artifactId>commons-io</artifactId>
         </dependency>
         <dependency>
+            <groupId>io.github.hakky54</groupId>
+            <artifactId>sslcontext-kickstart-for-pem</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
index 38905ed..a3f6c6a 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
@@ -19,13 +19,14 @@
 package org.apache.james.imapserver.netty;
 
 import org.apache.james.imap.decode.ImapRequestLineReader;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
 
 public abstract class AbstractNettyImapRequestLineReader extends ImapRequestLineReader {
     private final Channel channel;
-    private final ChannelBuffer cRequest = ChannelBuffers.wrappedBuffer("+ Ok\r\n".getBytes());
+    private final ByteBuf cRequest = Unpooled.wrappedBuffer("+ Ok\r\n".getBytes());
     private final boolean retry;
 
     public AbstractNettyImapRequestLineReader(Channel channel, boolean retry) {
@@ -40,7 +41,7 @@ public abstract class AbstractNettyImapRequestLineReader extends ImapRequestLine
         // request..
 
         if (!retry) {
-            channel.write(cRequest);
+            channel.writeAndFlush(cRequest);
         }
     }
 
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ChannelImapResponseWriter.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ChannelImapResponseWriter.java
index 8d49b93..41e43b4 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ChannelImapResponseWriter.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ChannelImapResponseWriter.java
@@ -26,15 +26,15 @@ import java.nio.channels.FileChannel;
 
 import org.apache.james.imap.encode.ImapResponseWriter;
 import org.apache.james.imap.message.Literal;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.DefaultFileRegion;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.handler.codec.compression.ZlibEncoder;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.handler.stream.ChunkedNioFile;
-import org.jboss.netty.handler.stream.ChunkedStream;
+
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.DefaultFileRegion;
+import io.netty.handler.codec.compression.ZlibEncoder;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedNioFile;
+import io.netty.handler.stream.ChunkedStream;
 
 /**
  * {@link ImapResponseWriter} implementation which writes the data to a
@@ -56,28 +56,28 @@ public class ChannelImapResponseWriter implements ImapResponseWriter {
 
     @Override
     public void write(byte[] buffer) throws IOException {
-        if (channel.isConnected()) {
-            channel.write(ChannelBuffers.wrappedBuffer(buffer));
+        if (channel.isActive()) {
+            channel.writeAndFlush(Unpooled.wrappedBuffer(buffer));
         }
     }
 
     @Override
     public void write(Literal literal) throws IOException {
-        if (channel.isConnected()) {
+        if (channel.isActive()) {
             InputStream in = literal.getInputStream();
-            if (in instanceof FileInputStream && channel.getFactory() instanceof NioServerSocketChannelFactory) {
+            if (in instanceof FileInputStream) {
                 FileChannel fc = ((FileInputStream) in).getChannel();
                 // Zero-copy is only possible if no SSL/TLS  and no COMPRESS is in place
                 //
                 // See JAMES-1305 and JAMES-1306
-                ChannelPipeline cp = channel.getPipeline();
+                ChannelPipeline cp = channel.pipeline();
                 if (zeroCopy && cp.get(SslHandler.class) == null && cp.get(ZlibEncoder.class) == null) {
-                    channel.write(new DefaultFileRegion(fc, fc.position(), literal.size()));
+                    channel.writeAndFlush(new DefaultFileRegion(fc, fc.position(), literal.size()));
                 } else {
-                    channel.write(new ChunkedNioFile(fc, 8192));
+                    channel.writeAndFlush(new ChunkedNioFile(fc, 8192));
                 }
             } else {
-                channel.write(new ChunkedStream(literal.getInputStream()));
+                channel.writeAndFlush(new ChunkedStream(literal.getInputStream()));
             }
         }
     }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java
index 8e39371..136322d 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java
@@ -26,7 +26,8 @@ import java.util.Optional;
 import org.apache.james.core.Username;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.util.MDCBuilder;
-import org.jboss.netty.channel.ChannelHandlerContext;
+
+import io.netty.channel.ChannelHandlerContext;
 
 public class IMAPMDCContext {
 
@@ -38,7 +39,7 @@ public class IMAPMDCContext {
     }
 
     private static String retrieveIp(ChannelHandlerContext ctx) {
-        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
             InetSocketAddress address = (InetSocketAddress) remoteAddress;
             return address.getAddress().getHostAddress();
@@ -47,7 +48,7 @@ public class IMAPMDCContext {
     }
 
     private static String retrieveHost(ChannelHandlerContext ctx) {
-        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
             InetSocketAddress address = (InetSocketAddress) remoteAddress;
             return address.getHostName();
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 e58eab3..7896835 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
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.james.imapserver.netty;
 
-import static org.jboss.netty.channel.Channels.pipeline;
-
 import java.net.MalformedURLException;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
@@ -37,20 +35,12 @@ import org.apache.james.imap.encode.ImapEncoder;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
+import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelGroupHandler;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
 import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
 import org.apache.james.util.Size;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.handler.stream.ChunkedWriteHandler;
-import org.jboss.netty.handler.timeout.IdleStateHandler;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -58,11 +48,21 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableSet;
 
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedWriteHandler;
+import io.netty.handler.timeout.IdleStateHandler;
+
+
 /**
  * NIO IMAP Server which use Netty.
  */
 public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapConstants, IMAPServerMBean, NettyConstants {
     private static final Logger LOG = LoggerFactory.getLogger(IMAPServer.class);
+    private static final int TIMEOUT_TIMER_DISABLED = 0;
 
     public static class AuthenticationConfiguration {
         private static final boolean PLAIN_AUTH_DISALLOWED_DEFAULT = true;
@@ -209,21 +209,25 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
     }
 
     @Override
-    protected ChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
         
-        return new ChannelPipelineFactory() {
-            
+        return new AbstractChannelPipelineFactory(group, getFrameHandlerFactory()) {
+
+            @Override
+            protected ChannelInboundHandlerAdapter createHandler() {
+                return createCoreHandler();
+            }
+
             private final ChannelGroupHandler groupHandler = new ChannelGroupHandler(group);
-            private final HashedWheelTimer timer = new HashedWheelTimer();
-            
+
             private final TimeUnit timeoutUnit = TimeUnit.SECONDS;
 
             @Override
-            public ChannelPipeline getPipeline() throws Exception {
-                ChannelPipeline pipeline = pipeline();
+            public void initChannel(Channel channel) throws Exception {
+                ChannelPipeline pipeline = channel.pipeline();
                 pipeline.addLast(GROUP_HANDLER, groupHandler);
-                pipeline.addLast("idleHandler", new IdleStateHandler(timer, 0, 0, timeout, timeoutUnit));
-                pipeline.addLast(TIMEOUT_HANDLER, new ImapIdleStateHandler());
+                pipeline.addLast("idleHandler", new IdleStateHandler(TIMEOUT_TIMER_DISABLED, TIMEOUT_TIMER_DISABLED, timeout, timeoutUnit));
+                pipeline.addLast(TIMEOUT_HANDLER, new ImapIdleStateHandler(timeout));
                 pipeline.addLast(CONNECTION_LIMIT_HANDLER, new ConnectionLimitUpstreamHandler(IMAPServer.this.connectionLimit));
 
                 pipeline.addLast(CONNECTION_LIMIT_PER_IP_HANDLER, new ConnectionPerIpLimitUpstreamHandler(IMAPServer.this.connPerIP));
@@ -246,15 +250,9 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
 
                 pipeline.addLast(CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
 
-                ExecutionHandler ehandler = getExecutionHandler();
-                if (ehandler  != null) {
-                    pipeline.addLast(EXECUTION_HANDLER, ehandler);
-
-                }
                 pipeline.addLast(REQUEST_DECODER, new ImapRequestFrameDecoder(decoder, inMemorySizeLimit, literalSizeLimit));
 
-                pipeline.addLast(CORE_HANDLER, createCoreHandler());
-                return pipeline;
+                pipeline.addLast(CORE_HANDLER, createHandler());
             }
 
         };
@@ -266,7 +264,7 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
     }
 
     @Override
-    protected ChannelUpstreamHandler createCoreHandler() {
+    protected ChannelInboundHandlerAdapter createCoreHandler() {
         Encryption secure = getEncryption();
         ImapChannelUpstreamHandler.ImapChannelUpstreamHandlerBuilder coreHandlerBuilder = ImapChannelUpstreamHandler.builder()
             .hello(hello)
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java
index 2b4874b..e7046b2 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java
@@ -32,7 +32,6 @@ import org.apache.james.imap.encode.ImapEncoder;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.lib.netty.AbstractServerFactory;
-import org.jboss.netty.util.HashedWheelTimer;
 
 public class IMAPServerFactory extends AbstractServerFactory {
 
@@ -41,17 +40,15 @@ public class IMAPServerFactory extends AbstractServerFactory {
     protected final ImapEncoder encoder;
     protected final ImapProcessor processor;
     protected final ImapMetrics imapMetrics;
-    private final HashedWheelTimer hashedWheelTimer;
 
     @Inject
     public IMAPServerFactory(FileSystem fileSystem, ImapDecoder decoder, ImapEncoder encoder, ImapProcessor processor,
-                             MetricFactory metricFactory, HashedWheelTimer hashedWheelTimer) {
+                             MetricFactory metricFactory) {
         this.fileSystem = fileSystem;
         this.decoder = decoder;
         this.encoder = encoder;
         this.processor = processor;
         this.imapMetrics = new ImapMetrics(metricFactory);
-        this.hashedWheelTimer = hashedWheelTimer;
     }
 
     protected IMAPServer createServer() {
@@ -67,7 +64,6 @@ public class IMAPServerFactory extends AbstractServerFactory {
         for (HierarchicalConfiguration<ImmutableNode> serverConfig: configs) {
             IMAPServer server = createServer();
             server.setFileSystem(fileSystem);
-            server.setHashWheelTimer(hashedWheelTimer);
             server.configure(serverConfig);
             servers.add(server);
         }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java
index 1f87867..c264e11 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java
@@ -39,23 +39,23 @@ import org.apache.james.imap.main.ResponseEncoder;
 import org.apache.james.metrics.api.Metric;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.util.MDCBuilder;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFutureListener;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.frame.TooLongFrameException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelPipeline;
+import io.netty.handler.codec.TooLongFrameException;
+
 /**
- * {@link SimpleChannelUpstreamHandler} which handles IMAP
+ * {@link ChannelInboundHandlerAdapter} which handles IMAP
  */
-public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler implements NettyConstants {
+@ChannelHandler.Sharable
+public class ImapChannelUpstreamHandler extends ChannelInboundHandlerAdapter implements NettyConstants {
     private static final Logger LOGGER = LoggerFactory.getLogger(ImapChannelUpstreamHandler.class);
     public static final String MDC_KEY = "bound_MDC";
 
@@ -122,7 +122,7 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
 
     private final ImapEncoder encoder;
 
-    private final ImapHeartbeatHandler heartbeatHandler = new ImapHeartbeatHandler();
+    private final ImapHeartbeatHandler heartbeatHandler = new ImapHeartbeatHandler(0,0,0);
 
     private final AuthenticationConfiguration authenticationConfiguration;
 
@@ -143,20 +143,30 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
     }
 
     @Override
-    public void channelBound(final ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        ImapSession imapsession = new NettyImapSession(ctx.getChannel(), secure, compress, authenticationConfiguration.isSSLRequired(),
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ImapSession imapsession = new NettyImapSession(ctx.channel(), secure, compress, authenticationConfiguration.isSSLRequired(),
             authenticationConfiguration.isPlainAuthEnabled(), SessionId.generate(),
             authenticationConfiguration.getOidcSASLConfiguration());
         MDCBuilder boundMDC = IMAPMDCContext.boundMDC(ctx);
         imapsession.setAttribute(MDC_KEY, boundMDC);
-        attributes.set(ctx.getChannel(), imapsession);
+        ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).set(imapsession);
         try (Closeable closeable = boundMDC.build()) {
-            super.channelBound(ctx, e);
+            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
+            LOGGER.info("Connection established from {}", address.getAddress().getHostAddress());
+            imapConnectionsMetric.increment();
+
+            ImapResponseComposer response = new ImapResponseComposerImpl(new ChannelImapResponseWriter(ctx.channel()));
+            ctx.channel().attr(CONTEXT_ATTACHMENT_ATTRIBUTE_KEY).set(response);
+
+            // write hello to client
+            response.untagged().message("OK").message(hello).end();
+            super.channelActive(ctx);
         }
+
     }
 
     private MDCBuilder mdc(ChannelHandlerContext ctx) {
-        ImapSession maybeSession = (ImapSession) attributes.get(ctx.getChannel());
+        ImapSession maybeSession = ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).get();
 
         return Optional.ofNullable(maybeSession)
             .map(session -> {
@@ -169,45 +179,29 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
     }
 
     @Override
-    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         try (Closeable closeable = mdc(ctx).build()) {
-            InetSocketAddress address = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
+            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
             LOGGER.info("Connection closed for {}", address.getAddress().getHostAddress());
 
             // remove the stored attribute for the channel to free up resources
             // See JAMES-1195
-            ImapSession imapSession = (ImapSession) attributes.remove(ctx.getChannel());
+            ImapSession imapSession = ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).getAndSet(null);
             if (imapSession != null) {
                 imapSession.logout();
             }
             imapConnectionsMetric.decrement();
 
-            super.channelClosed(ctx, e);
-        }
-    }
-
-    @Override
-    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        try (Closeable closeable = mdc(ctx).build()) {
-            InetSocketAddress address = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
-            LOGGER.info("Connection established from {}", address.getAddress().getHostAddress());
-            imapConnectionsMetric.increment();
-
-            ImapResponseComposer response = new ImapResponseComposerImpl(new ChannelImapResponseWriter(ctx.getChannel()));
-            ctx.setAttachment(response);
-
-            // write hello to client
-            response.untagged().message("OK").message(hello).end();
-            super.channelConnected(ctx, e);
+            super.channelInactive(ctx);
         }
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
         try (Closeable closeable = mdc(ctx).build()) {
-            LOGGER.warn("Error while processing imap request", e.getCause());
+            LOGGER.warn("Error while processing imap request", cause);
 
-            if (e.getCause() instanceof TooLongFrameException) {
+            if (cause instanceof TooLongFrameException) {
 
                 // Max line length exceeded
                 // See RFC 2683 section 3.2.1
@@ -223,21 +217,21 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
                 // command length."
                 //
                 // See also JAMES-1190
-                ImapResponseComposer composer = (ImapResponseComposer) ctx.getAttachment();
+                ImapResponseComposer composer = (ImapResponseComposer) ctx.channel().attr(CONTEXT_ATTACHMENT_ATTRIBUTE_KEY).get();
                 composer.untaggedResponse(ImapConstants.BAD + " failed. Maximum command line length exceeded");
 
             } else {
 
                 // logout on error not sure if that is the best way to handle it
-                final ImapSession imapSession = (ImapSession) attributes.get(ctx.getChannel());
+                final ImapSession imapSession = ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).get();
                 if (imapSession != null) {
                     imapSession.logout();
                 }
 
                 // Make sure we close the channel after all the buffers were flushed out
-                Channel channel = ctx.getChannel();
-                if (channel.isConnected()) {
-                    channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
+                Channel channel = ctx.channel();
+                if (channel.isActive()) {
+                    channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
                 }
 
             }
@@ -245,13 +239,13 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
     }
 
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throws Exception {
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         try (Closeable closeable = mdc(ctx).build()) {
             imapCommandsMetric.increment();
-            ImapSession session = (ImapSession) attributes.get(ctx.getChannel());
-            ImapResponseComposer response = (ImapResponseComposer) ctx.getAttachment();
-            ImapMessage message = (ImapMessage) event.getMessage();
-            ChannelPipeline cp = ctx.getPipeline();
+            ImapSession session = ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).get();
+            ImapResponseComposer response = (ImapResponseComposer) ctx.channel().attr(CONTEXT_ATTACHMENT_ATTRIBUTE_KEY).get();
+            ImapMessage message = (ImapMessage) msg;
+            ChannelPipeline cp = ctx.pipeline();
 
             try {
                 try {
@@ -268,9 +262,9 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
 
                 if (session.getState() == ImapSessionState.LOGOUT) {
                     // Make sure we close the channel after all the buffers were flushed out
-                    Channel channel = ctx.getChannel();
-                    if (channel.isConnected()) {
-                        channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
+                    Channel channel = ctx.channel();
+                    if (channel.isActive()) {
+                        channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
                     }
                 }
                 final IOException failure = responseEncoder.getFailure();
@@ -282,7 +276,7 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
                 }
             } finally {
                 try {
-                    ctx.getPipeline().remove(NettyConstants.HEARTBEAT_HANDLER);
+                    ctx.pipeline().remove(NettyConstants.HEARTBEAT_HANDLER);
                 } catch (NoSuchElementException e) {
                     LOGGER.info("Heartbeat handler was concurrently removed");
                 }
@@ -291,7 +285,7 @@ public class ImapChannelUpstreamHandler extends SimpleChannelUpstreamHandler imp
                 }
             }
 
-            super.messageReceived(ctx, event);
+            super.channelReadComplete(ctx);
         }
     }
 
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java
index 4d05da2..0bfa67f 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapHeartbeatHandler.java
@@ -20,23 +20,27 @@ package org.apache.james.imapserver.netty;
 
 import java.nio.charset.StandardCharsets;
 
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.timeout.IdleState;
-import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
-import org.jboss.netty.handler.timeout.IdleStateEvent;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.handler.timeout.IdleStateHandler;
 
-public class ImapHeartbeatHandler extends IdleStateAwareChannelHandler {
+@ChannelHandler.Sharable
+public class ImapHeartbeatHandler extends IdleStateHandler {
 
-    private static final ChannelBuffer HEARTBEAT_BUFFER = ChannelBuffers
-        .unmodifiableBuffer(
-            ChannelBuffers.wrappedBuffer("* OK Hang in there..\r\n".getBytes(StandardCharsets.US_ASCII)));
+    private static final ByteBuf HEARTBEAT_BUFFER = Unpooled.wrappedUnmodifiableBuffer(Unpooled.wrappedBuffer("* OK Hang in there..\r\n".getBytes(StandardCharsets.US_ASCII)));
+
+    ImapHeartbeatHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {
+        super(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds);
+    }
 
     @Override
     public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
-        if (e.getState().equals(IdleState.WRITER_IDLE)) {
-            e.getChannel().write(HEARTBEAT_BUFFER);
+        if (e.state().equals(IdleState.WRITER_IDLE)) {
+            ctx.channel().writeAndFlush(HEARTBEAT_BUFFER);
         }
         super.channelIdle(ctx, e);
     }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapIdleStateHandler.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapIdleStateHandler.java
index f0d2b4a..b964e08 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapIdleStateHandler.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapIdleStateHandler.java
@@ -21,27 +21,38 @@ package org.apache.james.imapserver.netty;
 import java.net.InetSocketAddress;
 
 import org.apache.james.imap.api.process.ImapSession;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.timeout.IdleState;
-import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
-import org.jboss.netty.handler.timeout.IdleStateEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.handler.timeout.IdleStateHandler;
+
 /**
- * {@link IdleStateAwareChannelHandler} which will call {@link ImapSession#logout()} if the
+ * {@link IdleStateHandler} which will call {@link ImapSession#logout()} if the
  * connected client did not receive or send any traffic in a given timeframe.
  */
-public class ImapIdleStateHandler extends IdleStateAwareChannelHandler implements NettyConstants {
+@ChannelHandler.Sharable
+public class ImapIdleStateHandler extends IdleStateHandler implements NettyConstants {
     private static final Logger LOGGER = LoggerFactory.getLogger(ImapIdleStateHandler.class);
 
+    public ImapIdleStateHandler(int allIdleTimeSeconds) {
+        this(0, 0, allIdleTimeSeconds);
+    }
+
+    public ImapIdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {
+        super(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds);
+    }
+
     @Override
     public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
 
         // check if the client did nothing for too long
-        if (e.getState().equals(IdleState.ALL_IDLE)) {
-            ImapSession session = (ImapSession) attributes.get(ctx.getChannel());
-            InetSocketAddress address = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
+        if (e.state().equals(IdleState.ALL_IDLE)) {
+            ImapSession session = ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).get();
+            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
 
             LOGGER.info("Logout client {} ({}) because it idled for too long...",
                 address.getHostName(),
@@ -51,7 +62,7 @@ public class ImapIdleStateHandler extends IdleStateAwareChannelHandler implement
             session.logout();
 
             // close the channel
-            ctx.getChannel().close();
+            ctx.channel().close();
 
         }
         
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
index 67f4476..82f1ac6 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
@@ -20,18 +20,20 @@ package org.apache.james.imapserver.netty;
 
 import org.apache.james.imap.api.process.ImapLineHandler;
 import org.apache.james.imap.api.process.ImapSession;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
 
 /**
- * {@link SimpleChannelUpstreamHandler} implementation which will delegate the
+ * {@link ChannelInboundHandlerAdapter} implementation which will delegate the
  * data received on
- * {@link #messageReceived(ChannelHandlerContext, MessageEvent)} to a
+ * {@link #channelRead(ChannelHandlerContext, Object)} to a
  * {@link ImapLineHandler#onLine(ImapSession, byte[])}
  */
-public class ImapLineHandlerAdapter extends SimpleChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public class ImapLineHandlerAdapter extends ChannelInboundHandlerAdapter {
 
     private final ImapLineHandler lineHandler;
     private final ImapSession session;
@@ -42,8 +44,8 @@ public class ImapLineHandlerAdapter extends SimpleChannelUpstreamHandler {
     }
 
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        ChannelBuffer buf = (ChannelBuffer) e.getMessage();
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf buf = (ByteBuf) msg;
         byte[] data;
         if (buf.hasArray()) {
             data = buf.array();
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
index 6dbec4d..696e54f 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
@@ -24,6 +24,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.james.imap.api.ImapMessage;
@@ -31,21 +32,21 @@ import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.decode.ImapDecoder;
 import org.apache.james.imap.decode.ImapRequestLineReader;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFutureListener;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.handler.codec.frame.FrameDecoder;
 
 import com.google.common.annotations.VisibleForTesting;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPipeline;
+import io.netty.handler.codec.ByteToMessageDecoder;
+
+
 /**
- * {@link FrameDecoder} which will decode via and {@link ImapDecoder} instance
+ * {@link ByteToMessageDecoder} which will decode via and {@link ImapDecoder} instance
  */
-public class ImapRequestFrameDecoder extends FrameDecoder implements NettyConstants {
+public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements NettyConstants {
 
     private final ImapDecoder decoder;
     private final int inMemorySizeLimit;
@@ -63,27 +64,27 @@ public class ImapRequestFrameDecoder extends FrameDecoder implements NettyConsta
     }
 
     @Override
-    public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        ctx.setAttachment(new HashMap<String, Object>());
-        super.channelOpen(ctx, e);
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.channel().attr(FRAME_DECODE_ATTACHMENT_ATTRIBUTE_KEY).set(new HashMap<>());
+        super.channelActive(ctx);
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
-        buffer.markReaderIndex();
+    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+        in.markReaderIndex();
         boolean retry = false;
 
         ImapRequestLineReader reader;
         // check if we failed before and if we already know how much data we
         // need to sucess next run
-        Map<String, Object> attachment = (Map<String, Object>) ctx.getAttachment();
+        Map<String, Object> attachment = ctx.channel().attr(FRAME_DECODE_ATTACHMENT_ATTRIBUTE_KEY).get();
         int size = -1;
         if (attachment.containsKey(NEEDED_DATA)) {
             retry = true;
             size = (Integer) attachment.get(NEEDED_DATA);
             // now see if the buffer hold enough data to process.
-            if (size != NettyImapRequestLineReader.NotEnoughDataException.UNKNOWN_SIZE && size > buffer.readableBytes()) {
+            if (size != NettyImapRequestLineReader.NotEnoughDataException.UNKNOWN_SIZE && size > in.readableBytes()) {
 
                 // check if we have a inMemorySize limit and if so if the
                 // expected size will fit into it
@@ -94,31 +95,31 @@ public class ImapRequestFrameDecoder extends FrameDecoder implements NettyConsta
                     final File f;
                     int written;
 
-                    OutputStream out;
+                    OutputStream outputStream;
                     // check if we have created a temporary file already or if
                     // we need to create a new one
                     if (attachment.containsKey(STORED_DATA)) {
                         f = (File) attachment.get(STORED_DATA);
                         written = (Integer) attachment.get(WRITTEN_DATA);
-                        out = (OutputStream) attachment.get(OUTPUT_STREAM);
+                        outputStream = (OutputStream) attachment.get(OUTPUT_STREAM);
                     } else {
                         f = File.createTempFile("imap-literal", ".tmp");
                         attachment.put(STORED_DATA, f);
                         written = 0;
                         attachment.put(WRITTEN_DATA, written);
-                        out = new FileOutputStream(f, true);
-                        attachment.put(OUTPUT_STREAM, out);
+                        outputStream = new FileOutputStream(f, true);
+                        attachment.put(OUTPUT_STREAM, outputStream);
 
                     }
 
 
                     try {
-                        int amount = Math.min(buffer.readableBytes(), size - written);
-                        buffer.readBytes(out, amount);
+                        int amount = Math.min(in.readableBytes(), size - written);
+                        in.readBytes(outputStream, amount);
                         written += amount;
                     } catch (Exception e) {
                         try {
-                            out.close();
+                            outputStream.close();
                         } catch (IOException ignored) {
                             //ignore exception during close
                         }
@@ -127,31 +128,31 @@ public class ImapRequestFrameDecoder extends FrameDecoder implements NettyConsta
                     // Check if all needed data was streamed to the file.
                     if (written == size) {
                         try {
-                            out.close();
+                            outputStream.close();
                         } catch (IOException ignored) {
                             //ignore exception during close
                         }
 
-                        reader = new NettyStreamImapRequestLineReader(channel, f, retry);
+                        reader = new NettyStreamImapRequestLineReader(ctx.channel(), f, retry);
                     } else {
                         attachment.put(WRITTEN_DATA, written);
-                        return null;
+                        return;
                     }
 
                 } else {
-                    buffer.resetReaderIndex();
-                    return null;
+                    in.resetReaderIndex();
+                    return;
                 }
 
             } else {
 
-                reader = new NettyImapRequestLineReader(channel, buffer, retry, literalSizeLimit);
+                reader = new NettyImapRequestLineReader(ctx.channel(), in, retry, literalSizeLimit);
             }
         } else {
-            reader = new NettyImapRequestLineReader(channel, buffer, retry, literalSizeLimit);
+            reader = new NettyImapRequestLineReader(ctx.channel(), in, retry, literalSizeLimit);
         }
 
-        ImapSession session = (ImapSession) attributes.get(channel);
+        ImapSession session = ctx.channel().attr(IMAP_SESSION_ATTRIBUTE_KEY).get();
 
         // check if the session was removed before to prevent a harmless NPE. See JAMES-1312
         // Also check if the session was logged out if so there is not need to try to decode it. See JAMES-1341
@@ -167,10 +168,10 @@ public class ImapRequestFrameDecoder extends FrameDecoder implements NettyConsta
                     reader.consumeLine();
                 }
                 
-                ((SwitchableLineBasedFrameDecoder) channel.getPipeline().get(FRAMER)).enableFraming();
+                ((SwitchableLineBasedFrameDecoder) ctx.channel().pipeline().get(FRAMER)).enableFraming();
                 
                 attachment.clear();
-                return message;
+                out.add(message);
             } catch (NettyImapRequestLineReader.NotEnoughDataException e) {
                 // this exception was thrown because we don't have enough data
                 // yet
@@ -178,42 +179,21 @@ public class ImapRequestFrameDecoder extends FrameDecoder implements NettyConsta
                 // store the needed data size for later usage
                 attachment.put(NEEDED_DATA, neededData);
                 
-                final ChannelPipeline pipeline = channel.getPipeline();
-                final ChannelHandlerContext framerContext = pipeline.getContext(FRAMER);
+                final ChannelPipeline pipeline = ctx.channel().pipeline();
+                final ChannelHandlerContext framerContext = pipeline.context(FRAMER);
 
                 // SwitchableDelimiterBasedFrameDecoder added further to JAMES-1436.
                 final SwitchableLineBasedFrameDecoder framer = (SwitchableLineBasedFrameDecoder) pipeline.get(FRAMER);
+
+                in.resetReaderIndex();
                 framer.disableFraming(framerContext);
-                
-                buffer.resetReaderIndex();
-                return null;
             }
         } else {
             // The session was null so may be the case because the channel was already closed but there were still bytes in the buffer.
             // We now try to disconnect the client if still connected
-            if (channel.isConnected()) {
-                channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
-            }
-            return null;
-        }
-    }
-
-    @Override
-    protected synchronized ChannelBuffer newCumulationBuffer(ChannelHandlerContext ctx, int minimumCapacity) {
-        Map<String, Object> attachment = (Map<String, Object>) ctx.getAttachment();
-        Object sizeAsObject = attachment.get(NEEDED_DATA);
-        if (sizeAsObject != null) {
-            @SuppressWarnings("unchecked")
-            int size = (Integer) sizeAsObject;
-
-            if (size > 0) {
-                int sanitizedInMemorySizeLimit = Math.max(0, inMemorySizeLimit);
-                int sanitizedSize = Math.min(sanitizedInMemorySizeLimit, size);
-
-                return ChannelBuffers.dynamicBuffer(sanitizedSize, ctx.getChannel().getConfig().getBufferFactory());
+            if (ctx.channel().isActive()) {
+                ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
             }
         }
-        return super.newCumulationBuffer(ctx, minimumCapacity);
     }
-
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
index c8c23bb..4733fb4 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
@@ -18,7 +18,12 @@
  ****************************************************************/
 package org.apache.james.imapserver.netty;
 
-import org.jboss.netty.channel.ChannelLocal;
+import java.util.Map;
+
+import org.apache.james.imap.api.process.ImapSession;
+
+import io.netty.util.AttributeKey;
+
 
 /**
  * Just some constants which are used with the Netty implementation
@@ -39,5 +44,8 @@ public interface NettyConstants {
     String EXECUTION_HANDLER = "executionHandler";
     String HEARTBEAT_HANDLER = "heartbeatHandler";
 
-    ChannelLocal<Object> attributes = new ChannelLocal<>();
+    AttributeKey<ImapSession> IMAP_SESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("ImapSession");
+    AttributeKey<Object> CONTEXT_ATTACHMENT_ATTRIBUTE_KEY = AttributeKey.valueOf("ContextAttachment");
+    AttributeKey<Map<String, Object>> FRAME_DECODE_ATTACHMENT_ATTRIBUTE_KEY  = AttributeKey.valueOf("FrameDecoderMap");
+
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapRequestLineReader.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapRequestLineReader.java
index 8cfed94..ea66a6f 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapRequestLineReader.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapRequestLineReader.java
@@ -29,23 +29,24 @@ import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.message.BytesBackedLiteral;
 import org.apache.james.imap.message.Literal;
 import org.apache.james.imap.utils.EolInputStream;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
-import org.jboss.netty.channel.Channel;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.channel.Channel;
 
 /**
  * {@link ImapRequestLineReader} implementation which will write to a
- * {@link Channel} and read from a {@link ChannelBuffer}. Please see the docs on
+ * {@link Channel} and read from a {@link ByteBuf}. Please see the docs on
  * {@link #nextChar()} and {@link #read(int, boolean)} to understand the special behavior
  * of this implementation
  */
 public class NettyImapRequestLineReader extends AbstractNettyImapRequestLineReader {
 
-    private final ChannelBuffer buffer;
+    private final ByteBuf buffer;
     private int read = 0;
     private final int maxLiteralSize;
 
-    public NettyImapRequestLineReader(Channel channel, ChannelBuffer buffer, boolean retry, int maxLiteralSize) {
+    public NettyImapRequestLineReader(Channel channel, ByteBuf buffer, boolean retry, int maxLiteralSize) {
         super(channel, retry);
         this.buffer = buffer;
         this.maxLiteralSize  = maxLiteralSize;
@@ -57,7 +58,7 @@ public class NettyImapRequestLineReader extends AbstractNettyImapRequestLineRead
      * call till {@link #consume()} was called.
      * 
      * This implementation will throw a {@link NotEnoughDataException} if the
-     * wrapped {@link ChannelBuffer} contains not enough data to read the next
+     * wrapped {@link ByteBuf} contains not enough data to read the next
      * char
      */
     @Override
@@ -65,7 +66,7 @@ public class NettyImapRequestLineReader extends AbstractNettyImapRequestLineRead
         if (!nextSeen) {
             int next;
 
-            if (buffer.readable()) {
+            if (buffer.isReadable()) {
                 next = buffer.readByte();
                 read++;
             } else {
@@ -78,8 +79,8 @@ public class NettyImapRequestLineReader extends AbstractNettyImapRequestLineRead
     }
 
     /**
-     * Return a {@link ChannelBufferInputStream} if the wrapped
-     * {@link ChannelBuffer} contains enough data. If not it will throw a
+     * Return a {@link ByteBufInputStream} if the wrapped
+     * {@link ByteBuf} contains enough data. If not it will throw a
      * {@link NotEnoughDataException}
      */
     @Override
@@ -105,8 +106,8 @@ public class NettyImapRequestLineReader extends AbstractNettyImapRequestLineRead
 
 
         try {
-            // limit the size via commons-io as ChannelBufferInputStream size limiting is buggy
-            InputStream in = new BoundedInputStream(new ChannelBufferInputStream(buffer), size);
+            // limit the size via commons-io as ByteBufInputStream size limiting is buggy
+            InputStream in = new BoundedInputStream(new ByteBufInputStream(buffer), size);
             if (extraCRLF) {
                 return BytesBackedLiteral.copy(new EolInputStream(this, in));
             } else {
@@ -121,7 +122,7 @@ public class NettyImapRequestLineReader extends AbstractNettyImapRequestLineRead
      * {@link RuntimeException} which will get thrown by
      * {@link NettyImapRequestLineReader#nextChar()} and
      * {@link NettyImapRequestLineReader#read(int, boolean)} if not enough data is
-     * readable in the underlying {@link ChannelBuffer}
+     * readable in the underlying {@link ByteBuf}
      */
     public static final class NotEnoughDataException extends RuntimeException {
 
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index b582066..a70a8a6 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -28,11 +28,14 @@ import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.handler.codec.compression.ZlibDecoder;
-import org.jboss.netty.handler.codec.compression.ZlibEncoder;
-import org.jboss.netty.handler.codec.compression.ZlibWrapper;
-import org.jboss.netty.handler.ssl.SslHandler;
+
+import io.netty.channel.Channel;
+import io.netty.handler.codec.compression.JZlibDecoder;
+import io.netty.handler.codec.compression.JZlibEncoder;
+import io.netty.handler.codec.compression.ZlibDecoder;
+import io.netty.handler.codec.compression.ZlibEncoder;
+import io.netty.handler.codec.compression.ZlibWrapper;
+import io.netty.handler.ssl.SslHandler;
 
 public class NettyImapSession implements ImapSession, NettyConstants {
     private ImapSessionState state = ImapSessionState.NON_AUTHENTICATED;
@@ -142,13 +145,13 @@ public class NettyImapSession implements ImapSession, NettyConstants {
         if (!supportStartTLS()) {
             return false;
         }
-        channel.setReadable(false);
+        channel.config().setAutoRead(false);
 
         SslHandler filter = new SslHandler(secure.createSSLEngine(), false);
-        filter.getEngine().setUseClientMode(false);
-        channel.getPipeline().addFirst(SSL_HANDLER, filter);
+        filter.engine().setUseClientMode(false);
+        channel.pipeline().addFirst(SSL_HANDLER, filter);
 
-        channel.setReadable(true);
+        channel.config().setAutoRead(true);
 
         return true;
     }
@@ -169,39 +172,39 @@ public class NettyImapSession implements ImapSession, NettyConstants {
             return false;
         }
 
-        channel.setReadable(false);
-        ZlibDecoder decoder = new ZlibDecoder(ZlibWrapper.NONE);
-        ZlibEncoder encoder = new ZlibEncoder(ZlibWrapper.NONE, 5);
+        channel.config().setAutoRead(false);
+        ZlibDecoder decoder = new JZlibDecoder(ZlibWrapper.NONE);
+        ZlibEncoder encoder = new JZlibEncoder(ZlibWrapper.NONE, 5);
 
         // Check if we have the SslHandler in the pipeline already
         // if so we need to move the compress encoder and decoder
         // behind it in the chain
         // See JAMES-1186
-        if (channel.getPipeline().get(SSL_HANDLER) == null) {
-            channel.getPipeline().addFirst(ZLIB_DECODER, decoder);
-            channel.getPipeline().addFirst(ZLIB_ENCODER, encoder);
+        if (channel.pipeline().get(SSL_HANDLER) == null) {
+            channel.pipeline().addFirst(ZLIB_DECODER, decoder);
+            channel.pipeline().addFirst(ZLIB_ENCODER, encoder);
         } else {
-            channel.getPipeline().addAfter(SSL_HANDLER, ZLIB_DECODER, decoder);
-            channel.getPipeline().addAfter(SSL_HANDLER, ZLIB_ENCODER, encoder);
+            channel.pipeline().addAfter(SSL_HANDLER, ZLIB_DECODER, decoder);
+            channel.pipeline().addAfter(SSL_HANDLER, ZLIB_ENCODER, encoder);
         }
 
-        channel.setReadable(true);
+        channel.config().setAutoRead(true);
 
         return true;
     }
 
     @Override
     public void pushLineHandler(ImapLineHandler lineHandler) {
-        channel.setReadable(false);
-        channel.getPipeline().addBefore(REQUEST_DECODER, "lineHandler" + handlerCount++, new ImapLineHandlerAdapter(this, lineHandler));
-        channel.setReadable(true);
+        channel.config().setAutoRead(false);
+        channel.pipeline().addBefore(REQUEST_DECODER, "lineHandler" + handlerCount++, new ImapLineHandlerAdapter(this, lineHandler));
+        channel.config().setAutoRead(true);
     }
 
     @Override
     public void popLineHandler() {
-        channel.setReadable(false);
-        channel.getPipeline().remove("lineHandler" + --handlerCount);
-        channel.setReadable(true);
+        channel.config().setAutoRead(false);
+        channel.pipeline().remove("lineHandler" + --handlerCount);
+        channel.config().setAutoRead(true);
     }
 
     @Override
@@ -226,7 +229,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
 
     @Override
     public boolean isTLSActive() {
-        return channel.getPipeline().get(SSL_HANDLER) != null;
+        return channel.pipeline().get(SSL_HANDLER) != null;
     }
 
     @Override
@@ -236,7 +239,7 @@ public class NettyImapSession implements ImapSession, NettyConstants {
 
     @Override
     public boolean isCompressionActive() {
-        return channel.getPipeline().get(ZLIB_DECODER) != null;
+        return channel.pipeline().get(ZLIB_DECODER) != null;
     }
 
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java
index bb5c37e..57069c7 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java
@@ -29,11 +29,12 @@ import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.decode.DecodingException;
 import org.apache.james.imap.message.Literal;
 import org.apache.james.imap.utils.EolInputStream;
-import org.jboss.netty.channel.Channel;
 
 import com.google.common.io.ByteStreams;
 import com.google.common.io.CountingInputStream;
 
+import io.netty.channel.Channel;
+
 public class NettyStreamImapRequestLineReader extends AbstractNettyImapRequestLineReader implements Closeable {
     private class FileLiteral implements Literal, Closeable {
         private final long offset;
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServer.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServer.java
deleted file mode 100644
index 4bc8d7a..0000000
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServer.java
+++ /dev/null
@@ -1,51 +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.imapserver.netty;
-
-import org.apache.james.imap.api.process.ImapProcessor;
-import org.apache.james.imap.decode.ImapDecoder;
-import org.apache.james.imap.encode.ImapEncoder;
-import org.jboss.netty.channel.socket.ServerSocketChannelFactory;
-import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-
-/**
- * IMAPServer which use old IO and not NIO. If you want to use NIO you should
- * use {@link IMAPServer}
- */
-public class OioIMAPServer extends IMAPServer {
-
-    public OioIMAPServer(ImapDecoder decoder, ImapEncoder encoder, ImapProcessor processor, ImapMetrics imapMetrics) {
-        super(decoder, encoder, processor, imapMetrics);
-    }
-
-    @Override
-    protected ServerSocketChannelFactory createSocketChannelFactory() {
-        return new OioServerSocketChannelFactory(createBossExecutor(), createWorkerExecutor());
-    }
-
-    /**
-     * As OIO use one thread per connection we disable the use of the {@link ExecutionHandler}
-     */
-    @Override
-    protected ExecutionHandler createExecutionHandler() {
-        return null;
-    }
-
-}
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServerFactory.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServerFactory.java
deleted file mode 100644
index 32893fc..0000000
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/OioIMAPServerFactory.java
+++ /dev/null
@@ -1,43 +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.imapserver.netty;
-
-import javax.inject.Inject;
-
-import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.imap.api.process.ImapProcessor;
-import org.apache.james.imap.decode.ImapDecoder;
-import org.apache.james.imap.encode.ImapEncoder;
-import org.apache.james.metrics.api.MetricFactory;
-import org.jboss.netty.util.HashedWheelTimer;
-
-public class OioIMAPServerFactory extends IMAPServerFactory {
-
-    @Inject
-    public OioIMAPServerFactory(FileSystem fileSystem, ImapDecoder decoder, ImapEncoder encoder, ImapProcessor processor,
-                                MetricFactory metricFactory, HashedWheelTimer hashedWheelTimer) {
-        super(fileSystem, decoder, encoder, processor, metricFactory, hashedWheelTimer);
-    }
-
-    @Override
-    protected IMAPServer createServer() {
-        return new OioIMAPServer(decoder, encoder, processor, imapMetrics);
-    }
-
-}
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java
index fb5d58e..7ad1257 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java
@@ -22,15 +22,12 @@ package org.apache.james.imapserver.netty;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
-import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.protocols.api.CommandDetectionSession;
 import org.apache.james.protocols.netty.AllButStartTlsLineBasedChannelHandler;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.channel.MessageEvent;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPipeline;
 
 public class SwitchableLineBasedFrameDecoder extends AllButStartTlsLineBasedChannelHandler {
     public static final String PATTERN = ImapConstants.STARTTLS_COMMAND.getName().toLowerCase();
@@ -42,11 +39,11 @@ public class SwitchableLineBasedFrameDecoder extends AllButStartTlsLineBasedChan
     }
 
     @Override
-    public synchronized void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         if (this.framingEnabled) {
-            super.messageReceived(ctx, e);
+            super.channelRead(ctx, msg);
         } else {
-            ctx.sendUpstream(e);
+            ctx.fireChannelRead(msg);
         }
     }
 
@@ -56,16 +53,17 @@ public class SwitchableLineBasedFrameDecoder extends AllButStartTlsLineBasedChan
 
     public synchronized void disableFraming(ChannelHandlerContext ctx) {
         this.framingEnabled = false;
-        if (this.cumulation != null && this.cumulation.readable()) {
-            final ChannelBuffer spareBytes = this.cumulation.readBytes(this.cumulation.readableBytes());
-            this.cumulation = null;
-            Channels.fireMessageReceived(ctx, spareBytes);
+
+        if (internalBuffer().readableBytes() > 0) {
+            ByteBuf spareBytes = internalBuffer().retainedDuplicate();
+            internalBuffer().clear();
+            ctx.fireChannelRead(spareBytes);
         }
     }
 
     @Override
-    protected CommandDetectionSession retrieveSession(ChannelHandlerContext ctx, Channel channel) {
-        return (ImapSession) NettyConstants.attributes.get(ctx.getChannel());
+    protected CommandDetectionSession retrieveSession(ChannelHandlerContext ctx) {
+        return ctx.channel().attr(NettyConstants.IMAP_SESSION_ATTRIBUTE_KEY).get();
     }
 
     @Override
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoderFactory.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoderFactory.java
index a9cc66c..f497710 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoderFactory.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoderFactory.java
@@ -19,8 +19,9 @@
 package org.apache.james.imapserver.netty;
 
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelPipeline;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
 
 public class SwitchableLineBasedFrameDecoderFactory implements ChannelHandlerFactory {
 
diff --git a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoderTest.java b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoderTest.java
deleted file mode 100644
index 8dffa0b..0000000
--- a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoderTest.java
+++ /dev/null
@@ -1,80 +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.imapserver.netty;
-
-
-import static org.apache.james.imapserver.netty.ImapRequestFrameDecoder.NEEDED_DATA;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.apache.james.imap.decode.ImapDecoder;
-import org.jboss.netty.buffer.ChannelBufferFactory;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelConfig;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-class ImapRequestFrameDecoderTest {
-    ImapRequestFrameDecoder testee;
-
-    @BeforeEach
-    void setUp() {
-        testee = new ImapRequestFrameDecoder(
-            mock(ImapDecoder.class),
-            12,
-            18);
-    }
-
-    @Test
-    void newCumulationBufferShouldNotThrowWhenNoAttachments() {
-        ChannelHandlerContext channelHandler = mock(ChannelHandlerContext.class);
-        Channel channel = mock(Channel.class);
-        ChannelConfig channelConfig = mock(ChannelConfig.class);
-
-        when(channelConfig.getBufferFactory()).thenReturn(mock(ChannelBufferFactory.class));
-        when(channelHandler.getChannel()).thenReturn(channel);
-        when(channel.getConfig()).thenReturn(channelConfig);
-
-        when(channelHandler.getAttachment()).thenReturn(ImmutableMap.<String, Object>of());
-
-        assertThatCode(() -> testee.newCumulationBuffer(channelHandler, 36))
-            .doesNotThrowAnyException();
-    }
-
-    @Test
-    void newCumulationBufferShouldNotThrowOnNegativeSize() {
-        ChannelHandlerContext channelHandler = mock(ChannelHandlerContext.class);
-        Channel channel = mock(Channel.class);
-        ChannelConfig channelConfig = mock(ChannelConfig.class);
-
-        when(channelConfig.getBufferFactory()).thenReturn(mock(ChannelBufferFactory.class));
-        when(channelHandler.getChannel()).thenReturn(channel);
-        when(channel.getConfig()).thenReturn(channelConfig);
-
-        when(channelHandler.getAttachment()).thenReturn(ImmutableMap.<String, Object>of(NEEDED_DATA, -1));
-
-        assertThatCode(() -> testee.newCumulationBuffer(channelHandler, 36))
-            .doesNotThrowAnyException();
-    }
-}
\ No newline at end of file
diff --git a/server/protocols/protocols-library/pom.xml b/server/protocols/protocols-library/pom.xml
index 3de2566..a3dfd63 100644
--- a/server/protocols/protocols-library/pom.xml
+++ b/server/protocols/protocols-library/pom.xml
@@ -85,7 +85,7 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.annotation</groupId>
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 52887da..5d5df1a 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,20 +47,20 @@ import org.apache.james.protocols.api.ClientAuth;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.lib.jmx.ServerMBean;
 import org.apache.james.protocols.netty.AbstractAsyncServer;
+import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.util.concurrent.JMXEnabledThreadPoolExecutor;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.group.ChannelGroup;
 import nl.altindag.ssl.SSLFactory;
 import nl.altindag.ssl.util.PemUtils;
 
+
 /**
  * Abstract base class for Servers for all James Servers
  */
@@ -93,7 +93,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
     private String x509Algorithm = defaultX509algorithm;
 
     private FileSystem fileSystem;
-    private HashedWheelTimer timer;
 
     private boolean enabled;
 
@@ -127,7 +126,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
 
     private final ConnectionCountHandler countHandler = new ConnectionCountHandler();
 
-    private ExecutionHandler executionHandler = null;
     private ChannelHandlerFactory frameHandlerFactory;
 
     private int maxExecutorThreads;
@@ -141,11 +139,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
         this.fileSystem = filesystem;
     }
 
-    @Inject
-    public void setHashWheelTimer(HashedWheelTimer timer) {
-        this.timer = timer;
-    }
-
     protected void registerMBean() {
 
         try {
@@ -291,7 +284,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
 
             buildSSLContext();
             preInit();
-            executionHandler = createExecutionHandler();
             frameHandlerFactory = createFrameHandlerFactory();
             bind();
             port = retrieveFirstBindedPort();
@@ -328,10 +320,6 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
             unbind();
             postDestroy();
 
-            if (executionHandler != null) {
-                executionHandler.releaseExternalResources();
-            }
-
             unregisterMBean();
         }
         LOGGER.info("Dispose {} done", getServiceType());
@@ -572,42 +560,24 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
         super.configureBootstrap(bootstrap);
         
         // enable tcp keep-alives
-        bootstrap.setOption("child.keepAlive", true);
+        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
     }
     
-    /**
-     * Create a new {@link ExecutionHandler} which is used to execute IO-Bound handlers
-     * 
-     * @return ehandler
-     */
-    protected ExecutionHandler createExecutionHandler() {
-        return new ExecutionHandler(new JMXEnabledOrderedMemoryAwareThreadPoolExecutor(maxExecutorThreads, 0, 0, getThreadPoolJMXPath(), getDefaultJMXName() + "-executor"));
-    }
-
     protected abstract ChannelHandlerFactory createFrameHandlerFactory();
 
-    /**
-     * Return the {@link ExecutionHandler} or null if non should be used. Be sure you call {@link #createExecutionHandler()} before
-     * 
-     * @return ehandler
-     */
-    protected ExecutionHandler getExecutionHandler() {
-        return executionHandler;
-    }
-    
     protected ChannelHandlerFactory getFrameHandlerFactory() {
         return frameHandlerFactory;
     }
 
-    protected abstract ChannelUpstreamHandler createCoreHandler();
+    protected abstract ChannelInboundHandlerAdapter createCoreHandler();
     
     @Override
-    protected ChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
         return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), connectionLimit, connPerIP, group,
-            getEncryption(), getExecutionHandler(), getFrameHandlerFactory(), timer) {
+            getEncryption(), getFrameHandlerFactory()) {
 
             @Override
-            protected ChannelUpstreamHandler createHandler() {
+            protected ChannelInboundHandlerAdapter createHandler() {
                 return AbstractConfigurableAsyncServer.this.createCoreHandler();
 
             }
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 06c6db2..a4271eb 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
@@ -21,32 +21,22 @@ package org.apache.james.protocols.lib.netty;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.netty.AbstractSSLAwareChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
-import org.apache.james.protocols.netty.HandlerConstants;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.util.HashedWheelTimer;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.group.ChannelGroup;
 
 /**
  * Abstract base class which should get used if you MAY need an {@link ExecutionHandler}
  * 
  *
  */
+@ChannelHandler.Sharable
 public abstract class AbstractExecutorAwareChannelPipelineFactory extends AbstractSSLAwareChannelPipelineFactory {
 
     public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp,
                                                        ChannelGroup group, Encryption encryption,
-                                                       ExecutionHandler eHandler, ChannelHandlerFactory frameHandlerFactory,
-                                                       HashedWheelTimer hashedWheelTimer) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, encryption, eHandler, frameHandlerFactory, hashedWheelTimer);
-    }
-    
-    @Override
-    public ChannelPipeline getPipeline() throws Exception {
-        ChannelPipeline pipeLine = super.getPipeline();
-        pipeLine.addBefore(HandlerConstants.CORE_HANDLER, "countHandler", getConnectionCountHandler());
-        
-        return pipeLine;
+                                                       ChannelHandlerFactory frameHandlerFactory) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, encryption, frameHandlerFactory);
     }
     
     /**
diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/ConnectionCountHandler.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/ConnectionCountHandler.java
index c1d76f3..16eca52 100644
--- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/ConnectionCountHandler.java
+++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/ConnectionCountHandler.java
@@ -21,29 +21,30 @@ package org.apache.james.protocols.lib.netty;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
 
 /**
  * Count connections
  */
-public class ConnectionCountHandler extends SimpleChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public class ConnectionCountHandler extends ChannelInboundHandlerAdapter {
 
     public final AtomicInteger currentConnectionCount = new AtomicInteger();
     public final AtomicLong connectionsTillStartup = new AtomicLong();
 
     @Override
-    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         currentConnectionCount.decrementAndGet();
-        super.channelClosed(ctx, e);
+        super.channelInactive(ctx);
     }
 
     @Override
-    public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
         currentConnectionCount.incrementAndGet();
         connectionsTillStartup.incrementAndGet();
-        super.channelOpen(ctx, e);
+        super.channelActive(ctx);
     }
 
     /**
diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/JMXEnabledOrderedMemoryAwareThreadPoolExecutor.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/JMXEnabledOrderedMemoryAwareThreadPoolExecutor.java
deleted file mode 100644
index 06644fb..0000000
--- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/JMXEnabledOrderedMemoryAwareThreadPoolExecutor.java
+++ /dev/null
@@ -1,141 +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.protocols.lib.netty;
-
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.james.util.concurrent.NamedThreadFactory;
-import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
-
-/**
- * {@link OrderedMemoryAwareThreadPoolExecutor} subclass which expose statistics via JMX
- */
-public class JMXEnabledOrderedMemoryAwareThreadPoolExecutor extends OrderedMemoryAwareThreadPoolExecutor implements JMXEnabledOrderedMemoryAwareThreadPoolExecutorMBean {
-
-    private final String jmxPath;
-    private final ThreadLocal<Long> startTime = new ThreadLocal<>();
-    private final AtomicLong totalTime = new AtomicLong(0);
-    private final AtomicInteger totalTasks = new AtomicInteger(0);
-    private MBeanServer mbeanServer;
-    private String mbeanName;
-    
-    public JMXEnabledOrderedMemoryAwareThreadPoolExecutor(int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize, String jmxPath, String name) {
-        super(corePoolSize, maxChannelMemorySize, maxTotalMemorySize, 30, TimeUnit.SECONDS, NamedThreadFactory.withName(name));
-        this.jmxPath = jmxPath;
-        registerMBean();
-    }
-
-    @Override
-    protected void beforeExecute(Thread t, Runnable r) {
-        super.beforeExecute(t, r);
-        startTime.set(System.currentTimeMillis());
-    }
-
-    @Override
-    protected void afterExecute(Runnable r, Throwable t) {
-        long time = System.currentTimeMillis() - startTime.get();
-        totalTime.addAndGet(time);
-        totalTasks.incrementAndGet();
-        super.afterExecute(r, t);
-    }
-
-    private void registerMBean() {
-        if (jmxPath != null) {
-            mbeanServer = ManagementFactory.getPlatformMBeanServer();
-            mbeanName = jmxPath + ",threadpool=" + ((NamedThreadFactory) getThreadFactory()).getName();
-            try {
-                mbeanServer.registerMBean(this, new ObjectName(mbeanName));
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to register mbean", e);
-            }
-        }
-    }
-
-    private void unregisterMBean() {
-        if (jmxPath != null) {
-            try {
-                mbeanServer.unregisterMBean(new ObjectName(mbeanName));
-
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to unregister mbean", e);
-            }
-        }
-    }
-
-    @Override
-    public synchronized void shutdown() {
-        // synchronized, because there is no way to access super.mainLock, which
-        // would be
-        // the preferred way to make this threadsafe
-        if (!isShutdown()) {
-            unregisterMBean();
-        }
-        super.shutdown();
-        startTime.remove();
-    }
-
-    @Override
-    public synchronized List<Runnable> shutdownNow() {
-        // synchronized, because there is no way to access super.mainLock, which
-        // would be
-        // the preferred way to make this threadsafe
-        if (!isShutdown()) {
-            unregisterMBean();
-        }
-        return super.shutdownNow();
-    }
-
-    @Override
-    public synchronized int getTotalTasks() {
-        return totalTasks.get();
-    }
-
-    @Override
-    public synchronized double getAverageTaskTime() {
-        return (totalTasks.get() == 0) ? 0 : totalTime.get() / totalTasks.get();
-    }
-
-    @Override
-    public int getActiveThreads() {
-        return getPoolSize();
-    }
-
-    @Override
-    public int getActiveTasks() {
-        return getActiveCount();
-    }
-
-    @Override
-    public int getQueuedTasks() {
-        return getQueue().size();
-    }
-
-    @Override
-    public int getMaximalThreads() {
-        return getMaximumPoolSize();
-    }
-
-}
diff --git a/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/AbstractConfigurableAsyncServerTest.java b/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/AbstractConfigurableAsyncServerTest.java
index 481c958..0ab2d81 100644
--- a/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/AbstractConfigurableAsyncServerTest.java
+++ b/server/protocols/protocols-library/src/test/java/org/apache/james/protocols/lib/AbstractConfigurableAsyncServerTest.java
@@ -36,7 +36,7 @@ import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.lib.mock.ConfigLoader;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
+import io.netty.channel.ChannelInboundHandlerAdapter;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -104,7 +104,7 @@ public class AbstractConfigurableAsyncServerTest {
         }
 
         @Override
-        protected ChannelUpstreamHandler createCoreHandler () {
+        protected ChannelInboundHandlerAdapter createCoreHandler () {
             return null;
         }
 
diff --git a/server/protocols/protocols-lmtp/pom.xml b/server/protocols/protocols-lmtp/pom.xml
index 430fd14..c82f3f1 100644
--- a/server/protocols/protocols-lmtp/pom.xml
+++ b/server/protocols/protocols-lmtp/pom.xml
@@ -152,7 +152,7 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.inject</groupId>
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 e1375fc..7899a7a 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
@@ -34,10 +34,11 @@ import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.LineDelimiterBasedChannelHandlerFactory;
 import org.apache.james.protocols.smtp.SMTPProtocol;
 import org.apache.james.smtpserver.netty.SMTPChannelUpstreamHandler;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
 public class LMTPServer extends AbstractProtocolAsyncServer implements LMTPServerMBean {
     private static final Logger LOGGER = LoggerFactory.getLogger(LMTPServer.class);
 
@@ -139,7 +140,7 @@ public class LMTPServer extends AbstractProtocolAsyncServer implements LMTPServe
     }
 
     @Override
-    protected ChannelUpstreamHandler createCoreHandler() {
+    protected ChannelInboundHandlerAdapter createCoreHandler() {
         SMTPProtocol protocol = new SMTPProtocol(getProtocolHandlerChain(), lmtpConfig);
         return new SMTPChannelUpstreamHandler(protocol, lmtpMetrics);
     }
diff --git a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServerFactory.java b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServerFactory.java
index e7e00f1..bd68bac 100644
--- a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServerFactory.java
+++ b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServerFactory.java
@@ -30,22 +30,18 @@ import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.protocols.lib.handler.ProtocolHandlerLoader;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.lib.netty.AbstractServerFactory;
-import org.jboss.netty.util.HashedWheelTimer;
 
 public class LMTPServerFactory extends AbstractServerFactory {
 
     private final ProtocolHandlerLoader loader;
     private final FileSystem fileSystem;
     protected final LMTPMetricsImpl lmtpMetrics;
-    private final HashedWheelTimer hashedWheelTimer;
 
     @Inject
-    public LMTPServerFactory(ProtocolHandlerLoader loader, FileSystem fileSystem, MetricFactory metricFactory,
-                             HashedWheelTimer hashedWheelTimer) {
+    public LMTPServerFactory(ProtocolHandlerLoader loader, FileSystem fileSystem, MetricFactory metricFactory) {
         this.loader = loader;
         this.fileSystem = fileSystem;
         this.lmtpMetrics = new LMTPMetricsImpl(metricFactory);
-        this.hashedWheelTimer = hashedWheelTimer;
     }
 
     protected LMTPServer createServer() {
@@ -60,7 +56,6 @@ public class LMTPServerFactory extends AbstractServerFactory {
         for (HierarchicalConfiguration<ImmutableNode> serverConfig: configs) {
             LMTPServer server = createServer();
             server.setFileSystem(fileSystem);
-            server.setHashWheelTimer(hashedWheelTimer);
             server.setProtocolHandlerLoader(loader);
             server.configure(serverConfig);
             servers.add(server);
diff --git a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServer.java b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServer.java
deleted file mode 100644
index 3253bc5..0000000
--- a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServer.java
+++ /dev/null
@@ -1,50 +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.lmtpserver.netty;
-
-import org.jboss.netty.channel.socket.ServerSocketChannelFactory;
-import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-
-/**
- * LMTPServer which use old IO and not NIO. If you want to use NIO you should
- * use {@link LMTPServer}
- */
-public class OioLMTPServer extends LMTPServer {
-
-
-    public OioLMTPServer(LMTPMetricsImpl lmtpMetrics) {
-        super(lmtpMetrics);
-    }
-
-    @Override
-    protected ServerSocketChannelFactory createSocketChannelFactory() {
-        return new OioServerSocketChannelFactory(createBossExecutor(), createWorkerExecutor());
-    }
-
-    /**
-     * As OIO use one thread per connection we disable the use of the {@link ExecutionHandler}
-     * 
-     */
-    @Override
-    protected ExecutionHandler createExecutionHandler() {
-        return null;
-    }
-
-}
diff --git a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServerFactory.java b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServerFactory.java
deleted file mode 100644
index dd466a0..0000000
--- a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/OioLMTPServerFactory.java
+++ /dev/null
@@ -1,41 +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.lmtpserver.netty;
-
-import javax.inject.Inject;
-
-import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.metrics.api.MetricFactory;
-import org.apache.james.protocols.lib.handler.ProtocolHandlerLoader;
-import org.jboss.netty.util.HashedWheelTimer;
-
-public class OioLMTPServerFactory extends LMTPServerFactory {
-
-    @Inject
-    public OioLMTPServerFactory(ProtocolHandlerLoader loader, FileSystem fileSystem, MetricFactory metricFactory,
-                                HashedWheelTimer hashedWheelTimer) {
-        super(loader, fileSystem, metricFactory, hashedWheelTimer);
-    }
-
-    @Override
-    protected LMTPServer createServer() {
-        return new OioLMTPServer(lmtpMetrics);
-    }
-
-}
diff --git a/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java b/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
index 154682d..b0b75bc 100644
--- a/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
+++ b/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
@@ -73,7 +73,6 @@ import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.mailet.DsnParameters;
 import org.apache.mailet.Mail;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
@@ -163,7 +162,7 @@ class LmtpServerTest {
     }
 
     private LMTPServerFactory createLMTPServer(MockProtocolHandlerLoader loader, String configuration) throws Exception {
-        LMTPServerFactory lmtpServerFactory = new LMTPServerFactory(loader, fileSystem, new RecordingMetricFactory(), new HashedWheelTimer());
+        LMTPServerFactory lmtpServerFactory = new LMTPServerFactory(loader, fileSystem, new RecordingMetricFactory());
         lmtpServerFactory.configure(ConfigLoader.getConfig(ClassLoader.getSystemResourceAsStream(configuration)));
         lmtpServerFactory.init();
         return lmtpServerFactory;
diff --git a/server/protocols/protocols-managesieve/pom.xml b/server/protocols/protocols-managesieve/pom.xml
index 4d7cb86..d500ed2 100644
--- a/server/protocols/protocols-managesieve/pom.xml
+++ b/server/protocols/protocols-managesieve/pom.xml
@@ -40,7 +40,7 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.annotation</groupId>
diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
index d131efb..d068dfe 100644
--- a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
@@ -24,8 +24,9 @@ import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.james.protocols.api.CommandDetectionSession;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.handler.stream.ChunkedStream;
+
+import io.netty.channel.Channel;
+import io.netty.handler.stream.ChunkedStream;
 
 public class ChannelManageSieveResponseWriter implements CommandDetectionSession {
     private final Channel channel;
@@ -36,9 +37,9 @@ public class ChannelManageSieveResponseWriter implements CommandDetectionSession
     }
 
     public void write(String response) {
-        if (channel.isConnected()) {
+        if (channel.isActive()) {
             InputStream in = new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8));
-            channel.write(new ChunkedStream(in));
+            channel.writeAndFlush(new ChunkedStream(in));
         }
     }
 
diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
index bdee262..f013553 100644
--- a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
@@ -28,32 +28,29 @@ import org.apache.james.managesieve.transcode.ManageSieveProcessor;
 import org.apache.james.managesieve.transcode.NotEnoughDataException;
 import org.apache.james.managesieve.util.SettableSession;
 import org.apache.james.protocols.api.Encryption;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFutureListener;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelLocal;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.frame.TooLongFrameException;
-import org.jboss.netty.handler.ssl.SslHandler;
 import org.slf4j.Logger;
 
-public class ManageSieveChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.codec.TooLongFrameException;
+import io.netty.handler.ssl.SslHandler;
+
+@ChannelHandler.Sharable
+public class ManageSieveChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
 
     static final String SSL_HANDLER = "sslHandler";
 
     private final Logger logger;
-    private final ChannelLocal<Session> attributes;
     private final ManageSieveProcessor manageSieveProcessor;
     private final Encryption secure;
 
     public ManageSieveChannelUpstreamHandler(
             ManageSieveProcessor manageSieveProcessor, Encryption secure, Logger logger) {
         this.logger = logger;
-        this.attributes = new ChannelLocal<>();
         this.manageSieveProcessor = manageSieveProcessor;
         this.secure = secure;
     }
@@ -63,20 +60,20 @@ public class ManageSieveChannelUpstreamHandler extends SimpleChannelUpstreamHand
     }
 
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        ChannelManageSieveResponseWriter attachment = (ChannelManageSieveResponseWriter) ctx.getAttachment();
-        try (Closeable closeable = ManageSieveMDCContext.from(ctx, attributes)) {
-            String request = attachment.cumulate((String) e.getMessage());
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ChannelManageSieveResponseWriter attachment = ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).get();
+        try (Closeable closeable = ManageSieveMDCContext.from(ctx)) {
+            String request = attachment.cumulate((String) msg);
             if (request.isEmpty() || request.startsWith("\r\n")) {
                 return;
             }
 
-            Session manageSieveSession = attributes.get(ctx.getChannel());
+            Session manageSieveSession = ctx.channel().attr(NettyConstants.SESSION_ATTRIBUTE_KEY).get();
             String responseString = manageSieveProcessor.handleRequest(manageSieveSession, request);
             attachment.resetCumulation();
             attachment.write(responseString);
             if (manageSieveSession.getState() == Session.State.SSL_NEGOCIATION) {
-                turnSSLon(ctx.getChannel());
+                turnSSLon(ctx.channel());
                 manageSieveSession.setSslEnabled(true);
                 manageSieveSession.setState(Session.State.UNAUTHENTICATED);
             }
@@ -86,16 +83,16 @@ public class ManageSieveChannelUpstreamHandler extends SimpleChannelUpstreamHand
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
-        try (Closeable closeable = ManageSieveMDCContext.from(ctx, attributes)) {
-            logger.warn("Error while processing ManageSieve request", e.getCause());
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        try (Closeable closeable = ManageSieveMDCContext.from(ctx)) {
+            logger.warn("Error while processing ManageSieve request", cause);
 
-            if (e.getCause() instanceof TooLongFrameException) {
+            if (cause instanceof TooLongFrameException) {
                 // Max line length exceeded
                 // See also JAMES-1190
-                ((ChannelManageSieveResponseWriter) ctx.getAttachment()).write("NO Maximum command line length exceeded");
-            } else if (e.getCause() instanceof SessionTerminatedException) {
-                ((ChannelManageSieveResponseWriter) ctx.getAttachment()).write("OK channel is closing");
+                ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).get().write("NO Maximum command line length exceeded");
+            } else if (cause instanceof SessionTerminatedException) {
+                ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).get().write("OK channel is closing");
                 logout(ctx);
             }
         }
@@ -103,48 +100,48 @@ public class ManageSieveChannelUpstreamHandler extends SimpleChannelUpstreamHand
 
     private void logout(ChannelHandlerContext ctx) {
         // logout on error not sure if that is the best way to handle it
-        attributes.remove(ctx.getChannel());
+        ctx.channel().attr(NettyConstants.SESSION_ATTRIBUTE_KEY).getAndSet(null);
         // Make sure we close the channel after all the buffers were flushed out
-        Channel channel = ctx.getChannel();
-        if (channel.isConnected()) {
-            channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
+        Channel channel = ctx.channel();
+        if (channel.isActive()) {
+            channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
         }
     }
 
     @Override
-    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        try (Closeable closeable = ManageSieveMDCContext.from(ctx, attributes)) {
-            InetSocketAddress address = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        try (Closeable closeable = ManageSieveMDCContext.from(ctx)) {
+            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
             logger.info("Connection established from {}", address.getAddress().getHostAddress());
 
             Session session = new SettableSession();
             if (isSSL()) {
                 session.setSslEnabled(true);
             }
-            attributes.set(ctx.getChannel(), session);
-            ctx.setAttachment(new ChannelManageSieveResponseWriter(ctx.getChannel()));
-            super.channelBound(ctx, e);
-            ((ChannelManageSieveResponseWriter) ctx.getAttachment()).write(manageSieveProcessor.getAdvertisedCapabilities() + "OK\r\n");
+            ctx.channel().attr(NettyConstants.SESSION_ATTRIBUTE_KEY).set(session);
+            ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).set(new ChannelManageSieveResponseWriter(ctx.channel()));
+            super.channelActive(ctx);
+            ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).get().write(manageSieveProcessor.getAdvertisedCapabilities() + "OK\r\n");
         }
     }
 
     @Override
-    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        try (Closeable closeable = ManageSieveMDCContext.from(ctx, attributes)) {
-            InetSocketAddress address = (InetSocketAddress) ctx.getChannel().getRemoteAddress();
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        try (Closeable closeable = ManageSieveMDCContext.from(ctx)) {
+            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
             logger.info("Connection closed for {}", address.getAddress().getHostAddress());
-            attributes.remove(ctx.getChannel());
-            super.channelClosed(ctx, e);
+            ctx.channel().attr(NettyConstants.SESSION_ATTRIBUTE_KEY).getAndSet(null);
+            super.channelInactive(ctx);
         }
     }
 
     private void turnSSLon(Channel channel) {
         if (secure != null) {
-            channel.setReadable(false);
+            channel.config().setAutoRead(false);
             SslHandler filter = new SslHandler(secure.createSSLEngine(), false);
-            filter.getEngine().setUseClientMode(false);
-            channel.getPipeline().addFirst(SSL_HANDLER, filter);
-            channel.setReadable(true);
+            filter.engine().setUseClientMode(false);
+            channel.pipeline().addFirst(SSL_HANDLER, filter);
+            channel.config().setAutoRead(true);
         }
     }
 }
diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java
index 2e44aa2..c04210d 100644
--- a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java
@@ -27,22 +27,22 @@ import java.util.Optional;
 import org.apache.james.core.Username;
 import org.apache.james.managesieve.api.Session;
 import org.apache.james.util.MDCBuilder;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelLocal;
+
+import io.netty.channel.ChannelHandlerContext;
 
 public class ManageSieveMDCContext {
-    public static Closeable from(ChannelHandlerContext ctx, ChannelLocal<Session> attributes) {
+    public static Closeable from(ChannelHandlerContext ctx) {
         return MDCBuilder.create()
-            .addToContext(from(attributes.get(ctx.getChannel())))
+            .addToContext(from(ctx.channel().attr(NettyConstants.SESSION_ATTRIBUTE_KEY).get()))
             .addToContext(MDCBuilder.PROTOCOL, "MANAGE-SIEVE")
             .addToContext(MDCBuilder.IP, retrieveIp(ctx))
             .addToContext(MDCBuilder.HOST, retrieveHost(ctx))
-            .addToContext(MDCBuilder.SESSION_ID, Integer.toString(ctx.getChannel().getId()))
+            .addToContext(MDCBuilder.SESSION_ID, ctx.channel().id().asShortText())
             .build();
     }
 
     private static String retrieveIp(ChannelHandlerContext ctx) {
-        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
             InetSocketAddress address = (InetSocketAddress) remoteAddress;
             return address.getAddress().getHostAddress();
@@ -51,7 +51,7 @@ public class ManageSieveMDCContext {
     }
 
     private static String retrieveHost(ChannelHandlerContext ctx) {
-        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
             InetSocketAddress address = (InetSocketAddress) remoteAddress;
             return address.getHostName();
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 b1510b7..e9f35fa 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,7 +19,6 @@
 
 package org.apache.james.managesieveserver.netty;
 
-import static org.jboss.netty.channel.Channels.pipeline;
 
 import javax.net.ssl.SSLEngine;
 
@@ -32,19 +31,19 @@ import org.apache.james.protocols.netty.ChannelGroupHandler;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
 import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
-import org.jboss.netty.channel.ChannelPipeline;
-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.string.StringDecoder;
-import org.jboss.netty.handler.codec.string.StringEncoder;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.handler.stream.ChunkedWriteHandler;
-import org.jboss.netty.util.CharsetUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedWriteHandler;
+import io.netty.util.CharsetUtil;
+
 public class ManageSieveServer extends AbstractConfigurableAsyncServer implements ManageSieveServerMBean {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ManageSieveServer.class);
@@ -78,22 +77,27 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement
     }
 
     @Override
-    protected ChannelUpstreamHandler createCoreHandler() {
+    protected ChannelInboundHandlerAdapter createCoreHandler() {
         return new ManageSieveChannelUpstreamHandler(manageSieveProcessor,
             getEncryption(),
             LOGGER);
     }
 
     @Override
-    protected ChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
+    protected AbstractChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
+
+        return new AbstractChannelPipelineFactory(group, createFrameHandlerFactory()) {
 
-        return new ChannelPipelineFactory() {
+            @Override
+            protected ChannelInboundHandlerAdapter createHandler() {
+                return createCoreHandler();
+            }
 
             private final ChannelGroupHandler groupHandler = new ChannelGroupHandler(group);
 
             @Override
-            public ChannelPipeline getPipeline() throws Exception {
-                ChannelPipeline pipeline = pipeline();
+            public void initChannel(Channel channel) throws Exception {
+                ChannelPipeline pipeline = channel.pipeline();
                 Encryption secure = getEncryption();
                 if (secure != null && !secure.isStartTLS()) {
                     // We need to set clientMode to false.
@@ -113,15 +117,9 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement
                 pipeline.addLast(CONNECTION_COUNT_HANDLER, getConnectionCountHandler());
                 pipeline.addLast(CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
 
-                ExecutionHandler ehandler = getExecutionHandler();
-                if (ehandler  != null) {
-                    pipeline.addLast(EXECUTION_HANDLER, ehandler);
-
-                }
                 pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
-                pipeline.addLast(CORE_HANDLER, createCoreHandler());
+                pipeline.addLast(CORE_HANDLER, createHandler());
                 pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
-                return pipeline;
             }
 
         };
diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
index 014a863..532052d 100644
--- a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
@@ -36,7 +36,6 @@ import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.lib.netty.AbstractServerFactory;
 import org.apache.james.sieverepository.api.SieveRepository;
 import org.apache.james.user.api.UsersRepository;
-import org.jboss.netty.util.HashedWheelTimer;
 
 public class ManageSieveServerFactory extends AbstractServerFactory {
 
@@ -45,7 +44,6 @@ public class ManageSieveServerFactory extends AbstractServerFactory {
     private SieveRepository sieveRepository;
     private UsersRepository usersRepository;
     private Parser sieveParser;
-    private HashedWheelTimer hashedWheelTimer;
 
     @Inject
     public void setFileSystem(FileSystem fileSystem) {
@@ -67,11 +65,6 @@ public class ManageSieveServerFactory extends AbstractServerFactory {
         this.sieveParser = sieveParser;
     }
 
-    @Inject
-    public void setHashedWheelTimer(HashedWheelTimer hashedWheelTimer) {
-        this.hashedWheelTimer = hashedWheelTimer;
-    }
-
 
     @Override
     @PostConstruct
@@ -88,7 +81,6 @@ public class ManageSieveServerFactory extends AbstractServerFactory {
         for (HierarchicalConfiguration<ImmutableNode> serverConfig: configs) {
             ManageSieveServer server = new ManageSieveServer(8000, manageSieveProcessor);
             server.setFileSystem(fileSystem);
-            server.setHashWheelTimer(hashedWheelTimer);
             server.configure(serverConfig);
             servers.add(server);
         }
diff --git a/server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/OioPOP3ServerTest.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/NettyConstants.java
similarity index 72%
rename from server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/OioPOP3ServerTest.java
rename to server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/NettyConstants.java
index c5315ca..9e52d9f 100644
--- a/server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/OioPOP3ServerTest.java
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/NettyConstants.java
@@ -16,16 +16,17 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.pop3server;
+package org.apache.james.managesieveserver.netty;
 
-import org.apache.james.pop3server.netty.OioPOP3Server;
-import org.apache.james.pop3server.netty.POP3Server;
+import org.apache.james.managesieve.api.Session;
 
-public class OioPOP3ServerTest extends POP3ServerTest {
+import io.netty.util.AttributeKey;
 
-    @Override
-    protected POP3Server createPOP3Server() {
-        return new OioPOP3Server();
-    }
+/**
+ * Just some constants which are used with the Netty implementation
+ */
+public interface NettyConstants {
+    AttributeKey<ChannelManageSieveResponseWriter> RESPONSE_WRITER_ATTRIBUTE_KEY = AttributeKey.valueOf("ResponseWriter");
+    AttributeKey<Session> SESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("Session");
 
 }
diff --git a/server/protocols/protocols-pop3/pom.xml b/server/protocols/protocols-pop3/pom.xml
index 73e3090..a5c83f8 100644
--- a/server/protocols/protocols-pop3/pom.xml
+++ b/server/protocols/protocols-pop3/pom.xml
@@ -140,7 +140,7 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.inject</groupId>
diff --git a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3Server.java b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3Server.java
deleted file mode 100644
index d3bc448..0000000
--- a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3Server.java
+++ /dev/null
@@ -1,44 +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.pop3server.netty;
-
-import org.jboss.netty.channel.socket.ServerSocketChannelFactory;
-import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-
-/**
- * POP3Server which use old IO and not NIO. If you want to use NIO you should
- * use {@link POP3Server}
- */
-public class OioPOP3Server extends POP3Server {
-
-    @Override
-    protected ServerSocketChannelFactory createSocketChannelFactory() {
-        return new OioServerSocketChannelFactory(createBossExecutor(), createWorkerExecutor());
-    }
-
-    /**
-     * As OIO use one thread per connection we disable the use of the {@link ExecutionHandler}
-     */
-    @Override
-    protected ExecutionHandler createExecutionHandler() {
-        return null;
-    }
-
-}
diff --git a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3ServerFactory.java b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3ServerFactory.java
deleted file mode 100644
index 76e019b..0000000
--- a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/OioPOP3ServerFactory.java
+++ /dev/null
@@ -1,29 +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.pop3server.netty;
-
-public class OioPOP3ServerFactory extends POP3ServerFactory {
-
-    @Override
-    protected POP3Server createServer() {
-        return new OioPOP3Server();
-    }
-
-}
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 4c4981f..242874a 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
@@ -29,7 +29,8 @@ import org.apache.james.protocols.netty.BasicChannelUpstreamHandler;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ProtocolMDCContextFactory;
 import org.apache.james.protocols.pop3.POP3Protocol;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
+
+import io.netty.channel.ChannelInboundHandlerAdapter;
 
 /**
  * NIO POP3 Server which use Netty
@@ -85,7 +86,7 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve
     }
 
     @Override
-    protected ChannelUpstreamHandler createCoreHandler() {
+    protected ChannelInboundHandlerAdapter createCoreHandler() {
         return coreHandler; 
     }
 
diff --git a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3ServerFactory.java b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3ServerFactory.java
index f11b498..d146360 100644
--- a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3ServerFactory.java
+++ b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3ServerFactory.java
@@ -11,13 +11,11 @@ import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.protocols.lib.handler.ProtocolHandlerLoader;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.lib.netty.AbstractServerFactory;
-import org.jboss.netty.util.HashedWheelTimer;
 
 public class POP3ServerFactory extends AbstractServerFactory {
 
     private ProtocolHandlerLoader loader;
     private FileSystem fileSystem;
-    private HashedWheelTimer hashedWheelTimer;
 
     @Inject
     public void setProtocolHandlerLoader(ProtocolHandlerLoader loader) {
@@ -29,11 +27,6 @@ public class POP3ServerFactory extends AbstractServerFactory {
         this.fileSystem = filesystem;
     }
 
-    @Inject
-    public void setHashedWheelTimer(HashedWheelTimer hashedWheelTimer) {
-        this.hashedWheelTimer = hashedWheelTimer;
-    }
-
     protected POP3Server createServer() {
        return new POP3Server();
     }
@@ -48,7 +41,6 @@ public class POP3ServerFactory extends AbstractServerFactory {
             POP3Server server = createServer();
             server.setProtocolHandlerLoader(loader);
             server.setFileSystem(fileSystem);
-            server.setHashWheelTimer(hashedWheelTimer);
             server.configure(serverConfig);
             servers.add(server);
         }
diff --git a/server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/POP3ServerTest.java b/server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/POP3ServerTest.java
index 128450a..17d1986 100644
--- a/server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/POP3ServerTest.java
+++ b/server/protocols/protocols-pop3/src/test/java/org/apache/james/pop3server/POP3ServerTest.java
@@ -67,7 +67,6 @@ import org.apache.james.server.core.filesystem.FileSystemImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.memory.MemoryUsersRepository;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
@@ -92,11 +91,9 @@ public class POP3ServerTest {
             + "Subject: test\r\n\r\n"
             + "Body Text POP3ServerTest.setupTestMails\r\n").getBytes();
     private POP3Server pop3Server;
-    private HashedWheelTimer hashedWheelTimer;
 
     @BeforeEach
     void setUp() throws Exception {
-        hashedWheelTimer = new HashedWheelTimer();
         setUpServiceManager();
         setUpPOP3Server();
         pop3Configuration = ConfigLoader.getConfig(fileSystem.getResource("classpath://pop3server.xml"));
@@ -116,7 +113,6 @@ public class POP3ServerTest {
         }
         protocolHandlerChain.dispose();
         pop3Server.destroy();
-        hashedWheelTimer.stop();
     }
 
     @Nested
@@ -926,7 +922,6 @@ public class POP3ServerTest {
     protected void setUpPOP3Server() {
         pop3Server = createPOP3Server();
         pop3Server.setFileSystem(fileSystem);
-        pop3Server.setHashWheelTimer(hashedWheelTimer);
         pop3Server.setProtocolHandlerLoader(protocolHandlerChain);
     }
 
diff --git a/server/protocols/protocols-smtp/pom.xml b/server/protocols/protocols-smtp/pom.xml
index 047ad9d..fd8e9a1 100644
--- a/server/protocols/protocols-smtp/pom.xml
+++ b/server/protocols/protocols-smtp/pom.xml
@@ -184,7 +184,7 @@
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
-            <artifactId>netty</artifactId>
+            <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.inject</groupId>
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SMTPConstants.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SMTPConstants.java
index 3b062e3..1655b96 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SMTPConstants.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SMTPConstants.java
@@ -20,9 +20,12 @@
 package org.apache.james.smtpserver;
 
 import org.apache.james.protocols.api.ProtocolSession;
+import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.server.core.MimeMessageInputStreamSource;
 import org.apache.mailet.Mail;
 
+import io.netty.util.AttributeKey;
+
 /**
  * Constants which are used within SMTP Session
  */
@@ -31,4 +34,6 @@ public interface SMTPConstants {
     ProtocolSession.AttachmentKey<MimeMessageInputStreamSource> DATA_MIMEMESSAGE_STREAMSOURCE = ProtocolSession.AttachmentKey.of("org.apache.james.core.DataCmdHandler.DATA_MIMEMESSAGE_STREAMSOURCE", MimeMessageInputStreamSource.class);
     ProtocolSession.AttachmentKey<Mail> MAIL = ProtocolSession.AttachmentKey.of("MAIL", Mail.class);
 
+    AttributeKey<SMTPSession> SMTP_SESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("SmtpSession");
+
 }
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServer.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServer.java
deleted file mode 100644
index 5e1f3e8..0000000
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServer.java
+++ /dev/null
@@ -1,47 +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.smtpserver.netty;
-
-import org.jboss.netty.channel.socket.ServerSocketChannelFactory;
-import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;
-import org.jboss.netty.handler.execution.ExecutionHandler;
-
-/**
- * SMTPServer which use old IO and not NIO. If you want to use NIO you should
- * use {@link SMTPServer}
- */
-public class OioSMTPServer extends SMTPServer {
-
-    public OioSMTPServer(SmtpMetricsImpl smtpMetrics) {
-        super(smtpMetrics);
-    }
-
-    @Override
-    protected ServerSocketChannelFactory createSocketChannelFactory() {
-        return new OioServerSocketChannelFactory(createBossExecutor(), createWorkerExecutor());
-    }
-
-    /**
-     * As OIO use one thread per connection we disable the use of the {@link ExecutionHandler}
-     */
-    @Override
-    protected ExecutionHandler createExecutionHandler() {
-        return null;
-    }
-}
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServerFactory.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServerFactory.java
deleted file mode 100644
index d95d24a..0000000
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/OioSMTPServerFactory.java
+++ /dev/null
@@ -1,43 +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.smtpserver.netty;
-
-import javax.inject.Inject;
-
-import org.apache.james.dnsservice.api.DNSService;
-import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.metrics.api.MetricFactory;
-import org.apache.james.protocols.lib.handler.ProtocolHandlerLoader;
-import org.jboss.netty.util.HashedWheelTimer;
-
-public class OioSMTPServerFactory extends SMTPServerFactory {
-
-    @Inject
-    public OioSMTPServerFactory(DNSService dns, ProtocolHandlerLoader loader, FileSystem fileSystem,
-                                MetricFactory metricFactory, HashedWheelTimer hashedWheelTimer) {
-        super(dns, loader, fileSystem, metricFactory, hashedWheelTimer);
-    }
-
-    @Override
-    protected SMTPServer createServer() {
-        return new OioSMTPServer(smtpMetrics);
-    }
-
-}
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
index fbfcf55..8152716 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
@@ -26,14 +26,12 @@ import org.apache.james.protocols.netty.BasicChannelUpstreamHandler;
 import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.core.SMTPMDCContextFactory;
 import org.apache.james.smtpserver.SMTPConstants;
-import org.jboss.netty.channel.ChannelHandler.Sharable;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.MessageEvent;
+
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
 
 /**
- * {@link ChannelUpstreamHandler} which is used by the SMTPServer
+ * {@link BasicChannelUpstreamHandler} which is used by the SMTPServer
  */
 @Sharable
 public class SMTPChannelUpstreamHandler extends BasicChannelUpstreamHandler {
@@ -51,20 +49,20 @@ public class SMTPChannelUpstreamHandler extends BasicChannelUpstreamHandler {
     }
 
     @Override
-    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        super.channelConnected(ctx, e);
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        super.channelActive(ctx);
         smtpMetrics.getConnectionMetric().increment();
     }
 
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        super.messageReceived(ctx, e);
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        super.channelRead(ctx, msg);
         smtpMetrics.getCommandsMetric().increment();
     }
 
     @Override
-    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        super.channelDisconnected(ctx, e);
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        super.channelInactive(ctx);
         smtpMetrics.getConnectionMetric().decrement();
     }
 
@@ -74,7 +72,7 @@ public class SMTPChannelUpstreamHandler extends BasicChannelUpstreamHandler {
     @Override
     protected void cleanup(ChannelHandlerContext ctx) {
         // Make sure we dispose everything on exit on session close
-        SMTPSession smtpSession = (SMTPSession) ctx.getAttachment();
+        SMTPSession smtpSession = ctx.channel().attr(SMTPConstants.SMTP_SESSION_ATTRIBUTE_KEY).get();
 
         if (smtpSession != null) {
             smtpSession.getAttachment(SMTPConstants.MAIL, State.Transaction).ifPresent(LifecycleUtil::dispose);
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 1db4e7f..65d8904 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
@@ -46,10 +46,11 @@ import org.apache.james.smtpserver.CoreCmdHandlerLoader;
 import org.apache.james.smtpserver.ExtendedSMTPSession;
 import org.apache.james.smtpserver.jmx.JMXHandlersLoader;
 import org.apache.james.util.Size;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
 /**
  * NIO SMTPServer which use Netty
  */
@@ -387,7 +388,7 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe
     }
 
     @Override
-    protected ChannelUpstreamHandler createCoreHandler() {
+    protected ChannelInboundHandlerAdapter createCoreHandler() {
         return coreHandler;
     }
 
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServerFactory.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServerFactory.java
index cfd37f7..6e0be63 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServerFactory.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServerFactory.java
@@ -32,7 +32,6 @@ import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.protocols.lib.handler.ProtocolHandlerLoader;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.lib.netty.AbstractServerFactory;
-import org.jboss.netty.util.HashedWheelTimer;
 
 public class SMTPServerFactory extends AbstractServerFactory {
 
@@ -40,16 +39,14 @@ public class SMTPServerFactory extends AbstractServerFactory {
     protected final ProtocolHandlerLoader loader;
     protected final FileSystem fileSystem;
     protected final SmtpMetricsImpl smtpMetrics;
-    private final HashedWheelTimer hashedWheelTimer;
 
     @Inject
     public SMTPServerFactory(DNSService dns, ProtocolHandlerLoader loader, FileSystem fileSystem,
-                             MetricFactory metricFactory, HashedWheelTimer hashedWheelTimer) {
+                             MetricFactory metricFactory) {
         this.dns = dns;
         this.loader = loader;
         this.fileSystem = fileSystem;
         this.smtpMetrics = new SmtpMetricsImpl(metricFactory);
-        this.hashedWheelTimer = hashedWheelTimer;
     }
 
     protected SMTPServer createServer() {
@@ -67,7 +64,6 @@ public class SMTPServerFactory extends AbstractServerFactory {
             server.setDnsService(dns);
             server.setProtocolHandlerLoader(loader);
             server.setFileSystem(fileSystem);
-            server.setHashWheelTimer(hashedWheelTimer);
             server.configure(serverConfig);
             servers.add(server);
         }
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AuthAnnounceTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AuthAnnounceTest.java
index 3e2c5a4..bdf2458 100644
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AuthAnnounceTest.java
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AuthAnnounceTest.java
@@ -65,7 +65,6 @@ import org.apache.james.smtpserver.netty.SmtpMetricsImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.assertj.core.api.SoftAssertions;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -78,7 +77,6 @@ class AuthAnnounceTest {
     public static final Username BOB = Username.of("bob@localhost");
     public static final String PASSWORD = "bobpwd";
 
-    protected HashedWheelTimer hashedWheelTimer;
     protected MemoryDomainList domainList;
     protected MemoryUsersRepository usersRepository;
     protected SMTPServerTest.AlterableDNSServer dnsServer;
@@ -103,7 +101,6 @@ class AuthAnnounceTest {
         createMailRepositoryStore();
 
         setUpFakeLoader();
-        hashedWheelTimer = new HashedWheelTimer();
         setUpSMTPServer();
     }
 
@@ -136,7 +133,6 @@ class AuthAnnounceTest {
         smtpServer = createSMTPServer(smtpMetrics);
         smtpServer.setDnsService(dnsServer);
         smtpServer.setFileSystem(fileSystem);
-        smtpServer.setHashWheelTimer(hashedWheelTimer);
         smtpServer.setProtocolHandlerLoader(chain);
     }
 
@@ -167,7 +163,6 @@ class AuthAnnounceTest {
     @AfterEach
     void tearDown() {
         smtpServer.destroy();
-        hashedWheelTimer.stop();
     }
 
     @Test
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/DSNTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/DSNTest.java
index 8fc9c6d..5c68d72 100644
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/DSNTest.java
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/DSNTest.java
@@ -75,7 +75,6 @@ import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.mailet.DsnParameters;
 import org.apache.mailet.Mail;
 import org.assertj.core.api.SoftAssertions;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -88,7 +87,6 @@ class DSNTest {
     public static final Username BOB = Username.of("bob@localhost");
     public static final String PASSWORD = "bobpwd";
 
-    protected HashedWheelTimer hashedWheelTimer;
     protected MemoryDomainList domainList;
     protected MemoryUsersRepository usersRepository;
     protected SMTPServerTest.AlterableDNSServer dnsServer;
@@ -114,7 +112,6 @@ class DSNTest {
         createMailRepositoryStore();
 
         setUpFakeLoader();
-        hashedWheelTimer = new HashedWheelTimer();
         setUpSMTPServer();
     }
 
@@ -147,7 +144,6 @@ class DSNTest {
         smtpServer = createSMTPServer(smtpMetrics);
         smtpServer.setDnsService(dnsServer);
         smtpServer.setFileSystem(fileSystem);
-        smtpServer.setHashWheelTimer(hashedWheelTimer);
         smtpServer.setProtocolHandlerLoader(chain);
     }
 
@@ -178,7 +174,6 @@ class DSNTest {
     @AfterEach
     void tearDown() {
         smtpServer.destroy();
-        hashedWheelTimer.stop();
     }
 
     @Test
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/OioSMTPServerTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/OioSMTPServerTest.java
deleted file mode 100644
index f265d25..0000000
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/OioSMTPServerTest.java
+++ /dev/null
@@ -1,31 +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.smtpserver;
-
-import org.apache.james.smtpserver.netty.OioSMTPServer;
-import org.apache.james.smtpserver.netty.SMTPServer;
-import org.apache.james.smtpserver.netty.SmtpMetricsImpl;
-
-public class OioSMTPServerTest extends SMTPServerTest {
-
-    @Override
-    protected SMTPServer createSMTPServer(SmtpMetricsImpl smtpMetrics) {
-        return new OioSMTPServer(smtpMetrics);
-    }
-}
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java
index 0c07100..56f66f8 100644
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java
@@ -77,7 +77,6 @@ import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.util.ClassLoaderUtils;
 import org.assertj.core.api.SoftAssertions;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -101,7 +100,6 @@ class SMTPSaslTest {
     public static final String INVALID_TOKEN = OIDCSASLHelper.generateOauthBearer(USER.asString(), OidcTokenFixture.INVALID_TOKEN);
 
 
-    protected HashedWheelTimer hashedWheelTimer;
     protected MemoryDomainList domainList;
     protected MemoryUsersRepository usersRepository;
     protected SMTPServerTest.AlterableDNSServer dnsServer;
@@ -127,7 +125,6 @@ class SMTPSaslTest {
         createMailRepositoryStore();
 
         setUpFakeLoader();
-        hashedWheelTimer = new HashedWheelTimer();
         setUpSMTPServer();
 
         authServer = ClientAndServer.startClientAndServer(0);
@@ -175,7 +172,6 @@ class SMTPSaslTest {
         smtpServer = createSMTPServer(smtpMetrics);
         smtpServer.setDnsService(dnsServer);
         smtpServer.setFileSystem(fileSystem);
-        smtpServer.setHashWheelTimer(hashedWheelTimer);
         smtpServer.setProtocolHandlerLoader(chain);
     }
 
@@ -215,7 +211,6 @@ class SMTPSaslTest {
     @AfterEach
     void tearDown() {
         smtpServer.destroy();
-        hashedWheelTimer.stop();
         authServer.stop();
     }
 
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
index 303119d..8b357c8 100644
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
@@ -89,7 +89,6 @@ import org.apache.james.smtpserver.netty.SmtpMetricsImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.mailet.Mail;
-import org.jboss.netty.util.HashedWheelTimer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
@@ -189,7 +188,6 @@ public class SMTPServerTest {
     private static final Logger LOGGER = LoggerFactory.getLogger(SMTPServerTest.class);
 
     protected SMTPTestConfiguration smtpConfiguration;
-    protected HashedWheelTimer hashedWheelTimer;
     protected MemoryDomainList domainList;
     protected MemoryUsersRepository usersRepository;
     protected AlterableDNSServer dnsServer;
@@ -228,7 +226,6 @@ public class SMTPServerTest {
         // slf4j can't set programmatically any log level. It's just a facade
         // log.setLevel(SimpleLog.LOG_LEVEL_ALL);
         smtpConfiguration = new SMTPTestConfiguration();
-        hashedWheelTimer = new HashedWheelTimer();
         setUpSMTPServer();
     }
 
@@ -261,7 +258,6 @@ public class SMTPServerTest {
         smtpServer = createSMTPServer(smtpMetrics);
         smtpServer.setDnsService(dnsServer);
         smtpServer.setFileSystem(fileSystem);
-        smtpServer.setHashWheelTimer(hashedWheelTimer);
         smtpServer.setProtocolHandlerLoader(chain);
     }
 
@@ -373,7 +369,6 @@ public class SMTPServerTest {
         if (smtpServer.isStarted()) {
             smtpServer.destroy();
         }
-        hashedWheelTimer.stop();
     }
 
     public void verifyLastMail(String sender, String recipient, MimeMessage msg) throws Exception {

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


[james-project] 16/29: JAMES-3715 Avoid creating a CONTINUATION REQUEST on each IMAP request

Posted by bt...@apache.org.
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 69aa3169fdea63c392426bcd1b72f2114b0fd0ea
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 11 09:57:25 2022 +0700

    JAMES-3715 Avoid creating a CONTINUATION REQUEST on each IMAP request
    
    This field can be static, not modifiable. Creating it was taking up to
    1.7% of CPU decoding time
---
 .../james/imapserver/netty/AbstractNettyImapRequestLineReader.java | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
index a3f6c6a..9230b50 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/AbstractNettyImapRequestLineReader.java
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.james.imapserver.netty;
 
+import java.nio.charset.StandardCharsets;
+
 import org.apache.james.imap.decode.ImapRequestLineReader;
 
 import io.netty.buffer.ByteBuf;
@@ -25,8 +27,9 @@ import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 
 public abstract class AbstractNettyImapRequestLineReader extends ImapRequestLineReader {
+    private static final ByteBuf CONTINUATION_REQUEST = Unpooled.wrappedUnmodifiableBuffer(Unpooled.wrappedBuffer("+ Ok\r\n".getBytes(StandardCharsets.US_ASCII)));
+
     private final Channel channel;
-    private final ByteBuf cRequest = Unpooled.wrappedBuffer("+ Ok\r\n".getBytes());
     private final boolean retry;
 
     public AbstractNettyImapRequestLineReader(Channel channel, boolean retry) {
@@ -41,7 +44,7 @@ public abstract class AbstractNettyImapRequestLineReader extends ImapRequestLine
         // request..
 
         if (!retry) {
-            channel.writeAndFlush(cRequest);
+            channel.writeAndFlush(CONTINUATION_REQUEST);
         }
     }
 

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


[james-project] 14/29: JAMES-3715 IMAP: Improve threading model

Posted by bt...@apache.org.
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 2dffa1342f445e81d96f9eb02ad14e9177490b46
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 10 15:56:22 2022 +0700

    JAMES-3715 IMAP: Improve threading model
    
    We can do framing + chunck writing on the eventloop now.
    
    This prevents us from always switching on a distinct thread for
    these operations and dramatically improves performance.
---
 .../java/org/apache/james/imapserver/netty/IMAPServer.java     |  6 +++---
 .../apache/james/imapserver/netty/ImapRequestFrameDecoder.java | 10 +++-------
 2 files changed, 6 insertions(+), 10 deletions(-)

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 fda2bdb..f689024 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
@@ -230,7 +230,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(getExecutorGroup(), FRAMER, getFrameHandlerFactory().create(pipeline));
+                pipeline.addLast(FRAMER, getFrameHandlerFactory().create(pipeline));
                
                 Encryption secure = getEncryption();
                 if (secure != null && !secure.isStartTLS()) {
@@ -243,10 +243,10 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
                 }
                 pipeline.addLast(CONNECTION_COUNT_HANDLER, getConnectionCountHandler());
 
-                pipeline.addLast(getExecutorGroup(), CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
+                pipeline.addLast(CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
 
                 pipeline.addLast(getExecutorGroup(), REQUEST_DECODER, new ImapRequestFrameDecoder(decoder, inMemorySizeLimit,
-                    literalSizeLimit, getExecutorGroup(), maxLineLength));
+                    literalSizeLimit, maxLineLength));
 
                 pipeline.addLast(getExecutorGroup(), CORE_HANDLER, createCoreHandler());
             }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
index 027fd3c..fb5d363 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
@@ -45,7 +45,6 @@ import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.codec.ByteToMessageDecoder;
-import io.netty.util.concurrent.EventExecutorGroup;
 
 
 /**
@@ -62,15 +61,12 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
     private final int inMemorySizeLimit;
     private final int literalSizeLimit;
     private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
-    private final EventExecutorGroup eventExecutors;
-    private int maxFrameLength;
+    private final int maxFrameLength;
 
-    public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit, EventExecutorGroup eventExecutors,
-                                   int maxFrameLength) {
+    public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit, int maxFrameLength) {
         this.decoder = decoder;
         this.inMemorySizeLimit = inMemorySizeLimit;
         this.literalSizeLimit = literalSizeLimit;
-        this.eventExecutors = eventExecutors;
         this.maxFrameLength = maxFrameLength;
     }
 
@@ -224,7 +220,7 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
         if (ctx.channel().pipeline().get(FRAMER) == null) {
             ctx.channel().config().setAutoRead(false);
             ctx.channel().eventLoop().execute(() ->
-                ctx.channel().pipeline().addBefore(eventExecutors, REQUEST_DECODER, FRAMER,
+                ctx.channel().pipeline().addBefore(REQUEST_DECODER, FRAMER,
                         new SwitchableLineBasedFrameDecoder(ctx.channel().pipeline(), maxFrameLength, false)));
             ctx.channel().config().setAutoRead(true);
         }

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


[james-project] 13/29: JAMES-3715 IMAP: IdleStateHandler is not needed

Posted by bt...@apache.org.
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 ff9ecadba0093593c56dfe99f0e889a27f622ccb
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 10 15:53:41 2022 +0700

    JAMES-3715 IMAP: IdleStateHandler is not needed
    
    ImapIdleStateHandler subclasses it and is already present on the pipeline,
    no need to duplicate this feature.
---
 .../src/main/java/org/apache/james/imapserver/netty/IMAPServer.java  | 5 -----
 1 file changed, 5 deletions(-)

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 15132e3..fda2bdb 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
@@ -54,7 +54,6 @@ import io.netty.channel.ChannelPipeline;
 import io.netty.channel.group.ChannelGroup;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.handler.stream.ChunkedWriteHandler;
-import io.netty.handler.timeout.IdleStateHandler;
 
 
 /**
@@ -62,7 +61,6 @@ import io.netty.handler.timeout.IdleStateHandler;
  */
 public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapConstants, IMAPServerMBean, NettyConstants {
     private static final Logger LOG = LoggerFactory.getLogger(IMAPServer.class);
-    private static final int TIMEOUT_TIMER_DISABLED = 0;
 
     public static class AuthenticationConfiguration {
         private static final boolean PLAIN_AUTH_DISALLOWED_DEFAULT = true;
@@ -220,13 +218,10 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
 
             private final ChannelGroupHandler groupHandler = new ChannelGroupHandler(group);
 
-            private final TimeUnit timeoutUnit = TimeUnit.SECONDS;
-
             @Override
             public void initChannel(Channel channel) throws Exception {
                 ChannelPipeline pipeline = channel.pipeline();
                 pipeline.addLast(GROUP_HANDLER, groupHandler);
-                pipeline.addLast("idleHandler", new IdleStateHandler(TIMEOUT_TIMER_DISABLED, TIMEOUT_TIMER_DISABLED, timeout, timeoutUnit));
                 pipeline.addLast(TIMEOUT_HANDLER, new ImapIdleStateHandler(timeout));
                 pipeline.addLast(CONNECTION_LIMIT_HANDLER, new ConnectionLimitUpstreamHandler(IMAPServer.this.connectionLimit));
 

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


[james-project] 05/29: JAMES-3715 Remove no longer needed JMXEnabledThreadPoolExecutor

Posted by bt...@apache.org.
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 95d33ed677d2adbf69df4228a0a9e7ef434d28ac
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Feb 27 20:29:38 2022 +0700

    JAMES-3715 Remove no longer needed JMXEnabledThreadPoolExecutor
    
    This is dead code since the Netty 4 migration. Remove.
    
    We now have easier to exploit metrics (JMX, HTTP endpoint, logs, ES reportings)
    that expose more interesting applicative level metrics.
---
 .../concurrent/JMXEnabledThreadPoolExecutor.java   | 174 ---------------------
 1 file changed, 174 deletions(-)

diff --git a/server/container/util/src/main/java/org/apache/james/util/concurrent/JMXEnabledThreadPoolExecutor.java b/server/container/util/src/main/java/org/apache/james/util/concurrent/JMXEnabledThreadPoolExecutor.java
deleted file mode 100644
index fa55ede..0000000
--- a/server/container/util/src/main/java/org/apache/james/util/concurrent/JMXEnabledThreadPoolExecutor.java
+++ /dev/null
@@ -1,174 +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.util.concurrent;
-
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-/**
- * {@link ThreadPoolExecutor} which expose statistics via JMX
- */
-public class JMXEnabledThreadPoolExecutor extends ThreadPoolExecutor implements JMXEnabledThreadPoolExecutorMBean {
-
-    private final String jmxPath;
-    private final ThreadLocal<Long> startTime = new ThreadLocal<>();
-    private final AtomicLong totalTime = new AtomicLong(0);
-    private final AtomicInteger totalTasks = new AtomicInteger(0);
-    private MBeanServer mbeanServer;
-    private String mbeanName;
-
-    public JMXEnabledThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> queue, NamedThreadFactory tFactory, String jmxPath) {
-        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, queue, tFactory);
-        this.jmxPath = jmxPath;
-        registerMBean();
-    }
-
-    @Override
-    protected void beforeExecute(Thread t, Runnable r) {
-        super.beforeExecute(t, r);
-        startTime.set(System.currentTimeMillis());
-    }
-
-    @Override
-    protected void afterExecute(Runnable r, Throwable t) {
-        long time = System.currentTimeMillis() - startTime.get();
-        totalTasks.incrementAndGet();
-        totalTime.addAndGet(time);
-        super.afterExecute(r, t);
-    }
-
-    private void registerMBean() {
-        if (jmxPath != null) {
-            mbeanServer = ManagementFactory.getPlatformMBeanServer();
-            mbeanName = jmxPath + ",threadpool=" + ((NamedThreadFactory) getThreadFactory()).getName();
-            try {
-                mbeanServer.registerMBean(this, new ObjectName(mbeanName));
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to register mbean", e);
-            }
-        }
-    }
-
-    private void unregisterMBean() {
-        if (jmxPath != null) {
-            try {
-                mbeanServer.unregisterMBean(new ObjectName(mbeanName));
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to unregister mbean", e);
-            }
-        }
-    }
-
-    @Override
-    public synchronized void shutdown() {
-        // synchronized, because there is no way to access super.mainLock, which
-        // would be
-        // the preferred way to make this threadsafe
-        if (!isShutdown()) {
-            unregisterMBean();
-        }
-        super.shutdown();
-        startTime.remove();
-    }
-
-    @Override
-    public synchronized List<Runnable> shutdownNow() {
-        // synchronized, because there is no way to access super.mainLock, which
-        // would be
-        // the preferred way to make this threadsafe
-        if (!isShutdown()) {
-            unregisterMBean();
-        }
-        return super.shutdownNow();
-    }
-
-    @Override
-    public synchronized int getTotalTasks() {
-        return totalTasks.get();
-    }
-
-    @Override
-    public synchronized double getAverageTaskTime() {
-        return (totalTasks.get() == 0) ? 0 : totalTime.get() / totalTasks.get();
-    }
-
-    @Override
-    public int getActiveThreads() {
-        return getPoolSize();
-    }
-
-    @Override
-    public int getActiveTasks() {
-        return getActiveCount();
-    }
-
-    @Override
-    public int getQueuedTasks() {
-        return getQueue().size();
-    }
-
-    @Override
-    public int getMaximalThreads() {
-        return getMaximumPoolSize();
-    }
-
-    /**
-     * Create a cached instance of this class. If jmxPath is null it will not
-     * register itself to the {@link MBeanServer}
-     * 
-     * @param jmxPath
-     * @param name
-     * @return pool
-     * 
-     */
-    public static JMXEnabledThreadPoolExecutor newCachedThreadPool(String jmxPath, String name) {
-        return new JMXEnabledThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), NamedThreadFactory.withName(name), jmxPath);
-
-    }
-
-    /**
-     * Create a cached instance of this class. If jmxPath is null it will not
-     * register itself to the {@link MBeanServer}
-     * 
-     * @param jmxPath
-     * @param factory
-     * @return pool
-     */
-    public static JMXEnabledThreadPoolExecutor newCachedThreadPool(String jmxPath, NamedThreadFactory factory) {
-        return new JMXEnabledThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), factory, jmxPath);
-    }
-    
-    public static JMXEnabledThreadPoolExecutor newFixedThreadPool(String jmxPath, int nThreads, NamedThreadFactory threadFactory) {
-        return new JMXEnabledThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), threadFactory, jmxPath);
-    }
-    
-    public static JMXEnabledThreadPoolExecutor newFixedThreadPool(String jmxPath, String name, int nThreads) {
-        return newFixedThreadPool(jmxPath, nThreads, NamedThreadFactory.withName(name));
-    }
-}

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


[james-project] 06/29: JAMES-3715 Execute core handlers outside of the event loop

Posted by bt...@apache.org.
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 92dcc05469b17f014fc72711ec0c3269b4160b7b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 7 09:28:31 2022 +0700

    JAMES-3715 Execute core handlers outside of the event loop
    
    WIP SMTP pipelining is currently brokem
---
 .../protocols/netty/AbstractChannelPipelineFactory.java  | 13 ++++++++-----
 .../netty/AbstractSSLAwareChannelPipelineFactory.java    | 10 ++++++----
 .../protocols/netty/BasicChannelUpstreamHandler.java     | 11 +++++++----
 .../james/protocols/netty/NettyProtocolTransport.java    |  7 +++++--
 .../org/apache/james/protocols/netty/NettyServer.java    |  8 +++++---
 .../org/apache/james/imapserver/netty/IMAPServer.java    | 10 +++++-----
 .../lib/netty/AbstractConfigurableAsyncServer.java       | 16 ++++++++++++----
 .../AbstractExecutorAwareChannelPipelineFactory.java     |  5 +++--
 .../org/apache/james/lmtpserver/netty/LMTPServer.java    |  2 +-
 .../james/managesieveserver/netty/ManageSieveServer.java | 14 +++++++-------
 .../org/apache/james/pop3server/netty/POP3Server.java    |  2 +-
 .../smtpserver/netty/SMTPChannelUpstreamHandler.java     |  9 +++++----
 .../org/apache/james/smtpserver/netty/SMTPServer.java    |  2 +-
 13 files changed, 66 insertions(+), 43 deletions(-)

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 32049af..db4a1bd 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
@@ -25,6 +25,7 @@ import io.netty.channel.ChannelPipeline;
 import io.netty.channel.group.ChannelGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.handler.stream.ChunkedWriteHandler;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 /**
  * Abstract base class for {@link ChannelInitializer} implementations
@@ -38,19 +39,21 @@ public abstract class AbstractChannelPipelineFactory<C extends SocketChannel> ex
     private final ChannelGroupHandler groupHandler;
     private final int timeout;
     private final ChannelHandlerFactory frameHandlerFactory;
+    private final EventExecutorGroup eventExecutorGroup;
 
     public AbstractChannelPipelineFactory(ChannelGroup channels,
-                                          ChannelHandlerFactory frameHandlerFactory) {
-        this(0, 0, 0, channels, frameHandlerFactory);
+                                          ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
+        this(0, 0, 0, channels, frameHandlerFactory, eventExecutorGroup);
     }
 
     public AbstractChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, ChannelGroup channels,
-                                          ChannelHandlerFactory frameHandlerFactory) {
+                                          ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
         this.connectionLimitHandler = new ConnectionLimitUpstreamHandler(maxConnections);
         this.connectionPerIpLimitHandler = new ConnectionPerIpLimitUpstreamHandler(maxConnectsPerIp);
         this.groupHandler = new ChannelGroupHandler(channels);
         this.timeout = timeout;
         this.frameHandlerFactory = frameHandlerFactory;
+        this.eventExecutorGroup = eventExecutorGroup;
     }
     
     
@@ -66,13 +69,13 @@ public abstract class AbstractChannelPipelineFactory<C extends SocketChannel> ex
 
         
         // 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, frameHandlerFactory.create(pipeline));
+        pipeline.addLast(eventExecutorGroup, HandlerConstants.FRAMER, frameHandlerFactory.create(pipeline));
        
         // Add the ChunkedWriteHandler to be able to write ChunkInput
         pipeline.addLast(HandlerConstants.CHUNK_HANDLER, new ChunkedWriteHandler());
         pipeline.addLast(HandlerConstants.TIMEOUT_HANDLER, new TimeoutHandler(timeout));
 
-        pipeline.addLast(HandlerConstants.CORE_HANDLER, createHandler());
+        pipeline.addLast(eventExecutorGroup, HandlerConstants.CORE_HANDLER, createHandler());
     }
 
     
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 e509ee0..f3399c9 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
@@ -27,6 +27,7 @@ import io.netty.channel.ChannelPipeline;
 import io.netty.channel.group.ChannelGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.handler.ssl.SslHandler;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 
 /**
@@ -39,14 +40,15 @@ public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketCha
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
                                                   int maxConnections, int maxConnectsPerIp, ChannelGroup group,
-                                                  ChannelHandlerFactory frameHandlerFactory) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory);
+                                                  ChannelHandlerFactory frameHandlerFactory,
+                                                  EventExecutorGroup eventExecutorGroup) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory, eventExecutorGroup);
     }
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
             int maxConnections, int maxConnectsPerIp, ChannelGroup group, Encryption secure,
-            ChannelHandlerFactory frameHandlerFactory) {
-        this(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory);
+            ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
+        this(timeout, maxConnections, maxConnectsPerIp, group, frameHandlerFactory, eventExecutorGroup);
 
         this.secure = secure;
     }
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 08086a6..1cde815 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
@@ -51,6 +51,7 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.codec.TooLongFrameException;
 import io.netty.util.AttributeKey;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 
 /**
@@ -67,16 +68,18 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
     protected final Protocol protocol;
     protected final ProtocolHandlerChain chain;
     protected final Encryption secure;
+    private final EventExecutorGroup eventExecutors;
 
-    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol) {
-        this(mdcContextFactory, protocol, null);
+    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, EventExecutorGroup eventExecutors) {
+        this(mdcContextFactory, protocol, null, eventExecutors);
     }
 
-    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, Encryption secure) {
+    public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol, Encryption secure, EventExecutorGroup eventExecutors) {
         this.mdcContextFactory = mdcContextFactory;
         this.protocol = protocol;
         this.chain = protocol.getProtocolChain();
         this.secure = secure;
+        this.eventExecutors = eventExecutors;
     }
 
 
@@ -197,7 +200,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter {
             engine = secure.createSSLEngine();
         }
 
-        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine));
+        return protocol.newSession(new NettyProtocolTransport(ctx.channel(), engine, eventExecutors));
     }
 
     @Override
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
index 36d5ab8..bdeee67 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyProtocolTransport.java
@@ -38,6 +38,7 @@ import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.DefaultFileRegion;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.handler.stream.ChunkedStream;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 
 /**
@@ -47,11 +48,13 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
     
     private final Channel channel;
     private final SSLEngine engine;
+    private final EventExecutorGroup eventExecutors;
     private int lineHandlerCount = 0;
     
-    public NettyProtocolTransport(Channel channel, SSLEngine engine) {
+    public NettyProtocolTransport(Channel channel, SSLEngine engine, EventExecutorGroup eventExecutors) {
         this.channel = channel;
         this.engine = engine;
+        this.eventExecutors = eventExecutors;
     }
 
     @Override
@@ -156,7 +159,7 @@ public class NettyProtocolTransport extends AbstractProtocolTransport {
         // it is executed with the same ExecutorHandler as the coreHandler (if one exist)
         // 
         // See JAMES-1277
-        channel.pipeline().addBefore(HandlerConstants.CORE_HANDLER, "lineHandler" + lineHandlerCount, new LineHandlerUpstreamHandler(session, overrideCommandHandler));
+        channel.pipeline().addBefore(eventExecutors, HandlerConstants.CORE_HANDLER, "lineHandler" + lineHandlerCount, new LineHandlerUpstreamHandler(session, overrideCommandHandler));
     }
     
    
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 35da9a9..e50a498 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
@@ -28,8 +28,9 @@ import org.apache.james.protocols.api.Protocol;
 import com.google.common.base.Preconditions;
 
 import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.DefaultEventLoopGroup;
 import io.netty.channel.group.ChannelGroup;
-
+import io.netty.util.concurrent.DefaultEventExecutorGroup;
 
 
 /**
@@ -104,7 +105,7 @@ public class NettyServer extends AbstractAsyncServer {
     }
 
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure);
+        return new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, secure, new DefaultEventExecutorGroup(2));
     }
     
     @Override
@@ -126,7 +127,8 @@ public class NettyServer extends AbstractAsyncServer {
             maxCurConnectionsPerIP,
             group,
             secure,
-            getFrameHandlerFactory()) {
+            getFrameHandlerFactory(),
+            new DefaultEventLoopGroup(16)) {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
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 7896835..649f4a8 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
@@ -211,7 +211,7 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
     @Override
     protected AbstractChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
         
-        return new AbstractChannelPipelineFactory(group, getFrameHandlerFactory()) {
+        return new AbstractChannelPipelineFactory(group, getFrameHandlerFactory(), getExecutorGroup()) {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
@@ -235,7 +235,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, getFrameHandlerFactory().create(pipeline));
+                pipeline.addLast(getExecutorGroup(), FRAMER, getFrameHandlerFactory().create(pipeline));
                
                 Encryption secure = getEncryption();
                 if (secure != null && !secure.isStartTLS()) {
@@ -248,11 +248,11 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
                 }
                 pipeline.addLast(CONNECTION_COUNT_HANDLER, getConnectionCountHandler());
 
-                pipeline.addLast(CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
+                pipeline.addLast(getExecutorGroup(), CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
 
-                pipeline.addLast(REQUEST_DECODER, new ImapRequestFrameDecoder(decoder, inMemorySizeLimit, literalSizeLimit));
+                pipeline.addLast(getExecutorGroup(), REQUEST_DECODER, new ImapRequestFrameDecoder(decoder, inMemorySizeLimit, literalSizeLimit));
 
-                pipeline.addLast(CORE_HANDLER, createHandler());
+                pipeline.addLast(getExecutorGroup(), CORE_HANDLER, createCoreHandler());
             }
 
         };
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 1ccbd84..1da9ce6 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
@@ -48,6 +48,7 @@ import org.apache.james.protocols.lib.jmx.ServerMBean;
 import org.apache.james.protocols.netty.AbstractAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
+import org.apache.james.util.concurrent.NamedThreadFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,6 +56,8 @@ import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.group.ChannelGroup;
+import io.netty.util.concurrent.DefaultEventExecutorGroup;
+import io.netty.util.concurrent.EventExecutorGroup;
 import nl.altindag.ssl.SSLFactory;
 import nl.altindag.ssl.util.PemUtils;
 
@@ -118,7 +121,7 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
 
     private ChannelHandlerFactory frameHandlerFactory;
 
-    private int maxExecutorThreads;
+    private EventExecutorGroup executorGroup;
 
     private MBeanServer mbeanServer;
 
@@ -189,8 +192,8 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
         int ioWorker = config.getInt("ioWorkerCount", DEFAULT_IO_WORKER_COUNT);
         setIoWorkerCount(ioWorker);
 
-        maxExecutorThreads = config.getInt("maxExecutorCount", DEFAULT_MAX_EXECUTOR_COUNT);
-
+        executorGroup = new DefaultEventExecutorGroup(config.getInt("maxExecutorCount", DEFAULT_MAX_EXECUTOR_COUNT),
+            NamedThreadFactory.withName(jmxName));
         
         configureHelloName(config);
 
@@ -266,6 +269,10 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
 
     }
 
+    protected EventExecutorGroup getExecutorGroup() {
+        return executorGroup;
+    }
+
     @PostConstruct
     public final void init() throws Exception {
 
@@ -308,6 +315,7 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
         if (isEnabled()) {
             unbind();
             postDestroy();
+            executorGroup.shutdownGracefully();
 
             unregisterMBean();
         }
@@ -550,7 +558,7 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
     @Override
     protected AbstractChannelPipelineFactory createPipelineFactory(ChannelGroup group) {
         return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), connectionLimit, connPerIP, group,
-            getEncryption(), getFrameHandlerFactory()) {
+            getEncryption(), getFrameHandlerFactory(), getExecutorGroup()) {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
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 a4271eb..4890f3c 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
@@ -24,6 +24,7 @@ import org.apache.james.protocols.netty.ChannelHandlerFactory;
 
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.group.ChannelGroup;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 /**
  * Abstract base class which should get used if you MAY need an {@link ExecutionHandler}
@@ -35,8 +36,8 @@ public abstract class AbstractExecutorAwareChannelPipelineFactory extends Abstra
 
     public AbstractExecutorAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp,
                                                        ChannelGroup group, Encryption encryption,
-                                                       ChannelHandlerFactory frameHandlerFactory) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, encryption, frameHandlerFactory);
+                                                       ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, encryption, frameHandlerFactory, eventExecutorGroup);
     }
     
     /**
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 7899a7a..0596813 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
@@ -142,7 +142,7 @@ public class LMTPServer extends AbstractProtocolAsyncServer implements LMTPServe
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
         SMTPProtocol protocol = new SMTPProtocol(getProtocolHandlerChain(), lmtpConfig);
-        return new SMTPChannelUpstreamHandler(protocol, lmtpMetrics);
+        return new SMTPChannelUpstreamHandler(protocol, lmtpMetrics, getExecutorGroup());
     }
 
     @Override
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 e9f35fa..294ddc7 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
@@ -86,7 +86,7 @@ public class ManageSieveServer extends AbstractConfigurableAsyncServer implement
     @Override
     protected AbstractChannelPipelineFactory createPipelineFactory(final ChannelGroup group) {
 
-        return new AbstractChannelPipelineFactory(group, createFrameHandlerFactory()) {
+        return new AbstractChannelPipelineFactory(group, createFrameHandlerFactory(), getExecutorGroup()) {
 
             @Override
             protected ChannelInboundHandlerAdapter createHandler() {
@@ -113,13 +113,13 @@ 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, getFrameHandlerFactory().create(pipeline));
-                pipeline.addLast(CONNECTION_COUNT_HANDLER, getConnectionCountHandler());
-                pipeline.addLast(CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
+                pipeline.addLast(getExecutorGroup(), FRAMER, getFrameHandlerFactory().create(pipeline));
+                pipeline.addLast(getExecutorGroup(), CONNECTION_COUNT_HANDLER, getConnectionCountHandler());
+                pipeline.addLast(getExecutorGroup(), CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
 
-                pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
-                pipeline.addLast(CORE_HANDLER, createHandler());
-                pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
+                pipeline.addLast(getExecutorGroup(), "stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
+                pipeline.addLast(getExecutorGroup(), CORE_HANDLER, createHandler());
+                pipeline.addLast(getExecutorGroup(), "stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
             }
 
         };
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 242874a..f05ec6c 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
@@ -77,7 +77,7 @@ public class POP3Server extends AbstractProtocolAsyncServer implements POP3Serve
     protected void preInit() throws Exception {
         super.preInit();
         POP3Protocol protocol = new POP3Protocol(getProtocolHandlerChain(), theConfigData);
-        coreHandler = new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, getEncryption());
+        coreHandler = new BasicChannelUpstreamHandler(new ProtocolMDCContextFactory.Standard(), protocol, getEncryption(), getExecutorGroup());
     }
 
     @Override
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
index 8152716..5379db5 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPChannelUpstreamHandler.java
@@ -29,6 +29,7 @@ import org.apache.james.smtpserver.SMTPConstants;
 
 import io.netty.channel.ChannelHandler.Sharable;
 import io.netty.channel.ChannelHandlerContext;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 /**
  * {@link BasicChannelUpstreamHandler} which is used by the SMTPServer
@@ -38,13 +39,13 @@ public class SMTPChannelUpstreamHandler extends BasicChannelUpstreamHandler {
 
     private final SmtpMetrics smtpMetrics;
 
-    public SMTPChannelUpstreamHandler(Protocol protocol, Encryption encryption, SmtpMetrics smtpMetrics) {
-        super(new SMTPMDCContextFactory(), protocol, encryption);
+    public SMTPChannelUpstreamHandler(Protocol protocol, Encryption encryption, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
+        super(new SMTPMDCContextFactory(), protocol, encryption, eventExecutorGroup);
         this.smtpMetrics = smtpMetrics;
     }
 
-    public SMTPChannelUpstreamHandler(Protocol protocol, SmtpMetrics smtpMetrics) {
-        super(new SMTPMDCContextFactory(), protocol);
+    public SMTPChannelUpstreamHandler(Protocol protocol, SmtpMetrics smtpMetrics, EventExecutorGroup eventExecutorGroup) {
+        super(new SMTPMDCContextFactory(), protocol, eventExecutorGroup);
         this.smtpMetrics = smtpMetrics;
     }
 
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 65d8904..83f1534 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
@@ -219,7 +219,7 @@ public class SMTPServer extends AbstractProtocolAsyncServer implements SMTPServe
             }
             
         };
-        coreHandler = new SMTPChannelUpstreamHandler(transport, getEncryption(), smtpMetrics);
+        coreHandler = new SMTPChannelUpstreamHandler(transport, getEncryption(), smtpMetrics, getExecutorGroup());
     }
 
     @Override

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


[james-project] 12/29: JAMES-3715 IMAP fix framer issues (IndexOutOfBound on bytebuf when turned on/off)

Posted by bt...@apache.org.
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 3222c5dcbb2886c5c75cacd29917b8997e32777e
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Mar 9 15:43:31 2022 +0700

    JAMES-3715 IMAP fix framer issues (IndexOutOfBound on bytebuf when turned on/off)
    
    This execption was raised for commands following a IMAP APPEND
    (that did turn off and on the framer), Issue was happening all the time following
    threading model changes.
    
    ```
    java.lang.IndexOutOfBoundsException: index: 24, length: -15 (expected: range(0, 65536))
    	at io.netty.buffer.AbstractByteBuf.checkRangeBounds(AbstractByteBuf.java:1390)
    	at io.netty.buffer.AbstractByteBuf.checkIndex0(AbstractByteBuf.java:1397)
    	at io.netty.buffer.AbstractByteBuf.checkIndex(AbstractByteBuf.java:1384)
    	at io.netty.buffer.AbstractByteBuf.forEachByte(AbstractByteBuf.java:1290)
    	at io.netty.handler.codec.LineBasedFrameDecoder.findEndOfLine(LineBasedFrameDecoder.java:169)
    	at io.netty.handler.codec.LineBasedFrameDecoder.decode(LineBasedFrameDecoder.java:99)
    	at org.apache.james.protocols.netty.AllButStartTlsLineBasedChannelHandler.decode(AllButStartTlsLineBasedChannelHandler.java:61)
    	at io.netty.handler.codec.LineBasedFrameDecoder.decode(LineBasedFrameDecoder.java:84)
    	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507)
    	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:446)
    	... 10 common frames omitted
    Wrapped by: io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: index: 24, length: -15 (expected: range(0, 65536))
    	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:477)
    	at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:404)
    	at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:371)
    	at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
    	at io.netty.channel.AbstractChannelHandlerContext.access$300(AbstractChannelHandlerContext.java:61)
    	at io.netty.channel.AbstractChannelHandlerContext$4.run(AbstractChannelHandlerContext.java:253)
    	at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66)
    	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
    	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    	at java.base/java.lang.Thread.run(Thread.java:829)
    ```
---
 .../apache/james/imapserver/netty/IMAPServer.java  |  3 +-
 .../imapserver/netty/ImapRequestFrameDecoder.java  | 39 +++++++++++++++++-----
 .../netty/SwitchableLineBasedFrameDecoder.java     | 26 ---------------
 3 files changed, 32 insertions(+), 36 deletions(-)

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 649f4a8..15132e3 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
@@ -250,7 +250,8 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
 
                 pipeline.addLast(getExecutorGroup(), CHUNK_WRITE_HANDLER, new ChunkedWriteHandler());
 
-                pipeline.addLast(getExecutorGroup(), REQUEST_DECODER, new ImapRequestFrameDecoder(decoder, inMemorySizeLimit, literalSizeLimit));
+                pipeline.addLast(getExecutorGroup(), REQUEST_DECODER, new ImapRequestFrameDecoder(decoder, inMemorySizeLimit,
+                    literalSizeLimit, getExecutorGroup(), maxLineLength));
 
                 pipeline.addLast(getExecutorGroup(), CORE_HANDLER, createCoreHandler());
             }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
index 485362b..027fd3c 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
@@ -44,8 +44,8 @@ import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelPipeline;
 import io.netty.handler.codec.ByteToMessageDecoder;
+import io.netty.util.concurrent.EventExecutorGroup;
 
 
 /**
@@ -62,11 +62,16 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
     private final int inMemorySizeLimit;
     private final int literalSizeLimit;
     private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
+    private final EventExecutorGroup eventExecutors;
+    private int maxFrameLength;
 
-    public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit) {
+    public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit, EventExecutorGroup eventExecutors,
+                                   int maxFrameLength) {
         this.decoder = decoder;
         this.inMemorySizeLimit = inMemorySizeLimit;
         this.literalSizeLimit = literalSizeLimit;
+        this.eventExecutors = eventExecutors;
+        this.maxFrameLength = maxFrameLength;
     }
 
     @Override
@@ -180,7 +185,7 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
                     reader.consumeLine();
                 }
                 
-                ((SwitchableLineBasedFrameDecoder) ctx.channel().pipeline().get(FRAMER)).enableFraming();
+                enableFraming(ctx);
                 
                 attachment.clear();
                 out.add(message);
@@ -190,15 +195,15 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
                 int neededData = e.getNeededSize();
                 // store the needed data size for later usage
                 attachment.put(NEEDED_DATA, neededData);
-                
-                final ChannelPipeline pipeline = ctx.channel().pipeline();
-                final ChannelHandlerContext framerContext = pipeline.context(FRAMER);
 
                 // SwitchableDelimiterBasedFrameDecoder added further to JAMES-1436.
-                final SwitchableLineBasedFrameDecoder framer = (SwitchableLineBasedFrameDecoder) pipeline.get(FRAMER);
-
+                disableFraming(ctx);
+                if (in.readableBytes() > 0) {
+                    ByteBuf spareBytes = in.retainedDuplicate();
+                    internalBuffer().clear();
+                    ctx.fireChannelRead(spareBytes);
+                }
                 in.resetReaderIndex();
-                framer.disableFraming(framerContext);
             }
         } else {
             // The session was null so may be the case because the channel was already closed but there were still bytes in the buffer.
@@ -209,6 +214,22 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
         }
     }
 
+    public void disableFraming(ChannelHandlerContext ctx) {
+        ctx.channel().config().setAutoRead(false);
+        ctx.channel().eventLoop().execute(() -> ctx.channel().pipeline().remove(FRAMER));
+        ctx.channel().config().setAutoRead(true);
+    }
+
+    public void enableFraming(ChannelHandlerContext ctx) {
+        if (ctx.channel().pipeline().get(FRAMER) == null) {
+            ctx.channel().config().setAutoRead(false);
+            ctx.channel().eventLoop().execute(() ->
+                ctx.channel().pipeline().addBefore(eventExecutors, REQUEST_DECODER, FRAMER,
+                        new SwitchableLineBasedFrameDecoder(ctx.channel().pipeline(), maxFrameLength, false)));
+            ctx.channel().config().setAutoRead(true);
+        }
+    }
+
     @Override
     public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
         behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java
index 7ad1257..2f4d117 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineBasedFrameDecoder.java
@@ -25,43 +25,17 @@ import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.protocols.api.CommandDetectionSession;
 import org.apache.james.protocols.netty.AllButStartTlsLineBasedChannelHandler;
 
-import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPipeline;
 
 public class SwitchableLineBasedFrameDecoder extends AllButStartTlsLineBasedChannelHandler {
     public static final String PATTERN = ImapConstants.STARTTLS_COMMAND.getName().toLowerCase();
 
-    private volatile boolean framingEnabled = true;
-
     public SwitchableLineBasedFrameDecoder(ChannelPipeline pipeline, int maxFrameLength, boolean stripDelimiter) {
         super(pipeline, maxFrameLength, stripDelimiter, PATTERN);
     }
 
     @Override
-    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        if (this.framingEnabled) {
-            super.channelRead(ctx, msg);
-        } else {
-            ctx.fireChannelRead(msg);
-        }
-    }
-
-    public synchronized void enableFraming() {
-        this.framingEnabled = true;
-    }
-
-    public synchronized void disableFraming(ChannelHandlerContext ctx) {
-        this.framingEnabled = false;
-
-        if (internalBuffer().readableBytes() > 0) {
-            ByteBuf spareBytes = internalBuffer().retainedDuplicate();
-            internalBuffer().clear();
-            ctx.fireChannelRead(spareBytes);
-        }
-    }
-
-    @Override
     protected CommandDetectionSession retrieveSession(ChannelHandlerContext ctx) {
         return ctx.channel().attr(NettyConstants.IMAP_SESSION_ATTRIBUTE_KEY).get();
     }

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


[james-project] 08/29: JAMES-3715 IMAP incorporate line overrides to the frame decoder

Posted by bt...@apache.org.
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 c8d2e984132be2761b4b9a472d48c59ce7c89d5f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 7 15:07:00 2022 +0700

    JAMES-3715 IMAP incorporate line overrides to the frame decoder
---
 .../netty/BasicChannelUpstreamHandler.java         |  6 ++--
 .../james/protocols/netty/LineHandlerAware.java    |  4 ++-
 .../imapserver/netty/ImapLineHandlerAdapter.java   |  2 +-
 .../imapserver/netty/ImapRequestFrameDecoder.java  | 34 ++++++++++++++++++----
 .../james/imapserver/netty/NettyImapSession.java   | 12 ++++----
 5 files changed, 41 insertions(+), 17 deletions(-)

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 8534a99..96a9d0d 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
@@ -68,7 +68,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter im
     protected final Protocol protocol;
     protected final ProtocolHandlerChain chain;
     protected final Encryption secure;
-    private final Deque<LineHandlerUpstreamHandler> behaviourOverrides = new ConcurrentLinkedDeque<>();
+    private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
 
     public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol) {
         this(mdcContextFactory, protocol, null);
@@ -150,7 +150,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter im
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        LineHandlerUpstreamHandler override = Iterables.getFirst(behaviourOverrides, null);
+        ChannelInboundHandlerAdapter override = Iterables.getFirst(behaviourOverrides, null);
         if (override != null) {
             override.channelRead(ctx, msg);
             return;
@@ -240,7 +240,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter im
     }
 
     @Override
-    public void pushLineHandler(LineHandlerUpstreamHandler lineHandlerUpstreamHandler) {
+    public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
         behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
     }
 
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
index 516dadf..355d1c8 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
@@ -1,7 +1,9 @@
 package org.apache.james.protocols.netty;
 
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
 public interface LineHandlerAware {
-    void pushLineHandler(LineHandlerUpstreamHandler lineHandlerUpstreamHandler);
+    void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler);
 
     void popLineHandler();
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
index 82f1ac6..2f1f260 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
@@ -44,7 +44,7 @@ public class ImapLineHandlerAdapter extends ChannelInboundHandlerAdapter {
     }
 
     @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+    public void channelRead(ChannelHandlerContext ctx, Object msg) {
         ByteBuf buf = (ByteBuf) msg;
         byte[] data;
         if (buf.hasArray()) {
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
index 696e54f..485362b 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
@@ -23,22 +23,27 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentLinkedDeque;
 
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.decode.ImapDecoder;
 import org.apache.james.imap.decode.ImapRequestLineReader;
+import org.apache.james.protocols.netty.LineHandlerAware;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Iterables;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelPipeline;
 import io.netty.handler.codec.ByteToMessageDecoder;
 
@@ -46,17 +51,18 @@ import io.netty.handler.codec.ByteToMessageDecoder;
 /**
  * {@link ByteToMessageDecoder} which will decode via and {@link ImapDecoder} instance
  */
-public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements NettyConstants {
-
-    private final ImapDecoder decoder;
-    private final int inMemorySizeLimit;
-    private final int literalSizeLimit;
+public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements NettyConstants, LineHandlerAware {
     @VisibleForTesting
     static final String NEEDED_DATA = "NEEDED_DATA";
     private static final String STORED_DATA = "STORED_DATA";
     private static final String WRITTEN_DATA = "WRITTEN_DATA";
     private static final String OUTPUT_STREAM = "OUTPUT_STREAM";
 
+    private final ImapDecoder decoder;
+    private final int inMemorySizeLimit;
+    private final int literalSizeLimit;
+    private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
+
     public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit) {
         this.decoder = decoder;
         this.inMemorySizeLimit = inMemorySizeLimit;
@@ -72,6 +78,12 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
     @Override
     @SuppressWarnings("unchecked")
     protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+        ChannelInboundHandlerAdapter override = Iterables.getFirst(behaviourOverrides, null);
+        if (override != null) {
+            override.channelRead(ctx, in);
+            return;
+        }
+
         in.markReaderIndex();
         boolean retry = false;
 
@@ -196,4 +208,16 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
             }
         }
     }
+
+    @Override
+    public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
+        behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
+    }
+
+    @Override
+    public void popLineHandler() {
+        if (!behaviourOverrides.isEmpty()) {
+            behaviourOverrides.removeFirst();
+        }
+    }
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index a70a8a6..11223ef 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -28,6 +28,7 @@ import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.protocols.netty.LineHandlerAware;
 
 import io.netty.channel.Channel;
 import io.netty.handler.codec.compression.JZlibDecoder;
@@ -44,7 +45,6 @@ public class NettyImapSession implements ImapSession, NettyConstants {
     private final Encryption secure;
     private final boolean compress;
     private final Channel channel;
-    private int handlerCount;
     private final boolean requiredSSL;
     private final boolean plainAuthEnabled;
     private final SessionId sessionId;
@@ -195,16 +195,14 @@ public class NettyImapSession implements ImapSession, NettyConstants {
 
     @Override
     public void pushLineHandler(ImapLineHandler lineHandler) {
-        channel.config().setAutoRead(false);
-        channel.pipeline().addBefore(REQUEST_DECODER, "lineHandler" + handlerCount++, new ImapLineHandlerAdapter(this, lineHandler));
-        channel.config().setAutoRead(true);
+        LineHandlerAware handler = (LineHandlerAware) channel.pipeline().get(REQUEST_DECODER);
+        handler.pushLineHandler(new ImapLineHandlerAdapter(this, lineHandler));
     }
 
     @Override
     public void popLineHandler() {
-        channel.config().setAutoRead(false);
-        channel.pipeline().remove("lineHandler" + --handlerCount);
-        channel.config().setAutoRead(true);
+        LineHandlerAware handler = (LineHandlerAware) channel.pipeline().get(REQUEST_DECODER);
+        handler.popLineHandler();
     }
 
     @Override

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


[james-project] 15/29: JAMES-3715 IMAP: We no longer have EXECUTION_HANDLER in Netty 4

Posted by bt...@apache.org.
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 c62f06b4d40ddd1c4854adb7266409d778af9553
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 10 15:59:20 2022 +0700

    JAMES-3715 IMAP: We no longer have EXECUTION_HANDLER in Netty 4
---
 .../apache/james/imapserver/netty/ImapChannelUpstreamHandler.java   | 6 +-----
 .../main/java/org/apache/james/imapserver/netty/NettyConstants.java | 1 -
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java
index c264e11..d9017cf 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapChannelUpstreamHandler.java
@@ -249,11 +249,7 @@ public class ImapChannelUpstreamHandler extends ChannelInboundHandlerAdapter imp
 
             try {
                 try {
-                    if (cp.get(NettyConstants.EXECUTION_HANDLER) != null) {
-                        cp.addBefore(NettyConstants.EXECUTION_HANDLER, NettyConstants.HEARTBEAT_HANDLER, heartbeatHandler);
-                    } else {
-                        cp.addBefore(NettyConstants.CORE_HANDLER, NettyConstants.HEARTBEAT_HANDLER, heartbeatHandler);
-                    }
+                    cp.addBefore(NettyConstants.CORE_HANDLER, NettyConstants.HEARTBEAT_HANDLER, heartbeatHandler);
                 } catch (IllegalArgumentException e) {
                     LOGGER.info("heartbeat handler is already part of this pipeline", e);
                 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
index 4733fb4..68bbd6d 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyConstants.java
@@ -41,7 +41,6 @@ public interface NettyConstants {
     String CONNECTION_LIMIT_PER_IP_HANDLER = "connectionPerIpLimitHandler";
     String CONNECTION_COUNT_HANDLER = "connectionCountHandler";
     String CHUNK_WRITE_HANDLER = "chunkWriteHandler";
-    String EXECUTION_HANDLER = "executionHandler";
     String HEARTBEAT_HANDLER = "heartbeatHandler";
 
     AttributeKey<ImapSession> IMAP_SESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("ImapSession");

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


[james-project] 22/29: JAMES-3715 Fix IDLE when COMPRESS is enabled

Posted by bt...@apache.org.
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 999d2c4d07532823d444c8d1f95aeb3ea820c6e7
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 17 16:01:48 2022 +0700

    JAMES-3715 Fix IDLE when COMPRESS is enabled
    
    Copy-less array did not account for offsets resulting in undesirable behaviour.
    
    Note that this is triggered only for line handlers and thus is irrelevant
    performance wise.
---
 .../apache/james/imapserver/netty/ImapLineHandlerAdapter.java    | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
index 2f1f260..c03e8d7 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
@@ -46,13 +46,8 @@ public class ImapLineHandlerAdapter extends ChannelInboundHandlerAdapter {
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) {
         ByteBuf buf = (ByteBuf) msg;
-        byte[] data;
-        if (buf.hasArray()) {
-            data = buf.array();
-        } else {
-            data = new byte[buf.readableBytes()];
-            buf.readBytes(data);
-        }
+        byte[] data = new byte[buf.readableBytes()];
+        buf.readBytes(data);
         lineHandler.onLine(session, data);
     }
 

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


[james-project] 29/29: JAMES-3715 netty-all dependency in protocols-imap4 is no longer needed for testing

Posted by bt...@apache.org.
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 acb10d396e9588f122bc2e793ec77d4e53df9c69
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 21 10:49:49 2022 +0700

    JAMES-3715 netty-all dependency in protocols-imap4 is no longer needed for testing
---
 server/protocols/protocols-imap4/pom.xml | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/server/protocols/protocols-imap4/pom.xml b/server/protocols/protocols-imap4/pom.xml
index ad3c82b..c370277 100644
--- a/server/protocols/protocols-imap4/pom.xml
+++ b/server/protocols/protocols-imap4/pom.xml
@@ -141,11 +141,6 @@
             <artifactId>netty-handler</artifactId>
         </dependency>
         <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-all</artifactId>
-            <version>4.1.72.Final</version>
-        </dependency>
-        <dependency>
             <groupId>io.projectreactor.netty</groupId>
             <artifactId>reactor-netty-core</artifactId>
             <scope>test</scope>

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