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.*;
    23
    24  import java.io.IOException;
    25  import java.net.InetSocketAddress;
    26  import java.net.ServerSocket;
    27  import java.net.Socket;
    28  import java.nio.ByteBuffer;
    29  import java.util.ArrayList;
    30  import java.util.List;
    31  import java.util.concurrent.CountDownLatch;
    32  import java.util.concurrent.ExecutionException;
    33  import java.util.concurrent.TimeUnit;
    34
    35  import org.apache.mina.api.AbstractIoFilter;
    36  import org.apache.mina.api.IoFuture;
    37  import org.apache.mina.api.IoSession;
    38  import org.apache.mina.filterchain.ReadFilterChainController;
    39  import org.apache.mina.filterchain.WriteFilterChainController;
    40  import org.apache.mina.session.WriteRequest;
    41  import org.apache.mina.transport.nio.NioTcpClient;
    42  import org.junit.Test;
    43  import org.slf4j.Logger;
    44  import org.slf4j.LoggerFactory;
    45
    46  /**
    47   * This class test the event dispatching of {@link NioTcpClient}.
    48   *
    49   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    50   */
    51  public class NioTcpClientFilterEventTest {
    52
    53      private static final Logger LOG = LoggerFactory.getLogger(NioTcpClientFilterEventTest.class);
    54
    55      private static final int CLIENT_COUNT = 10;
    56
    57      private static final int WAIT_TIME = 30000;
    58
    59      private final CountDownLatch msgSentLatch = new CountDownLatch(CLIENT_COUNT);
    60
    61      private final CountDownLatch msgReadLatch = new CountDownLatch(CLIENT_COUNT);
    62
    63      private final CountDownLatch openLatch = new CountDownLatch(CLIENT_COUNT);
    64
    65      private final CountDownLatch closedLatch = new CountDownLatch(CLIENT_COUNT);
    66
    67      /**
    68       * Create an old IO server and use a bunch of MINA client on it. Test if the events occurs correctly in the
    69       * different IoFilters.
    70       */
    71      @Test
    72      public void generate_all_kind_of_client_event() throws IOException, InterruptedException, ExecutionException {
    73          NioTcpClient client = new NioTcpClient();
    74          client.setFilters(new MyCodec(), new Handler());
    75
    76          ServerSocket serverSocket = new ServerSocket();
    77          serverSocket.bind(null);
    78          int port = serverSocket.getLocalPort();
    79
    80          // warm up
    81          Thread.sleep(100);
    82          final long t0 = System.currentTimeMillis();
    83
    84          // now connect the clients
    85
    86          List<IoFuture<IoSession>> cf = new ArrayList<IoFuture<IoSession>>();
    87          for (int i = 0; i < CLIENT_COUNT; i++) {
    88              cf.add(client.connect(new InetSocketAddress("localhost", port)));
    89          }
    90
    91          Socket[] clientSockets = new Socket[CLIENT_COUNT];
    92          for (int i = 0; i < CLIENT_COUNT; i++) {
    93              clientSockets[i] = serverSocket.accept();
    94          }
    95
    96          // does the session open message was fired ?
    97          assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    98
    99          // gather sessions from futures
    100         IoSession[] sessions = new IoSession[CLIENT_COUNT];
    101         for (int i = 0; i < CLIENT_COUNT; i++) {
    102             sessions[i] = cf.get(i).get();
    103             assertNotNull(sessions[i]);
    104         }
    105
    106         // write some messages
    107         for (int i = 0; i < CLIENT_COUNT; i++) {
    108             clientSockets[i].getOutputStream().write(("test:" + i).getBytes());
    109             clientSockets[i].getOutputStream().flush();
    110         }
    111
    112         // test is message was received by the server
    113         assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    114
    115         // does response was wrote and sent ?
    116         assertTrue(msgSentLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    117
    118         // read the echos
    119         final byte[] buffer = new byte[1024];
    120
    121         for (int i = 0; i < CLIENT_COUNT; i++) {
    122             final int bytes = clientSockets[i].getInputStream().read(buffer);
    123             final String text = new String(buffer, 0, bytes);
    124             assertEquals("test:" + i, text);
    125         }
    126
    127         // close the session
    128         assertEquals(CLIENT_COUNT, closedLatch.getCount());
    129         for (int i = 0; i < CLIENT_COUNT; i++) {
    130             clientSockets[i].close();
    131         }
    132
    133         // does the session close event was fired ?
    134         assertTrue(closedLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    135
    136         long t1 = System.currentTimeMillis();
    137
    138         System.out.println("Delta = " + (t1 - t0));
    139
    140         serverSocket.close();
    141     }
    142
    143     private class MyCodec extends AbstractIoFilter {
    144
    145         @Override
    146         public void messageReceived(final IoSession session, final Object message,
    147                 final ReadFilterChainController controller) {
    148             if (message instanceof ByteBuffer) {
    149                 final ByteBuffer in = (ByteBuffer) message;
    150                 final byte[] buffer = new byte[in.remaining()];
    151                 in.get(buffer);
    152                 controller.callReadNextFilter(new String(buffer));
    153             } else {
    154                 fail();
    155             }
    156         }
    157
    158         @Override
    159         public void messageWriting(IoSession session, WriteRequest writeRequest, WriteFilterChainController controller) {
    160             writeRequest.setMessage(ByteBuffer.wrap(writeRequest.getMessage().toString().getBytes()));
    161             controller.callWriteNextFilter(writeRequest);
    162         }
    163     }
    164
    165     private class Handler extends AbstractIoFilter {
    166
    167         @Override
    168         public void sessionOpened(final IoSession session) {
    169             LOG.info("** session open");
    170             openLatch.countDown();
    171         }
    172
    173         @Override
    174         public void sessionClosed(final IoSession session) {
    175             LOG.info("** session closed");
    176             closedLatch.countDown();
    177         }
    178
    179         @Override
    180         public void messageReceived(final IoSession session, final Object message,
    181                 final ReadFilterChainController controller) {
    182             LOG.info("** message received {}", message);
    183             msgReadLatch.countDown();
    184             session.write(message.toString());
    185         }
    186
    187         @Override
    188         public void messageSent(final IoSession session, final Object message) {
    189             LOG.info("** message sent {}", message);
    190             msgSentLatch.countDown();
    191         }
    192     }
    193 }