You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ma...@apache.org on 2007/08/20 00:16:53 UTC

svn commit: r567490 - in /mina/trunk/core/src: main/java/org/apache/mina/filter/logging/ main/java/org/apache/mina/filter/util/ test/java/org/apache/mina/filter/util/ test/java/org/apache/mina/util/

Author: maarten
Date: Sun Aug 19 15:16:51 2007
New Revision: 567490

URL: http://svn.apache.org/viewvc?rev=567490&view=rev
Log:
DIRMINA-422 : create a new loggingfilter that leverages SLF4J's MDC feauture

Added:
    mina/trunk/core/src/main/java/org/apache/mina/filter/logging/MdcLoggingFilter.java
    mina/trunk/core/src/main/java/org/apache/mina/filter/util/WrappingFilter.java
    mina/trunk/core/src/test/java/org/apache/mina/filter/util/
    mina/trunk/core/src/test/java/org/apache/mina/filter/util/WrappingFilterTest.java
    mina/trunk/core/src/test/java/org/apache/mina/util/DummySession.java

Added: mina/trunk/core/src/main/java/org/apache/mina/filter/logging/MdcLoggingFilter.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/logging/MdcLoggingFilter.java?rev=567490&view=auto
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/logging/MdcLoggingFilter.java (added)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/logging/MdcLoggingFilter.java Sun Aug 19 15:16:51 2007
@@ -0,0 +1,70 @@
+package org.apache.mina.filter.logging;
+
+import org.apache.mina.common.*;
+import org.apache.mina.filter.util.WrappingFilter;
+import org.slf4j.MDC;
+
+import java.net.InetSocketAddress;
+import java.util.*;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev: 566952 $, $Date: 2007-08-17 09:25:04 +0200 (vr, 17 aug 2007) $
+ */
+
+public class MdcLoggingFilter extends WrappingFilter {
+
+    /** key used for storing the context map in the IoSession */
+    public static final String CONTEXT_KEY = MdcLoggingFilter.class + ".CONTEXT_KEY";
+
+    protected void wrapFilterAction(IoEventType eventType, IoSession session, WrappingFilter.FilterAction action) {
+        //noinspection unchecked
+        Map<String,String> context = getContext(session);
+        /* copy context to the MDC */
+        for (Map.Entry<String, String> e : context.entrySet()) {
+            MDC.put(e.getKey(), e.getValue());
+        }
+        try {
+            /* propagate event down the filter chain */
+            action.execute();
+        } finally {
+            /* remove context from the MDC */
+            for (String key : context.keySet()) {
+                MDC.remove(key);
+            }
+        }
+    }    
+
+    public Map<String,String> getContext(final IoSession session) {
+        //noinspection unchecked
+        Map<String,String> context = (Map<String,String>) session.getAttribute(CONTEXT_KEY);
+        if (context == null) {
+            context = new HashMap<String, String>();
+            fillContext(session, context);
+            session.setAttribute(CONTEXT_KEY, context);
+        }
+        return context;
+    }
+
+    /**
+     * write key properties of the session to the Mapped Diagnostic Context
+     * sub-classes could override this method to map more/other attributes
+     * @param session the session to map
+     * @param context key properties will be added to this map
+     */
+    protected void fillContext(final IoSession session, final Map<String,String> context) {
+        context.put("IoHandlerClass", session.getHandler().getClass().toString());
+        context.put("remoteAddress", session.getRemoteAddress().toString());
+        context.put("localAddress", session.getLocalAddress().toString());
+        if (session.getService().getMetadata().getAddressType() == InetSocketAddress.class) {
+            InetSocketAddress remoteAddress = (InetSocketAddress) session.getRemoteAddress();
+            InetSocketAddress localAddress  = (InetSocketAddress) session.getLocalAddress();
+            context.put("remoteIp", remoteAddress.getAddress().getHostAddress());
+            context.put("remotePort", String.valueOf(remoteAddress.getPort()));
+            context.put("localIp", localAddress.getAddress().getHostAddress());
+            context.put("localPort", String.valueOf(localAddress.getPort()));
+        }
+    }
+
+}

Added: mina/trunk/core/src/main/java/org/apache/mina/filter/util/WrappingFilter.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/util/WrappingFilter.java?rev=567490&view=auto
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/util/WrappingFilter.java (added)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/util/WrappingFilter.java Sun Aug 19 15:16:51 2007
@@ -0,0 +1,92 @@
+package org.apache.mina.filter.util;
+
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoEventType;
+import org.apache.mina.common.IoFilterAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.WriteRequest;
+
+/**
+ * Extend this class when you want to create a filter that
+ * wraps the same logic around all 9 IoEvents
+ */
+public abstract class WrappingFilter extends IoFilterAdapter {
+
+    protected interface FilterAction {
+        void execute();
+    }
+
+    abstract protected void wrapFilterAction(IoEventType eventType, IoSession session, FilterAction action);
+
+    public void sessionCreated(final NextFilter nextFilter, final IoSession session) throws Exception {
+        wrapFilterAction(IoEventType.SESSION_CREATED, session, new FilterAction() {
+            public void execute() {
+                nextFilter.sessionCreated(session);
+            }
+        });
+    }
+
+    public void sessionOpened(final NextFilter nextFilter, final IoSession session) throws Exception {
+        wrapFilterAction(IoEventType.SESSION_OPENED, session, new FilterAction() {
+            public void execute() {
+                nextFilter.sessionOpened(session);
+            }
+        });
+    }
+
+    public void sessionClosed(final NextFilter nextFilter, final IoSession session) throws Exception {
+        wrapFilterAction(IoEventType.SESSION_CLOSED, session, new FilterAction() {
+            public void execute() {
+                nextFilter.sessionClosed(session);
+            }
+        });
+    }
+
+    public void sessionIdle(final NextFilter nextFilter, final IoSession session, final IdleStatus status) throws Exception {
+        wrapFilterAction(IoEventType.SESSION_IDLE, session, new FilterAction() {
+            public void execute() {
+                nextFilter.sessionIdle(session, status);
+            }
+        });
+    }
+
+    public void exceptionCaught(final NextFilter nextFilter, final IoSession session, final Throwable cause) throws Exception {
+        wrapFilterAction(IoEventType.EXCEPTION_CAUGHT, session, new FilterAction() {
+            public void execute() {
+                nextFilter.exceptionCaught(session, cause);
+            }
+        });
+    }
+
+    public void messageReceived(final NextFilter nextFilter, final IoSession session, final Object message) throws Exception {
+        wrapFilterAction(IoEventType.MESSAGE_RECEIVED, session, new FilterAction() {
+            public void execute() {
+                nextFilter.messageReceived(session, message);
+            }
+        });
+    }
+
+    public void messageSent(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest) throws Exception {
+        wrapFilterAction(IoEventType.MESSAGE_SENT, session, new FilterAction() {
+            public void execute() {
+                nextFilter.messageSent(session, writeRequest);
+            }
+        });
+    }
+
+    public void filterWrite(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest) throws Exception {
+        wrapFilterAction(IoEventType.WRITE, session, new FilterAction() {
+            public void execute() {
+                nextFilter.filterWrite(session, writeRequest);
+            }
+        });
+    }
+
+    public void filterClose(final NextFilter nextFilter, final IoSession session) throws Exception {
+        wrapFilterAction(IoEventType.CLOSE, session, new FilterAction() {
+            public void execute() {
+                nextFilter.filterClose(session);
+            }
+        });
+    }
+}

Added: mina/trunk/core/src/test/java/org/apache/mina/filter/util/WrappingFilterTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/filter/util/WrappingFilterTest.java?rev=567490&view=auto
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/filter/util/WrappingFilterTest.java (added)
+++ mina/trunk/core/src/test/java/org/apache/mina/filter/util/WrappingFilterTest.java Sun Aug 19 15:16:51 2007
@@ -0,0 +1,105 @@
+package org.apache.mina.filter.util;
+
+import junit.framework.TestCase;
+import org.apache.mina.common.*;
+import org.apache.mina.util.DummySession;
+import org.easymock.MockControl;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Tests {@link WrappingFilter}.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev: 567208 $, $Date: 2007-08-18 04:27:05 +0200 (za, 18 aug 2007) $
+ */
+
+public class WrappingFilterTest extends TestCase {
+
+    private MockControl mockNextFilter;
+
+    private IoSession session;
+
+    private IoFilter.NextFilter nextFilter;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        /*
+         * Create the mocks.
+         */
+        session = new DummySession();
+        mockNextFilter = MockControl.createControl(IoFilter.NextFilter.class);
+        nextFilter = (IoFilter.NextFilter) mockNextFilter.getMock();
+    }
+
+    public void testFilter() throws Exception {
+        MyWrappingFilter wrappingFilter = new MyWrappingFilter();
+
+        /* record expectations */
+        Object message1 = "message one";
+        Object message2 = "message two";
+        WriteRequest writeRequest1 = new DefaultWriteRequest("test1");
+        WriteRequest writeRequest2 = new DefaultWriteRequest("test2");
+        Throwable cause = new Throwable("testing");
+
+        nextFilter.sessionCreated(session);
+        nextFilter.sessionOpened(session);
+        nextFilter.sessionIdle(session, IdleStatus.READER_IDLE);
+        nextFilter.messageReceived(session, message1);
+        nextFilter.messageSent(session, writeRequest1);
+        nextFilter.messageSent(session, writeRequest2);
+        nextFilter.messageReceived(session, message2);
+        nextFilter.filterWrite(session, writeRequest1);
+        nextFilter.filterClose(session);
+        nextFilter.exceptionCaught(session, cause);
+        nextFilter.sessionClosed(session);
+
+        /* replay */
+        mockNextFilter.replay();
+        wrappingFilter.sessionCreated(nextFilter, session);
+        wrappingFilter.sessionOpened(nextFilter, session);
+        wrappingFilter.sessionIdle(nextFilter, session, IdleStatus.READER_IDLE);
+        wrappingFilter.messageReceived(nextFilter, session, message1);
+        wrappingFilter.messageSent(nextFilter, session, writeRequest1);
+        wrappingFilter.messageSent(nextFilter, session, writeRequest2);
+        wrappingFilter.messageReceived(nextFilter, session, message2);
+        wrappingFilter.filterWrite(nextFilter,session, writeRequest1);
+        wrappingFilter.filterClose(nextFilter, session);
+        wrappingFilter.exceptionCaught(nextFilter, session, cause);
+        wrappingFilter.sessionClosed(nextFilter, session);
+
+        /* verify */
+        mockNextFilter.verify();
+
+        /* check event lists */
+        assertEquals(11, wrappingFilter.eventsBefore.size());
+        assertEquals(IoEventType.SESSION_CREATED, wrappingFilter.eventsBefore.get(0));
+        assertEquals(IoEventType.SESSION_OPENED, wrappingFilter.eventsBefore.get(1));
+        assertEquals(IoEventType.SESSION_IDLE, wrappingFilter.eventsBefore.get(2));
+        assertEquals(IoEventType.MESSAGE_RECEIVED, wrappingFilter.eventsBefore.get(3));
+        assertEquals(IoEventType.MESSAGE_SENT, wrappingFilter.eventsBefore.get(4));
+        assertEquals(IoEventType.MESSAGE_SENT, wrappingFilter.eventsBefore.get(5));
+        assertEquals(IoEventType.MESSAGE_RECEIVED, wrappingFilter.eventsBefore.get(6));
+        assertEquals(IoEventType.WRITE, wrappingFilter.eventsBefore.get(7));
+        assertEquals(IoEventType.CLOSE, wrappingFilter.eventsBefore.get(8));
+        assertEquals(IoEventType.EXCEPTION_CAUGHT, wrappingFilter.eventsBefore.get(9));
+        assertEquals(IoEventType.SESSION_CLOSED, wrappingFilter.eventsBefore.get(10));
+        assertEquals(wrappingFilter.eventsBefore,  wrappingFilter.eventsAfter);
+    }
+
+
+    private static class MyWrappingFilter extends WrappingFilter {
+
+        private List<IoEventType> eventsBefore = new ArrayList<IoEventType>();
+
+        private List<IoEventType> eventsAfter = new ArrayList<IoEventType>();
+
+        protected void wrapFilterAction(IoEventType eventType, IoSession session, WrappingFilter.FilterAction action) {
+            eventsBefore.add(eventType);
+            action.execute();
+            eventsAfter.add(eventType);
+        }
+    }
+}

Added: mina/trunk/core/src/test/java/org/apache/mina/util/DummySession.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/util/DummySession.java?rev=567490&view=auto
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/util/DummySession.java (added)
+++ mina/trunk/core/src/test/java/org/apache/mina/util/DummySession.java Sun Aug 19 15:16:51 2007
@@ -0,0 +1,56 @@
+package org.apache.mina.util;
+
+import org.apache.mina.common.*;
+
+import java.net.SocketAddress;
+
+/**
+ * dummy {@link IoSession} implementation for use in test cases.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev: 567228 $, $Date: 2007-08-18 06:39:46 +0200 (za, 18 aug 2007) $
+ */
+public class DummySession  extends AbstractIoSession {
+
+    @Override
+    protected void updateTrafficMask() {
+    }
+
+    public IoSessionConfig getConfig() {
+        return null;
+    }
+
+    public IoFilterChain getFilterChain() {
+        return null;
+    }
+
+    public IoHandler getHandler() {
+        return null;
+    }
+
+    public SocketAddress getLocalAddress() {
+        return null;
+    }
+
+    public SocketAddress getRemoteAddress() {
+        return null;
+    }
+
+    public int getScheduledWriteBytes() {
+        return 0;
+    }
+
+    public int getScheduledWriteMessages() {
+        return 0;
+    }
+
+    public IoService getService() {
+        return null;
+    }
+
+    public IoServiceMetadata getTransportType() {
+        return null;
+    }
+}
+
+