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.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 NioUdpServer}.
44   * 
45   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
46   */
47  public class NioUdpServerFilterEventTest {
48  
49      private static final Logger LOG = LoggerFactory.getLogger(NioUdpServerFilterEventTest.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      @Test
62      public void generate_all_kind_of_server_event() throws IOException, InterruptedException {
63          final NioUdpServer server = new NioUdpServer();
64          server.getSessionConfig().setIdleTimeInMillis(IdleStatus.READ_IDLE, 2000);
65          server.setFilters(new MyCodec(), new Handler());
66          server.bind(0);
67          // warm up
68          // Thread.sleep(100);
69  
70          final int port = server.getDatagramChannel().socket().getLocalPort();
71  
72          final DatagramSocket[] clients = new DatagramSocket[CLIENT_COUNT];
73  
74          InetSocketAddress serverAddy = new InetSocketAddress("127.0.0.1", port);
75          // connect some clients
76          for (int i = 0; i < CLIENT_COUNT; i++) {
77              try {
78                  clients[i] = new DatagramSocket();
79              } catch (Exception e) {
80                  e.printStackTrace();
81                  System.out.println("Creation client " + i + " failed");
82              }
83          }
84  
85          // write some messages
86          for (int i = 0; i < CLIENT_COUNT; i++) {
87              byte[] data = ("test:" + i).getBytes();
88              clients[i].send(new DatagramPacket(data, data.length, serverAddy));
89          }
90  
91          // does the session open message was fired ?
92          assertTrue(openLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
93  
94          // test is message was received by the server
95          assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
96  
97          // does response was wrote and sent ?
98          assertTrue(msgSentLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
99  
100         // read the echos
101         final byte[] buffer = new byte[1024];
102 
103         for (int i = 0; i < CLIENT_COUNT; i++) {
104             DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
105             clients[i].receive(dp);
106             final String text = new String(buffer, 0, dp.getLength());
107             assertEquals("test:" + i, text);
108         }
109 
110         msgReadLatch = new CountDownLatch(CLIENT_COUNT);
111 
112         // try again
113         // write some messages again
114         for (int i = 0; i < CLIENT_COUNT; i++) {
115             byte[] data = ("test:" + i).getBytes();
116             clients[i].send(new DatagramPacket(data, data.length, serverAddy));
117         }
118 
119         // test is message was received by the server
120         assertTrue(msgReadLatch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
121 
122         // wait echo
123 
124         // close the session
125         for (int i = 0; i < CLIENT_COUNT; i++) {
126             clients[i].close();
127         }
128 
129         server.unbind();
130     }
131 
132     private class MyCodec extends AbstractIoFilter {
133 
134         @Override
135         public void messageReceived(final IoSession session, final Object message,
136                 final ReadFilterChainController controller) {
137             if (message instanceof ByteBuffer) {
138                 final ByteBuffer in = (ByteBuffer) message;
139                 final byte[] buffer = new byte[in.remaining()];
140                 in.get(buffer);
141                 controller.callReadNextFilter(new String(buffer));
142             } else {
143                 fail();
144             }
145         }
146 
147         @Override
148         public void messageWriting(IoSession session, WriteRequest writeRequest, WriteFilterChainController controller) {
149             writeRequest.setMessage(ByteBuffer.wrap(writeRequest.getMessage().toString().getBytes()));
150             controller.callWriteNextFilter(writeRequest);
151         }
152     }
153 
154     private class Handler extends AbstractIoFilter {
155 
156         @Override
157         public void sessionOpened(final IoSession session) {
158             LOG.info("** session open");
159             openLatch.countDown();
160         }
161 
162         @Override
163         public void sessionClosed(final IoSession session) {
164             LOG.info("** session closed");
165         }
166 
167         @Override
168         public void messageReceived(final IoSession session, final Object message,
169                 final ReadFilterChainController controller) {
170             LOG.info("** message received {}", message);
171             msgReadLatch.countDown();
172             session.write(message.toString());
173         }
174 
175         @Override
176         public void messageSent(final IoSession session, final Object message) {
177             LOG.info("** message sent {}", message);
178             msgSentLatch.countDown();
179         }
180 
181         @Override
182         public void sessionIdle(IoSession session, IdleStatus status) {
183             LOG.info("** sesssion idle {}", session);
184             session.close(false);
185         }
186     }
187 }