You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2017/08/24 03:46:31 UTC

[06/38] james-project git commit: JAMES-2114 MDC logging context for SMTP LMTP and POP3

JAMES-2114 MDC logging context for SMTP LMTP and POP3


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

Branch: refs/heads/master
Commit: 8d4254a94757100389c1869a9fbbf8bd2cadfb97
Parents: f998640
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 14 11:49:03 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 24 10:34:42 2017 +0700

----------------------------------------------------------------------
 .../apache/james/protocols/api/Protocol.java    |   1 +
 .../james/protocols/api/ProtocolImpl.java       |   2 +-
 protocols/netty/pom.xml                         |   4 +
 .../netty/BasicChannelUpstreamHandler.java      | 163 ++++++++++---------
 .../protocols/netty/ProtocolMDCContext.java     |  71 ++++++++
 protocols/pom.xml                               |   5 +
 .../james/protocols/pop3/POP3Protocol.java      |   6 +-
 .../james/protocols/smtp/SMTPProtocol.java      |   4 +
 8 files changed, 179 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/api/src/main/java/org/apache/james/protocols/api/Protocol.java
----------------------------------------------------------------------
diff --git a/protocols/api/src/main/java/org/apache/james/protocols/api/Protocol.java b/protocols/api/src/main/java/org/apache/james/protocols/api/Protocol.java
index 551fda2..23e7341 100644
--- a/protocols/api/src/main/java/org/apache/james/protocols/api/Protocol.java
+++ b/protocols/api/src/main/java/org/apache/james/protocols/api/Protocol.java
@@ -26,6 +26,7 @@ import org.slf4j.Logger;
  * Define a protocol
  */
 public interface Protocol {
+    String getName();
 
     /**
      * Return the {@link ProtocolHandlerChain} which is defined for the {@link Protocol}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolImpl.java
----------------------------------------------------------------------
diff --git a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolImpl.java b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolImpl.java
index 003aed4..a010c54 100644
--- a/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolImpl.java
+++ b/protocols/api/src/main/java/org/apache/james/protocols/api/ProtocolImpl.java
@@ -26,7 +26,7 @@ import org.slf4j.Logger;
  * Basic {@link Protocol} implementation 
  *
  */
-public class ProtocolImpl implements Protocol{
+public abstract class ProtocolImpl implements Protocol{
     private final ProtocolHandlerChain chain;
     private final ProtocolConfiguration config;
     protected final Logger logger;

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/netty/pom.xml
----------------------------------------------------------------------
diff --git a/protocols/netty/pom.xml b/protocols/netty/pom.xml
index e1e0588..3d68079 100644
--- a/protocols/netty/pom.xml
+++ b/protocols/netty/pom.xml
@@ -39,6 +39,10 @@
             <artifactId>protocols-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-util-java8</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java
----------------------------------------------------------------------
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java
index 2b7c481..16d43cc 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
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.james.protocols.netty;
 
+import java.io.Closeable;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -69,8 +70,10 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
 
     @Override
     public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        ctx.setAttachment(createSession(ctx));
-        super.channelBound(ctx, e);
+        try (Closeable closeable = ProtocolMDCContext.from(protocol, ctx)) {
+            ctx.setAttachment(createSession(ctx));
+            super.channelBound(ctx, e);
+        }
     }
 
 
@@ -81,32 +84,34 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        List<ConnectHandler> connectHandlers = chain.getHandlers(ConnectHandler.class);
-        List<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
-        ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-        session.getLogger().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) {
-                    // Disable till PROTOCOLS-37 is implemented
-                    if (response instanceof FutureResponse) {
-                        session.getLogger().debug("ProtocolHandlerResultHandler are not supported for FutureResponse yet");
-                        break;
+        try (Closeable closeable = ProtocolMDCContext.from(protocol, ctx)) {
+            List<ConnectHandler> connectHandlers = chain.getHandlers(ConnectHandler.class);
+            List<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
+            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+            session.getLogger().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) {
+                        // Disable till PROTOCOLS-37 is implemented
+                        if (response instanceof FutureResponse) {
+                            session.getLogger().debug("ProtocolHandlerResultHandler are not supported for FutureResponse yet");
+                            break;
+                        }
+                        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);
                     }
-                    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.channelConnected(ctx, e);
         }
-        super.channelConnected(ctx, e);
     }
 
 
@@ -114,14 +119,16 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
     @SuppressWarnings({ "rawtypes", "unchecked" })
 	@Override
     public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        List<DisconnectHandler> connectHandlers = chain.getHandlers(DisconnectHandler.class);
-        ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-        if (connectHandlers != null) {
-            for (DisconnectHandler connectHandler : connectHandlers) {
-                connectHandler.onDisconnect(session);
+        try (Closeable closeable = ProtocolMDCContext.from(protocol, ctx)) {
+            List<DisconnectHandler> connectHandlers = chain.getHandlers(DisconnectHandler.class);
+            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+            if (connectHandlers != null) {
+                for (DisconnectHandler connectHandler : connectHandlers) {
+                    connectHandler.onDisconnect(session);
+                }
             }
+            super.channelDisconnected(ctx, e);
         }
-        super.channelDisconnected(ctx, e);
     }
 
 
@@ -131,45 +138,49 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        ProtocolSession pSession = (ProtocolSession) ctx.getAttachment();
-        LinkedList<LineHandler> lineHandlers = chain.getHandlers(LineHandler.class);
-        LinkedList<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
+        try (Closeable closeable = ProtocolMDCContext.from(protocol, ctx)) {
+            ProtocolSession pSession = (ProtocolSession) ctx.getAttachment();
+            LinkedList<LineHandler> lineHandlers = chain.getHandlers(LineHandler.class);
+            LinkedList<ProtocolHandlerResultHandler> resultHandlers = chain.getHandlers(ProtocolHandlerResultHandler.class);
 
-        
-        if (lineHandlers.size() > 0) {
-        
-            ChannelBuffer buf = (ChannelBuffer) e.getMessage();      
-            LineHandler lHandler=  (LineHandler) lineHandlers.getLast();
-            long start = System.currentTimeMillis();            
-            Response response = lHandler.onLine(pSession,buf.toByteBuffer());
-            long executionTime = System.currentTimeMillis() - start;
-
-            for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
-                // Disable till PROTOCOLS-37 is implemented
-                if (response instanceof FutureResponse) {
-                    pSession.getLogger().debug("ProtocolHandlerResultHandler are not supported for FutureResponse yet");
-                    break;
+
+            if (lineHandlers.size() > 0) {
+
+                ChannelBuffer buf = (ChannelBuffer) e.getMessage();
+                LineHandler lHandler = (LineHandler) lineHandlers.getLast();
+                long start = System.currentTimeMillis();
+                Response response = lHandler.onLine(pSession, buf.toByteBuffer());
+                long executionTime = System.currentTimeMillis() - start;
+
+                for (ProtocolHandlerResultHandler resultHandler : resultHandlers) {
+                    // Disable till PROTOCOLS-37 is implemented
+                    if (response instanceof FutureResponse) {
+                        pSession.getLogger().debug("ProtocolHandlerResultHandler are not supported for FutureResponse yet");
+                        break;
+                    }
+                    response = resultHandler.onResponse(pSession, response, executionTime, lHandler);
                 }
-                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);
+                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);
+                }
+
             }
 
+            super.messageReceived(ctx, e);
         }
-        
-        super.messageReceived(ctx, e);
     }
 
 
     @Override
     public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
-        ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-        getLogger(session).info("Connection closed for " + session.getRemoteAddress().getAddress().getHostAddress());
-        cleanup(ctx);
+        try (Closeable closeable = ProtocolMDCContext.from(protocol, ctx)) {
+            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+            getLogger(session).info("Connection closed for " + session.getRemoteAddress().getAddress().getHostAddress());
+            cleanup(ctx);
 
-        super.channelClosed(ctx, e);
+            super.channelClosed(ctx, e);
+        }
     }
 
     /**
@@ -202,26 +213,28 @@ public class BasicChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
 
     @Override
     public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
-        Channel channel = ctx.getChannel();
-        ProtocolSession session = (ProtocolSession) ctx.getAttachment();
-        if (e.getCause() 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) {
-                ProtocolTransport transport = ((ProtocolSessionImpl)session).getProtocolTransport();
-
-                Response r = session.newFatalErrorResponse();
+        try (Closeable closeable = ProtocolMDCContext.from(protocol, ctx)) {
+            Channel channel = ctx.getChannel();
+            ProtocolSession session = (ProtocolSession) ctx.getAttachment();
+            if (e.getCause() instanceof TooLongFrameException && session != null) {
+                Response r = session.newLineTooLongResponse();
+                ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
                 if (r != null) {
                     transport.writeResponse(r, session);
-                } 
-                transport.writeResponse(Response.DISCONNECT, session);
+                }
+            } else {
+                if (channel.isConnected() && session != null) {
+                    ProtocolTransport transport = ((ProtocolSessionImpl) session).getProtocolTransport();
+
+                    Response r = session.newFatalErrorResponse();
+                    if (r != null) {
+                        transport.writeResponse(r, session);
+                    }
+                    transport.writeResponse(Response.DISCONNECT, session);
+                }
+                getLogger(session).error("Unable to process request", e.getCause());
+                cleanup(ctx);
             }
-            getLogger(session).error("Unable to process request", e.getCause());
-            cleanup(ctx);            
         }
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContext.java
----------------------------------------------------------------------
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContext.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContext.java
new file mode 100644
index 0000000..f5d76a6
--- /dev/null
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContext.java
@@ -0,0 +1,71 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.protocols.netty;
+
+import java.io.Closeable;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Optional;
+
+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;
+
+public class ProtocolMDCContext {
+    public static Closeable from(Protocol protocol, ChannelHandlerContext ctx) {
+        return MDCBuilder.create()
+            .addContext(from(ctx.getAttachment()))
+            .addContext(MDCBuilder.PROTOCOL, protocol.getName())
+            .addContext(MDCBuilder.IP, retrieveIp(ctx))
+            .addContext(MDCBuilder.HOST, retrieveHost(ctx))
+            .build();
+    }
+
+    private static String retrieveIp(ChannelHandlerContext ctx) {
+        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        if (remoteAddress instanceof InetSocketAddress) {
+            InetSocketAddress address = (InetSocketAddress) remoteAddress;
+            return address.getAddress().getHostAddress();
+        }
+        return remoteAddress.toString();
+    }
+
+    private static String retrieveHost(ChannelHandlerContext ctx) {
+        SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+        if (remoteAddress instanceof InetSocketAddress) {
+            InetSocketAddress address = (InetSocketAddress) remoteAddress;
+            return address.getHostName();
+        }
+        return remoteAddress.toString();
+    }
+
+    private static MDCBuilder from(Object o) {
+        return Optional.ofNullable(o)
+            .filter(object -> object instanceof ProtocolSession)
+            .map(object -> (ProtocolSession) object)
+            .map(protocolSession -> MDCBuilder.create()
+                .addContext(MDCBuilder.SESSION_ID, protocolSession.getSessionID())
+                .addContext(MDCBuilder.CHARSET, protocolSession.getCharset().displayName())
+                .addContext(MDCBuilder.USER, protocolSession.getUser()))
+            .orElse(MDCBuilder.create());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/pom.xml
----------------------------------------------------------------------
diff --git a/protocols/pom.xml b/protocols/pom.xml
index 35f4000..0d6fc46 100644
--- a/protocols/pom.xml
+++ b/protocols/pom.xml
@@ -69,6 +69,11 @@
                 <version>${project.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.james</groupId>
+                <artifactId>james-server-util-java8</artifactId>
+                <version>3.1.0-SNAPSHOT</version>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.james.protocols</groupId>
                 <artifactId>protocols-pop3</artifactId>
                 <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/POP3Protocol.java
----------------------------------------------------------------------
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/POP3Protocol.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/POP3Protocol.java
index 5da598e..ab3ad92 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/POP3Protocol.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/POP3Protocol.java
@@ -36,7 +36,11 @@ public class POP3Protocol extends ProtocolImpl{
         super(chain, config, logger);
     }
 
-    
+    @Override
+    public String getName() {
+        return "POP3";
+    }
+
     @Override
     public ProtocolSession newSession(ProtocolTransport transport) {
         return new POP3SessionImpl(logger, transport, getConfiguration());

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d4254a9/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPProtocol.java
----------------------------------------------------------------------
diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPProtocol.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPProtocol.java
index 9b50145..4e2ba67 100644
--- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPProtocol.java
+++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPProtocol.java
@@ -41,4 +41,8 @@ public class SMTPProtocol extends ProtocolImpl {
         return new SMTPSessionImpl(logger, transport, (SMTPConfiguration) getConfiguration());
     }
 
+    @Override
+    public String getName() {
+        return "SMTP";
+    }
 }


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