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