1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.MessageExchangePattern;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleException;
16 import org.mule.api.config.ThreadingProfile;
17 import org.mule.api.endpoint.OutboundEndpoint;
18 import org.mule.api.transport.DispatchException;
19 import org.mule.api.transport.MessageDispatcher;
20 import org.mule.config.ImmutableThreadingProfile;
21 import org.mule.tck.junit4.AbstractMuleContextTestCase;
22 import org.mule.tck.testmodels.mule.TestConnector;
23 import org.mule.tck.testmodels.mule.TestMessageDispatcher;
24 import org.mule.tck.testmodels.mule.TestMessageDispatcherFactory;
25
26 import java.util.concurrent.CountDownLatch;
27 import java.util.concurrent.TimeUnit;
28 import java.util.concurrent.atomic.AtomicInteger;
29 import org.junit.Test;
30
31 import static org.junit.Assert.assertEquals;
32 import static org.junit.Assert.assertTrue;
33
34
35
36
37
38
39
40 public class DispatcherThreadingProfileTestCase extends AbstractMuleContextTestCase
41 {
42
43 public static int DELAY_TIME = 500;
44 public static int WAIT_TIME = DELAY_TIME + DELAY_TIME / 4;
45 public static int SERIAL_WAIT_TIME = (DELAY_TIME * 2) + DELAY_TIME / 4;
46 public static int LONGER_WAIT_TIME = DELAY_TIME * 5;
47 private CountDownLatch latch;
48 private AtomicInteger counter = new AtomicInteger();
49
50 public DispatcherThreadingProfileTestCase()
51 {
52 setStartContext(true);
53 }
54
55 @Override
56 protected void doTearDown() throws Exception
57 {
58 super.doTearDown();
59 counter.set(0);
60 }
61
62 @Test
63 public void testDefaultThreadingProfileConfiguration() throws MuleException
64 {
65 TestConnector connector = new TestConnector(muleContext);
66 muleContext.getRegistry().registerConnector(connector);
67 assertEquals(ThreadingProfile.DEFAULT_MAX_THREADS_ACTIVE, connector.getDispatcherThreadingProfile()
68 .getMaxThreadsActive());
69 assertEquals(ThreadingProfile.DEFAULT_MAX_THREADS_IDLE, connector.getDispatcherThreadingProfile()
70 .getMaxThreadsIdle());
71 assertEquals(ThreadingProfile.WHEN_EXHAUSTED_RUN, connector.getDispatcherThreadingProfile()
72 .getPoolExhaustedAction());
73 assertEquals(ThreadingProfile.DEFAULT_MAX_BUFFER_SIZE, connector.getDispatcherThreadingProfile()
74 .getMaxBufferSize());
75 assertEquals(ThreadingProfile.DEFAULT_MAX_THREAD_TTL, connector.getDispatcherThreadingProfile()
76 .getThreadTTL());
77 assertEquals(ThreadingProfile.DEFAULT_THREAD_WAIT_TIMEOUT, connector.getDispatcherThreadingProfile()
78 .getThreadWaitTimeout());
79 }
80
81 @Test
82 public void testDefaultRunExhaustedAction() throws Exception
83 {
84
85
86
87
88
89 latch = new CountDownLatch(2);
90
91 createTestConnectorWithSingleDispatcherThread(ThreadingProfile.WHEN_EXHAUSTED_RUN);
92 dispatchTwoAsyncEvents();
93
94
95 assertTrue(latch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
96 }
97
98 @Test
99 public void testWaitExhaustedAction() throws Exception
100 {
101
102 latch = new CountDownLatch(2);
103
104 createTestConnectorWithSingleDispatcherThread(1, ThreadingProfile.WHEN_EXHAUSTED_WAIT,
105 ThreadingProfile.DEFAULT_THREAD_WAIT_TIMEOUT, ThreadingProfile.DEFAULT_MAX_BUFFER_SIZE);
106 dispatchTwoAsyncEvents();
107
108
109 assertTrue(latch.await(SERIAL_WAIT_TIME, TimeUnit.MILLISECONDS));
110 }
111
112 @Test
113 public void testWaitTimeoutExhaustedAction() throws Exception
114 {
115
116 latch = new CountDownLatch(1);
117
118 createTestConnectorWithSingleDispatcherThread(ThreadingProfile.WHEN_EXHAUSTED_WAIT);
119 dispatchTwoAsyncEvents();
120
121
122 assertTrue(latch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
123
124
125 Thread.sleep(LONGER_WAIT_TIME);
126 assertEquals(1, counter.get());
127 }
128
129 @Test
130 public void testAbortExhaustedAction() throws Exception
131 {
132
133 latch = new CountDownLatch(1);
134
135 createTestConnectorWithSingleDispatcherThread(ThreadingProfile.WHEN_EXHAUSTED_ABORT);
136 dispatchTwoAsyncEvents();
137
138
139 assertTrue(latch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
140
141
142 Thread.sleep(LONGER_WAIT_TIME);
143 assertEquals(1, counter.get());
144 }
145
146 @Test
147 public void testDiscardExhaustedAction() throws Exception
148 {
149
150 latch = new CountDownLatch(1);
151
152 createTestConnectorWithSingleDispatcherThread(ThreadingProfile.WHEN_EXHAUSTED_DISCARD);
153 dispatchTwoAsyncEvents();
154
155
156 assertTrue(latch.await(WAIT_TIME, TimeUnit.MILLISECONDS));
157
158
159 Thread.sleep(LONGER_WAIT_TIME);
160 assertEquals(1, counter.get());
161 }
162
163 @Test
164 public void testDiscardOldestExhaustedAction() throws Exception
165 {
166
167
168
169
170 latch = new CountDownLatch(3);
171
172
173
174
175 createTestConnectorWithSingleDispatcherThread(2, ThreadingProfile.WHEN_EXHAUSTED_DISCARD_OLDEST,
176 ThreadingProfile.DEFAULT_THREAD_WAIT_TIMEOUT, 1);
177
178 dispatchTwoAsyncEvents();
179 dispatchTwoAsyncEvents();
180 dispatchTwoAsyncEvents();
181
182 assertTrue(latch.await(SERIAL_WAIT_TIME, TimeUnit.MILLISECONDS));
183 Thread.sleep(LONGER_WAIT_TIME);
184 assertEquals(3, counter.get());
185 }
186
187 protected void createTestConnectorWithSingleDispatcherThread(int exhaustedAction) throws MuleException
188 {
189 createTestConnectorWithSingleDispatcherThread(1, exhaustedAction, 1, 1);
190 }
191
192 protected void createTestConnectorWithSingleDispatcherThread(int threads,
193 int exhaustedAction,
194 long waitTimeout,
195 int maxBufferSize) throws MuleException
196 {
197 TestConnector connector = new TestConnector(muleContext);
198 ThreadingProfile threadingProfile = new ImmutableThreadingProfile(threads, threads, maxBufferSize,
199 ThreadingProfile.DEFAULT_MAX_THREAD_TTL, waitTimeout, exhaustedAction, true, null, null);
200 threadingProfile.setMuleContext(muleContext);
201 connector.setDispatcherThreadingProfile(threadingProfile);
202 muleContext.getRegistry().registerConnector(connector);
203 connector.setDispatcherFactory(new DelayTestMessageDispatcherFactory());
204 }
205
206 private void dispatchTwoAsyncEvents() throws DispatchException, Exception
207 {
208 OutboundEndpoint endpoint = muleContext.getEndpointFactory().getOutboundEndpoint(
209 "test://test");
210 endpoint.process(getTestEvent("data", getTestInboundEndpoint(MessageExchangePattern.ONE_WAY)));
211 endpoint.process(getTestEvent("data", getTestInboundEndpoint(MessageExchangePattern.ONE_WAY)));
212 }
213
214 public class DelayTestMessageDispatcher extends TestMessageDispatcher
215 {
216 public DelayTestMessageDispatcher(OutboundEndpoint endpoint)
217 {
218 super(endpoint);
219 }
220
221 @Override
222 protected void doDispatch(MuleEvent event) throws Exception
223 {
224 super.doDispatch(event);
225 Thread.sleep(DELAY_TIME);
226 counter.incrementAndGet();
227 latch.countDown();
228 }
229 }
230
231 class DelayTestMessageDispatcherFactory extends TestMessageDispatcherFactory
232 {
233 @Override
234 public MessageDispatcher create(OutboundEndpoint endpoint) throws MuleException
235 {
236 return new DelayTestMessageDispatcher(endpoint);
237 }
238 }
239
240 }