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.transport.nio;
    21
    22  import static org.junit.Assert.assertEquals;
    23  import static org.junit.Assert.assertTrue;
    24  import static org.junit.Assert.fail;
    25
    26  import java.io.IOException;
    27  import java.net.Socket;
    28  import java.nio.ByteBuffer;
    29  import java.util.concurrent.CountDownLatch;
    30  import java.util.concurrent.TimeUnit;
    31
    32  import org.apache.mina.api.AbstractIoFilter;
    33  import org.apache.mina.api.IoSession;
    34  import org.apache.mina.filterchain.ReadFilterChainController;
    35  import org.apache.mina.filterchain.WriteFilterChainController;
    36  import org.apache.mina.session.WriteRequest;
    37  import org.apache.mina.transport.nio.FixedSelectorLoopPool;
    38  import org.apache.mina.transport.nio.NioTcpServer;
    39  import org.apache.mina.transport.nio.SelectorLoopPool;
    40  import org.junit.Test;
    41  import org.slf4j.Logger;
    42  import org.slf4j.LoggerFactory;
    43
    44  /**
    45   * This class test the event dispatching of {@link NioTcpServer}.
    46   *
    47   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    48   */
    49  public class NioTcpServerFilterEventTest {
    50
    51      private static final Logger LOG = LoggerFactory.getLogger(NioTcpServerFilterEventTest.class);
    52
    53      private static final int CLIENT_COUNT = 100;
    54
    55      private static final int WAIT_TIME = 30000;
    56
    57      private final CountDownLatch msgSentLatch = new CountDownLatch(CLIENT_COUNT);
    58
    59      private final CountDownLatch msgReadLatch = new CountDownLatch(CLIENT_COUNT);
    60
    61      private final CountDownLatch openLatch = new CountDownLatch(CLIENT_COUNT);
    62
    63      private final CountDownLatch closedLatch = new CountDownLatch(CLIENT_COUNT);
    64
    65      @Test
    66      public void generate_all_kind_of_server_event() throws IOException, InterruptedException {
    67          final NioTcpServer server = new NioTcpServer();
    68          server.setFilters(new MyCodec(), new Handler());
    69          server.bind(0);
    70          // warm up
    71          Thread.sleep(100);
    72
    73          long t0 = System.currentTimeMillis();
    74          final int port = server.getServerSocketChannel().socket().getLocalPort();
    75
    76          final Socket[] clients = new Socket[CLIENT_COUNT];
    77
    78          // connect some clients
    79          for (int i = 0; i < CLIENT_COUNT; i++) {
    80              // System.out.println("Creation client " + i);
    81              try {
    82                  clients[i] = new Socket("127.0.0.1", port);
    83              } catch (Exception e) {
    84                  e.printStackTrace();
    85                  System.out.println("Creation client " + i + " failed");
    86              }
    87          }
    88
    89          // does the session open message was fired ?
    90          assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    91
    92          // write some messages
    93          for (int i = 0; i < CLIENT_COUNT; i++) {
    94              clients[i].getOutputStream().write(("test:" + i).getBytes());
    95              clients[i].getOutputStream().flush();
    96          }
    97
    98          // test is message was received by the server
    99          assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    100
    101         // does response was wrote and sent ?
    102         assertTrue(msgSentLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    103
    104         // read the echos
    105         final byte[] buffer = new byte[1024];
    106
    107         for (int i = 0; i < CLIENT_COUNT; i++) {
    108             final int bytes = clients[i].getInputStream().read(buffer);
    109             final String text = new String(buffer, 0, bytes);
    110             assertEquals("test:" + i, text);
    111         }
    112
    113         // close the session
    114         assertEquals(CLIENT_COUNT, closedLatch.getCount());
    115         for (int i = 0; i < CLIENT_COUNT; i++) {
    116             clients[i].close();
    117         }
    118
    119         // does the session close event was fired ?
    120         assertTrue(closedLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    121
    122         long t1 = System.currentTimeMillis();
    123
    124         System.out.println("Delta = " + (t1 - t0));
    125
    126         server.unbind();
    127     }
    128
    129     /**
    130      * A test that creates 50 clients, each one of them writing one message. We will check that for each client we
    131      * correctly process the sessionOpened, messageReceived, messageSent and sessionClosed events. We use only one
    132      * selector to process all the OP events.
    133      */
    134     @Test
    135     public void generateAllKindOfServerEventOneSelector() throws IOException, InterruptedException {
    136         SelectorLoopPool selectorLoopPool = new FixedSelectorLoopPool("Server", 1);
    137         final NioTcpServer server = new NioTcpServer(selectorLoopPool.getSelectorLoop(), selectorLoopPool, null);
    138         server.setFilters(new MyCodec(), new Handler());
    139         server.bind(0);
    140         // warm up
    141         Thread.sleep(100);
    142
    143         long t0 = System.currentTimeMillis();
    144         final int port = server.getServerSocketChannel().socket().getLocalPort();
    145
    146         final Socket[] clients = new Socket[CLIENT_COUNT];
    147
    148         // connect some clients
    149         for (int i = 0; i < CLIENT_COUNT; i++) {
    150             // System.out.println("Creation client 2 " + i);
    151             clients[i] = new Socket("127.0.0.1", port);
    152         }
    153
    154         // does the session open message was fired ?
    155         assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    156
    157         // write some messages
    158         for (int i = 0; i < CLIENT_COUNT; i++) {
    159             clients[i].getOutputStream().write(("test:" + i).getBytes());
    160             clients[i].getOutputStream().flush();
    161         }
    162
    163         // test is message was received by the server
    164         assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    165
    166         // does response was wrote and sent ?
    167         assertTrue(msgSentLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    168
    169         // read the echos
    170         final byte[] buffer = new byte[1024];
    171
    172         for (int i = 0; i < CLIENT_COUNT; i++) {
    173             final int bytes = clients[i].getInputStream().read(buffer);
    174             final String text = new String(buffer, 0, bytes);
    175             assertEquals("test:" + i, text);
    176         }
    177
    178         // close the session
    179         assertEquals(CLIENT_COUNT, closedLatch.getCount());
    180         for (int i = 0; i < CLIENT_COUNT; i++) {
    181             clients[i].close();
    182         }
    183
    184         // does the session close event was fired ?
    185         assertTrue(closedLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    186
    187         long t1 = System.currentTimeMillis();
    188
    189         System.out.println("Delta = " + (t1 - t0));
    190
    191         server.unbind();
    192     }
    193
    194     private class MyCodec extends AbstractIoFilter {
    195
    196         @Override
    197         public void messageReceived(final IoSession session, final Object message,
    198                 final ReadFilterChainController controller) {
    199             if (message instanceof ByteBuffer) {
    200                 final ByteBuffer in = (ByteBuffer) message;
    201                 final byte[] buffer = new byte[in.remaining()];
    202                 in.get(buffer);
    203                 controller.callReadNextFilter(new String(buffer));
    204             } else {
    205                 fail();
    206             }
    207         }
    208
    209         @Override
    210         public void messageWriting(IoSession session, WriteRequest writeRequest, WriteFilterChainController controller) {
    211             writeRequest.setMessage(ByteBuffer.wrap(writeRequest.getMessage().toString().getBytes()));
    212             controller.callWriteNextFilter(writeRequest);
    213         }
    214     }
    215
    216     private class Handler extends AbstractIoFilter {
    217
    218         @Override
    219         public void sessionOpened(final IoSession session) {
    220             LOG.info("** session open");
    221             openLatch.countDown();
    222         }
    223
    224         @Override
    225         public void sessionClosed(final IoSession session) {
    226             LOG.info("** session closed");
    227             closedLatch.countDown();
    228         }
    229
    230         @Override
    231         public void messageReceived(final IoSession session, final Object message,
    232                 final ReadFilterChainController controller) {
    233             LOG.info("** message received {}", message);
    234             msgReadLatch.countDown();
    235             session.write(message.toString());
    236         }
    237
    238         @Override
    239         public void messageSent(final IoSession session, final Object message) {
    240             LOG.info("** message sent {}", message);
    241             msgSentLatch.countDown();
    242         }
    243     }
    244 }