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 }