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