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