In read chain message writting for IoFilters Useful for filters negociating or implementing a part of a protocol like security features.
Project: http://git-wip-us.apache.org/repos/asf/mina/repo Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/2ff729a6 Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/2ff729a6 Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/2ff729a6 Branch: refs/heads/trunk Commit: 2ff729a63d77039eb540138193c750bdb95c3fc6 Parents: 919154a Author: jvermillard <[email protected]> Authored: Mon Oct 28 15:57:02 2013 +0100 Committer: jvermillard <[email protected]> Committed: Mon Oct 28 15:57:02 2013 +0100 ---------------------------------------------------------------------- .../filterchain/ReadFilterChainController.java | 10 ++++ .../apache/mina/session/AbstractIoSession.java | 14 +++++ .../mina/session/AbstractIoSessionTest.java | 59 +++++++++++++++++++- 3 files changed, 80 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina/blob/2ff729a6/core/src/main/java/org/apache/mina/filterchain/ReadFilterChainController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mina/filterchain/ReadFilterChainController.java b/core/src/main/java/org/apache/mina/filterchain/ReadFilterChainController.java index 82b0147..227ba51 100644 --- a/core/src/main/java/org/apache/mina/filterchain/ReadFilterChainController.java +++ b/core/src/main/java/org/apache/mina/filterchain/ReadFilterChainController.java @@ -27,5 +27,15 @@ package org.apache.mina.filterchain; */ public interface ReadFilterChainController { + /** + * Push the message to the next filter. Transformed or not. + * @param message the message to push to the next filter. + */ void callReadNextFilter(Object message); + + /** + * Write a message according to the protocol implemented in the filter + * @param message the message to be written and sent to the previous mail + */ + void callWriteMessageForRead(Object message); } http://git-wip-us.apache.org/repos/asf/mina/blob/2ff729a6/core/src/main/java/org/apache/mina/session/AbstractIoSession.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mina/session/AbstractIoSession.java b/core/src/main/java/org/apache/mina/session/AbstractIoSession.java index a82a2fa..1504c13 100644 --- a/core/src/main/java/org/apache/mina/session/AbstractIoSession.java +++ b/core/src/main/java/org/apache/mina/session/AbstractIoSession.java @@ -792,6 +792,20 @@ public abstract class AbstractIoSession implements IoSession, ReadFilterChainCon * {@inheritDoc} */ @Override + public void callWriteMessageForRead(Object message) { + if (IS_DEBUG) { + LOG.debug("calling filter for reading for message '{}' position : {} from a write event", message, + readChainPosition); + } + + writeChainPosition = readChainPosition; + callWriteNextFilter(new DefaultWriteRequest(message)); + } + + /** + * {@inheritDoc} + */ + @Override public void callReadNextFilter(Object message) { readChainPosition++; http://git-wip-us.apache.org/repos/asf/mina/blob/2ff729a6/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java b/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java index a9277a6..abb381b 100644 --- a/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java +++ b/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java @@ -18,9 +18,18 @@ */ package org.apache.mina.session; -import static org.junit.Assert.*; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import java.net.SocketAddress; import java.nio.ByteBuffer; @@ -29,6 +38,7 @@ import org.apache.mina.api.AbstractIoFilter; import org.apache.mina.api.IoFilter; import org.apache.mina.api.IoFuture; import org.apache.mina.api.IoService; +import org.apache.mina.api.IoSession; import org.apache.mina.api.IoSessionConfig; import org.apache.mina.filterchain.ReadFilterChainController; import org.apache.mina.filterchain.WriteFilterChainController; @@ -127,6 +137,13 @@ public class AbstractIoSessionTest { private final IoFilter filter3 = spy(new PassthruFilter()); + private final IoFilter filterWriteBack = spy(new PassthruFilter() { + @Override + public void messageReceived(IoSession session, Object message, ReadFilterChainController controller) { + controller.callWriteMessageForRead(message); + } + }); + @Before public void setup() { service = mock(IoService.class); @@ -185,6 +202,42 @@ public class AbstractIoSessionTest { } @Test + public void chain_reads_with_writeback() { + service = mock(IoService.class); + when(service.getFilters()).thenReturn(new IoFilter[] { filter1, filterWriteBack, filter3 }); + final DummySession session = new DummySession(service); + final ByteBuffer buffer = ByteBuffer.allocate(1024); + + final long before = System.currentTimeMillis(); + session.processMessageReceived(buffer); + verify(filter1).messageReceived(eq(session), eq(buffer), any(ReadFilterChainController.class)); + verify(filterWriteBack).messageReceived(eq(session), eq(buffer), any(ReadFilterChainController.class)); + verify(filter1).messageWriting(eq(session), any(WriteRequest.class), any(WriteFilterChainController.class)); + + assertEquals(1024L, session.getReadBytes()); + final long lastRead = session.getLastReadTime(); + assertTrue(lastRead - before < 100); + verifyNoMoreInteractions(filter1, filter2, filter3, filterWriteBack); + } + + @Test + public void chain_reads_with_writeback_final() { + service = mock(IoService.class); + when(service.getFilters()).thenReturn(new IoFilter[] { filterWriteBack, filter2, filter3 }); + final DummySession session = new DummySession(service); + final ByteBuffer buffer = ByteBuffer.allocate(1024); + + final long before = System.currentTimeMillis(); + session.processMessageReceived(buffer); + verify(filterWriteBack).messageReceived(eq(session), eq(buffer), any(ReadFilterChainController.class)); + + assertEquals(1024L, session.getReadBytes()); + final long lastRead = session.getLastReadTime(); + assertTrue(lastRead - before < 100); + verifyNoMoreInteractions(filter1, filter2, filter3, filterWriteBack); + } + + @Test public void chain_writes() { final DummySession session = new DummySession(service); final WriteRequest buffer = mock(DefaultWriteRequest.class);
