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 }