1
2
3
4
5
6
7 package org.mule.transport.tcp.issues;
8
9 import org.mule.api.MuleMessage;
10 import org.mule.module.client.MuleClient;
11 import org.mule.tck.junit4.FunctionalTestCase;
12 import org.mule.tck.junit4.rule.DynamicPort;
13 import org.mule.transport.tcp.protocols.LengthProtocol;
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.HashMap;
21 import java.util.Map;
22
23 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
24 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
25 import org.junit.Rule;
26 import org.junit.Test;
27
28 import static org.junit.Assert.assertEquals;
29
30 public class KeepSendSocketOpenMule1491TestCase extends FunctionalTestCase
31 {
32
33 protected static String TEST_TCP_MESSAGE = "Test TCP Request";
34
35 @Rule
36 public DynamicPort dynamicPort1 = new DynamicPort("port1");
37
38 @Rule
39 public DynamicPort dynamicPort2 = new DynamicPort("port2");
40
41 @Rule
42 public DynamicPort dynamicPort3 = new DynamicPort("port3");
43
44 @Override
45 protected String getConfigResources()
46 {
47 return "tcp-keep-send-socket-open.xml";
48 }
49
50 @Test
51 public void testSend() throws Exception
52 {
53 MuleClient client = new MuleClient(muleContext);
54
55 Map<String, Object> props = new HashMap<String, Object>();
56 MuleMessage result = client.send("clientEndpoint", TEST_TCP_MESSAGE, props);
57 assertEquals(TEST_TCP_MESSAGE + " Received", result.getPayloadAsString());
58
59
60 result = client.send("clientEndpoint", TEST_TCP_MESSAGE, props);
61 assertEquals(TEST_TCP_MESSAGE + " Received", result.getPayloadAsString());
62 }
63
64 private void useServer(String endpoint, int port, int count) throws Exception
65 {
66 SimpleServerSocket server = new SimpleServerSocket(port);
67 try
68 {
69 new Thread(server).start();
70 MuleClient client = new MuleClient(muleContext);
71 client.send(endpoint, "Hello", null);
72 client.send(endpoint, "world", null);
73 assertEquals(count, server.getCount());
74 }
75 finally
76 {
77 server.close();
78 }
79 }
80
81 @Test
82 public void testOpen() throws Exception
83 {
84 useServer("tcp://localhost:" + dynamicPort2.getNumber() + "?connector=openConnectorLength", dynamicPort2.getNumber(), 1);
85 }
86
87 @Test
88 public void testClose() throws Exception
89 {
90 useServer("tcp://localhost:" + dynamicPort3.getNumber() + "?connector=closeConnectorLength", dynamicPort3.getNumber(), 2);
91 }
92
93 @SuppressWarnings("synthetic-access")
94 private class SimpleServerSocket implements Runnable
95 {
96 private ServerSocket server;
97 AtomicBoolean running = new AtomicBoolean(true);
98 AtomicInteger count = new AtomicInteger(0);
99
100 public SimpleServerSocket(int port) throws Exception
101 {
102 server = new ServerSocket();
103 logger.debug("starting server");
104 server.bind(new InetSocketAddress("localhost", port), 3);
105 }
106
107 public int getCount()
108 {
109 return count.get();
110 }
111
112 public void run()
113 {
114 try
115 {
116 LengthProtocol protocol = new LengthProtocol();
117 while (true)
118 {
119 Socket socket = server.accept();
120 logger.debug("have connection " + count);
121 count.incrementAndGet();
122 InputStream stream = new BufferedInputStream(socket.getInputStream());
123
124 while (true)
125 {
126 Object read = protocol.read(stream);
127 if (null == read)
128 {
129 break;
130 }
131 String msg = new String((byte[]) read);
132 logger.debug("read: " + msg);
133 logger.debug("writing reply");
134 protocol.write(socket.getOutputStream(), "ok");
135 }
136 }
137 }
138 catch (Exception e)
139 {
140
141 if (running.get())
142 {
143 throw new RuntimeException(e);
144 }
145 }
146 }
147
148 public void close()
149 {
150 try
151 {
152 running.set(false);
153 server.close();
154 }
155 catch (Exception e)
156 {
157
158 }
159 }
160 }
161
162 }