View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.filter.keepalive;
    21
    22  import static org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler.EXCEPTION;
    23  import static org.junit.Assert.assertFalse;
    24  import static org.junit.Assert.assertNotNull;
    25
    26  import java.net.InetSocketAddress;
    27  import java.util.concurrent.atomic.AtomicBoolean;
    28
    29  import org.apache.mina.core.buffer.IoBuffer;
    30  import org.apache.mina.core.future.ConnectFuture;
    31  import org.apache.mina.core.service.IoHandlerAdapter;
    32  import org.apache.mina.core.session.IdleStatus;
    33  import org.apache.mina.core.session.IoSession;
    34  import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
    35  import org.apache.mina.transport.socket.nio.NioSocketConnector;
    36  import org.junit.After;
    37  import org.junit.Before;
    38  import org.junit.Test;
    39
    40  /**
    41   * Tests {@link KeepAliveFilter} used by the connector with different
    42   * interested {@link IdleStatus}es.
    43   *
    44   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    45   */
    46  public class KeepAliveFilterTest {
    47      // Constants -----------------------------------------------------
    48      static final IoBuffer PING = IoBuffer.wrap(new byte[] { 1 });
    49
    50      static final IoBuffer PONG = IoBuffer.wrap(new byte[] { 2 });
    51
    52      private static final int INTERVAL = 2;
    53
    54      private static final int TIMEOUT = 1;
    55
    56      private int port;
    57
    58      private NioSocketAcceptor acceptor;
    59
    60      @Before
    61      public void setUp() throws Exception {
    62          acceptor = new NioSocketAcceptor();
    63          KeepAliveMessageFactory factory = new ServerFactory();
    64          KeepAliveFilter filter = new KeepAliveFilter(factory, IdleStatus.BOTH_IDLE);
    65          acceptor.getFilterChain().addLast("keep-alive", filter);
    66          acceptor.setHandler(new IoHandlerAdapter());
    67          acceptor.setDefaultLocalAddress(new InetSocketAddress(0));
    68          acceptor.bind();
    69          port = acceptor.getLocalAddress().getPort();
    70      }
    71
    72      @After
    73      public void tearDown() throws Exception {
    74          acceptor.unbind();
    75          acceptor.dispose();
    76      }
    77
    78      @Test
    79      public void testKeepAliveFilterForReaderIdle() throws Exception {
    80          keepAliveFilterForIdleStatus(IdleStatus.READER_IDLE);
    81      }
    82
    83      @Test
    84      public void testKeepAliveFilterForBothIdle() throws Exception {
    85          keepAliveFilterForIdleStatus(IdleStatus.BOTH_IDLE);
    86      }
    87
    88      @Test
    89      public void testKeepAliveFilterForWriterIdle() throws Exception {
    90          keepAliveFilterForIdleStatus(IdleStatus.WRITER_IDLE);
    91      }
    92
    93      // Package protected ---------------------------------------------
    94
    95      // Protected -----------------------------------------------------
    96
    97      // Private -------------------------------------------------------
    98
    99      private void keepAliveFilterForIdleStatus(IdleStatus status) throws Exception {
    100         NioSocketConnector connector = new NioSocketConnector();
    101         KeepAliveFilter filter = new KeepAliveFilter(new ClientFactory(), status, EXCEPTION, INTERVAL, TIMEOUT);
    102         filter.setForwardEvent(true);
    103         connector.getFilterChain().addLast("keep-alive", filter);
    104
    105         final AtomicBoolean gotException = new AtomicBoolean(false);
    106         connector.setHandler(new IoHandlerAdapter() {
    107             @Override
    108             public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
    109                 //cause.printStackTrace();
    110                 gotException.set(true);
    111             }
    112
    113             @Override
    114             public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
    115                 // Do nothing
    116             }
    117         });
    118
    119         ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", port)).awaitUninterruptibly();
    120         IoSession session = future.getSession();
    121         assertNotNull(session);
    122
    123         Thread.sleep((INTERVAL + TIMEOUT + 1) * 1000);
    124
    125         assertFalse("got an exception on the client", gotException.get());
    126
    127         session.close(true);
    128         connector.dispose();
    129     }
    130
    131     static boolean checkRequest(IoBuffer message) {
    132         IoBuffer buff = message;
    133         boolean check = buff.get() == 1;
    134         buff.rewind();
    135         return check;
    136     }
    137
    138     static boolean checkResponse(IoBuffer message) {
    139         IoBuffer buff = message;
    140         boolean check = buff.get() == 2;
    141         buff.rewind();
    142         return check;
    143     }
    144
    145     // Inner classes -------------------------------------------------
    146     private final class ServerFactory implements KeepAliveMessageFactory {
    147         /**
    148          * Default constructor
    149          */
    150         public ServerFactory() {
    151             super();
    152         }
    153
    154         public Object getRequest(IoSession session) {
    155             return null;
    156         }
    157
    158         public Object getResponse(IoSession session, Object request) {
    159             return PONG.duplicate();
    160         }
    161
    162         public boolean isRequest(IoSession session, Object message) {
    163             if (message instanceof IoBuffer) {
    164                 return checkRequest((IoBuffer) message);
    165             }
    166             return false;
    167         }
    168
    169         public boolean isResponse(IoSession session, Object message) {
    170             if (message instanceof IoBuffer) {
    171                 return checkResponse((IoBuffer) message);
    172             }
    173             return false;
    174         }
    175     }
    176
    177     private final class ClientFactory implements KeepAliveMessageFactory {
    178         /**
    179          * Default constructor
    180          */
    181         public ClientFactory() {
    182             super();
    183         }
    184
    185         public Object getRequest(IoSession session) {
    186             return PING.duplicate();
    187         }
    188
    189         public Object getResponse(IoSession session, Object request) {
    190             return null;
    191         }
    192
    193         public boolean isRequest(IoSession session, Object message) {
    194             if (message instanceof IoBuffer) {
    195                 return checkRequest((IoBuffer) message);
    196             }
    197             return false;
    198         }
    199
    200         public boolean isResponse(IoSession session, Object message) {
    201             if (message instanceof IoBuffer) {
    202                 return checkResponse((IoBuffer) message);
    203             }
    204             return false;
    205         }
    206     }
    207 }