View Javadoc

1   /*
2    * $Id: KeepSendSocketOpenMule1491TestCase.java 22461 2011-07-20 07:48:55Z justin.calleja $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.tcp.issues;
12  
13  import static org.junit.Assert.assertEquals;
14  
15  import java.io.BufferedInputStream;
16  import java.io.InputStream;
17  import java.net.InetSocketAddress;
18  import java.net.ServerSocket;
19  import java.net.Socket;
20  import java.util.Arrays;
21  import java.util.Collection;
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.concurrent.atomic.AtomicBoolean;
25  import java.util.concurrent.atomic.AtomicInteger;
26  
27  import org.junit.Rule;
28  import org.junit.Test;
29  import org.junit.runners.Parameterized.Parameters;
30  import org.mule.api.MuleMessage;
31  import org.mule.module.client.MuleClient;
32  import org.mule.tck.AbstractServiceAndFlowTestCase;
33  import org.mule.tck.junit4.rule.DynamicPort;
34  import org.mule.transport.tcp.protocols.LengthProtocol;
35  
36  public class KeepSendSocketOpenMule1491TestCase extends AbstractServiceAndFlowTestCase
37  {
38      protected static String TEST_TCP_MESSAGE = "Test TCP Request";
39  
40      @Rule
41      public DynamicPort dynamicPort1 = new DynamicPort("port1");
42  
43      @Rule
44      public DynamicPort dynamicPort2 = new DynamicPort("port2");
45  
46      @Rule
47      public DynamicPort dynamicPort3 = new DynamicPort("port3");
48  
49      public KeepSendSocketOpenMule1491TestCase(ConfigVariant variant, String configResources)
50      {
51          super(variant, configResources);
52      }
53          
54      @Parameters
55      public static Collection<Object[]> parameters()
56      {
57          return Arrays.asList(new Object[][]{{ConfigVariant.SERVICE, "tcp-keep-send-socket-open-service.xml"},
58              {ConfigVariant.FLOW, "tcp-keep-send-socket-open-flow.xml"}});
59      }
60  
61      @Test
62      public void testSend() throws Exception
63      {
64          MuleClient client = new MuleClient(muleContext);
65          
66          Map<String, Object> props = new HashMap<String, Object>();
67          MuleMessage result = client.send("clientEndpoint", TEST_TCP_MESSAGE, props);
68          assertEquals(TEST_TCP_MESSAGE + " Received", result.getPayloadAsString());
69          
70          // try an extra message in case it's a problem on repeat
71          result = client.send("clientEndpoint", TEST_TCP_MESSAGE, props);
72          assertEquals(TEST_TCP_MESSAGE + " Received", result.getPayloadAsString());
73      }
74  
75      private void useServer(String endpoint, int port, int count) throws Exception
76      {
77          SimpleServerSocket server = new SimpleServerSocket(port);
78          try
79          {
80              new Thread(server).start();
81              MuleClient client = new MuleClient(muleContext);
82              client.send(endpoint, "Hello", null);
83              client.send(endpoint, "world", null);
84              assertEquals(count, server.getCount());
85          }
86          finally
87          {
88              server.close();
89          }
90      }
91  
92      @Test
93      public void testOpen() throws Exception
94      {
95          useServer("tcp://localhost:" + dynamicPort2.getNumber() + "?connector=openConnectorLength", dynamicPort2.getNumber(), 1);
96      }
97  
98      @Test
99      public void testClose() throws Exception
100     {
101         useServer("tcp://localhost:" + dynamicPort3.getNumber() + "?connector=closeConnectorLength", dynamicPort3.getNumber(), 2);
102     }
103 
104     @SuppressWarnings("synthetic-access")
105     private class SimpleServerSocket implements Runnable
106     { 
107         private ServerSocket server;
108         AtomicBoolean running = new AtomicBoolean(true);
109         AtomicInteger count = new AtomicInteger(0);
110 
111         public SimpleServerSocket(int port) throws Exception
112         {
113             server = new ServerSocket();
114             logger.debug("starting server");
115             server.bind(new InetSocketAddress("localhost", port), 3);
116         }
117 
118         public int getCount()
119         {
120             return count.get();
121         }
122 
123         @Override
124         public void run()
125         {
126             try
127             {
128                 LengthProtocol protocol = new LengthProtocol();
129                 while (true)
130                 {
131                     Socket socket = server.accept();
132                     logger.debug("have connection " + count);
133                     count.incrementAndGet();
134                     InputStream stream = new BufferedInputStream(socket.getInputStream());
135                     // repeat for as many messages as we receive until null received
136                     while (true)
137                     {
138                         Object read = protocol.read(stream);
139                         if (null == read)
140                         {
141                             break;
142                         }
143                         String msg = new String((byte[]) read);
144                         logger.debug("read: " + msg);
145                         logger.debug("writing reply");
146                         protocol.write(socket.getOutputStream(), "ok");
147                     }
148                 }
149             }
150             catch (Exception e)
151             {
152                 // an exception is expected during shutdown
153                 if (running.get())
154                 {
155                     throw new RuntimeException(e);
156                 }
157             }
158         }
159 
160         public void close()
161         {
162             try
163             {
164                 running.set(false);
165                 server.close();
166             }
167             catch (Exception e)
168             {
169                 // no-op
170             }
171         }
172     }
173 }