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.bio;
    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.InetSocketAddress;
    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.IdleStatus;
    34  import org.apache.mina.api.IoSession;
    35  import org.apache.mina.filterchain.ReadFilterChainController;
    36  import org.apache.mina.filterchain.WriteFilterChainController;
    37  import org.apache.mina.session.WriteRequest;
    38  import org.junit.Test;
    39  import org.slf4j.Logger;
    40  import org.slf4j.LoggerFactory;
    41
    42  /**
    43   * This class test the event dispatching of {@link BioUdpServer}.
    44   *
    45   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    46   */
    47  public class BioUdpServerFilterEventTest {
    48
    49      private static final Logger LOG = LoggerFactory.getLogger(BioUdpServerFilterEventTest.class);
    50
    51      private static final int CLIENT_COUNT = 1;
    52
    53      private static final int WAIT_TIME = 10000;
    54
    55      private CountDownLatch msgSentLatch = new CountDownLatch(CLIENT_COUNT);
    56
    57      private CountDownLatch msgReadLatch = new CountDownLatch(CLIENT_COUNT);
    58
    59      private CountDownLatch openLatch = new CountDownLatch(CLIENT_COUNT);
    60
    61      private CountDownLatch closedLatch = new CountDownLatch(CLIENT_COUNT);
    62
    63      @Test
    64      public void generate_all_kind_of_server_event() throws IOException, InterruptedException {
    65          final BioUdpServer server = new BioUdpServer();
    66          server.getSessionConfig().setIdleTimeInMillis(IdleStatus.READ_IDLE, 2000);
    67          server.setFilters(new MyCodec(), new Handler());
    68          server.bind(0);
    69          // warm up
    70          Thread.sleep(100);
    71
    72          long t0 = System.currentTimeMillis();
    73          final int port = server.getDatagramChannel().socket().getLocalPort();
    74
    75          System.err.println("port : " + port);
    76          final DatagramSocket[] clients = new DatagramSocket[CLIENT_COUNT];
    77
    78          InetSocketAddress serverAddy = new InetSocketAddress("127.0.0.1", port);
    79          // connect some clients
    80          for (int i = 0; i < CLIENT_COUNT; i++) {
    81              try {
    82                  clients[i] = new DatagramSocket();
    83              } catch (Exception e) {
    84                  e.printStackTrace();
    85                  System.out.println("Creation client " + i + " failed");
    86              }
    87          }
    88
    89          // write some messages
    90          for (int i = 0; i < CLIENT_COUNT; i++) {
    91              byte[] data = ("test:" + i).getBytes();
    92              clients[i].send(new DatagramPacket(data, data.length, serverAddy));
    93          }
    94
    95          // does the session open message was fired ?
    96          assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    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             DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
    109             clients[i].receive(dp);
    110             final String text = new String(buffer, 0, dp.getLength());
    111             assertEquals("test:" + i, text);
    112         }
    113
    114         msgReadLatch = new CountDownLatch(CLIENT_COUNT);
    115
    116         // try again
    117         // write some messages again
    118         for (int i = 0; i < CLIENT_COUNT; i++) {
    119             byte[] data = ("test:" + i).getBytes();
    120             clients[i].send(new DatagramPacket(data, data.length, serverAddy));
    121         }
    122
    123         // test is message was received by the server
    124         assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    125
    126         // wait echo
    127
    128         // close the session
    129         assertEquals(CLIENT_COUNT, closedLatch.getCount());
    130         for (int i = 0; i < CLIENT_COUNT; i++) {
    131             clients[i].close();
    132         }
    133
    134         // does the session close event was fired ?
    135         assertTrue(closedLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
    136
    137         long t1 = System.currentTimeMillis();
    138
    139         System.out.println("Delta = " + (t1 - t0));
    140
    141         server.unbind();
    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         }
    173
    174         @Override
    175         public void sessionClosed(final IoSession session) {
    176             LOG.info("** session closed");
    177             closedLatch.countDown();
    178         }
    179
    180         @Override
    181         public void messageReceived(final IoSession session, final Object message,
    182                 final ReadFilterChainController controller) {
    183             LOG.info("** message received {}", message);
    184             msgReadLatch.countDown();
    185             session.write(message.toString());
    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("** sesssion idle {}", session);
    197             session.close(false);
    198         }
    199     }
    200 }