1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.spring.events;
12
13 import org.mule.api.MuleEventContext;
14 import org.mule.api.MuleException;
15 import org.mule.api.MuleMessage;
16 import org.mule.module.client.MuleClient;
17 import org.mule.tck.FunctionalTestCase;
18 import org.mule.tck.functional.EventCallback;
19 import org.mule.transformer.AbstractMessageTransformer;
20 import org.mule.util.ExceptionUtils;
21 import org.mule.util.concurrent.Latch;
22
23 import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
24 import edu.emory.mathcs.backport.java.util.concurrent.Executors;
25 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
26 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
27 import org.springframework.context.ApplicationContext;
28 import org.springframework.context.ApplicationEvent;
29 import org.springframework.context.event.ContextRefreshedEvent;
30 import org.springframework.context.support.AbstractApplicationContext;
31
32 public class SpringEventsTestCase extends FunctionalTestCase
33 {
34 protected static final int DEFAULT_LATCH_TIMEOUT = 10000;
35
36 private static final int NUMBER_OF_MESSAGES = 10;
37 volatile AtomicInteger eventCounter1;
38 volatile AtomicInteger eventCounter2;
39
40 @Override
41 protected void doSetUp() throws Exception
42 {
43 super.doSetUp();
44 eventCounter1 = new AtomicInteger(0);
45 eventCounter2 = new AtomicInteger(0);
46 }
47
48 @Override
49 protected String getConfigResources()
50 {
51 return "mule-events-app-context.xml";
52 }
53
54 public void testManagerIsInstanciated() throws Exception
55 {
56 assertTrue(muleContext.isInitialised());
57 assertTrue(muleContext.isStarted());
58 assertNotNull(muleContext.getRegistry().lookupObject(
59 AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME));
60 }
61
62 public void testRemovingListeners() throws Exception
63 {
64 TestSubscriptionEventBean subscriptionBean = (TestSubscriptionEventBean) muleContext.getRegistry()
65 .lookupObject("testSubscribingEventBean1");
66 assertNotNull(subscriptionBean);
67 MuleEventMulticaster multicaster = (MuleEventMulticaster) muleContext.getRegistry().lookupObject(
68 AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
69 assertNotNull(multicaster);
70
71 Latch whenFinished = new Latch();
72 subscriptionBean.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));
73
74 multicaster.removeApplicationListener(subscriptionBean);
75 MuleClient client = new MuleClient(muleContext);
76 client.send("vm://event.multicaster", "Test Spring MuleEvent", null);
77
78 assertEquals(0, eventCounter1.get());
79
80 multicaster.addApplicationListener(subscriptionBean);
81 client.send("vm://event.multicaster", "Test Spring MuleEvent", null);
82
83 assertTrue(whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
84 assertEquals(1, eventCounter1.get());
85 eventCounter1.set(0);
86
87 multicaster.removeAllListeners();
88 client.send("vm://event.multicaster", "Test Spring MuleEvent", null);
89
90 assertEquals(0, eventCounter1.get());
91 multicaster.addApplicationListener(subscriptionBean);
92
93 subscriptionBean.setEventCallback(null);
94 }
95
96 public void testReceivingANonSubscriptionMuleEvent() throws Exception
97 {
98 TestMuleEventBean bean = (TestMuleEventBean) muleContext.getRegistry().lookupObject(
99 "testNonSubscribingMuleEventBean");
100 assertNotNull(bean);
101
102
103 Latch whenFinished = new Latch();
104 bean.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));
105
106 MuleClient client = new MuleClient(muleContext);
107 client.send("vm://event.multicaster", "Test Spring MuleEvent", null);
108
109 whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
110 assertEquals(1, eventCounter1.get());
111 }
112
113 public void testReceivingASpringEvent() throws Exception
114 {
115 TestApplicationEventBean bean = (TestApplicationEventBean) muleContext.getRegistry().lookupObject(
116 "testEventSpringBean");
117 assertNotNull(bean);
118
119 final Latch whenFinished = new Latch();
120 EventCallback callback = new EventCallback()
121 {
122 public void eventReceived(MuleEventContext context, Object o) throws Exception
123 {
124 assertNull(context);
125 if (o instanceof TestApplicationEvent)
126 {
127 if (eventCounter1.incrementAndGet() == 1)
128 {
129 whenFinished.countDown();
130 }
131 }
132 }
133 };
134
135 bean.setEventCallback(callback);
136
137 ApplicationContext context = ((MuleEventMulticaster) muleContext.getRegistry().lookupObject(
138 "applicationEventMulticaster")).applicationContext;
139 context.publishEvent(new TestApplicationEvent(context));
140
141 whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
142 assertEquals(1, eventCounter1.get());
143 }
144
145 public void testReceivingAllEvents() throws Exception
146 {
147 TestAllEventBean bean = (TestAllEventBean) muleContext.getRegistry().lookupObject("testAllEventBean");
148 assertNotNull(bean);
149
150 Latch whenFinished = new Latch();
151 bean.setEventCallback(new CountingEventCallback(eventCounter1, 2, whenFinished));
152
153 MuleClient client = new MuleClient(muleContext);
154 client.send("vm://event.multicaster", "Test Spring MuleEvent", null);
155 ApplicationContext context = ((MuleEventMulticaster) muleContext.getRegistry().lookupObject(
156 "applicationEventMulticaster")).applicationContext;
157 context.publishEvent(new TestApplicationEvent(context));
158
159 whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
160 assertEquals(2, eventCounter1.get());
161 }
162
163 public void testReceivingASubscriptionEvent() throws Exception
164 {
165 TestSubscriptionEventBean subscriptionBean = (TestSubscriptionEventBean) muleContext.getRegistry()
166 .lookupObject("testSubscribingEventBean1");
167 assertNotNull(subscriptionBean);
168
169 Latch whenFinished = new Latch();
170 subscriptionBean.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));
171
172 MuleClient client = new MuleClient(muleContext);
173 client.send("vm://event.multicaster", "Test Spring MuleEvent", null);
174
175 whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
176 assertEquals(1, eventCounter1.get());
177 }
178
179 public void testReceiveAndPublishEvent() throws Exception
180 {
181 TestSubscriptionEventBean bean1 = (TestSubscriptionEventBean) muleContext.getRegistry().lookupObject(
182 "testSubscribingEventBean1");
183 assertNotNull(bean1);
184
185 final Latch whenFinished1 = new Latch();
186 EventCallback callback = new EventCallback()
187 {
188 public void eventReceived(MuleEventContext context, Object o) throws Exception
189 {
190 MuleApplicationEvent returnEvent = new MuleApplicationEvent("MuleEvent from a spring bean",
191 "vm://testBean2");
192 MuleApplicationEvent e = (MuleApplicationEvent) o;
193 e.getApplicationContext().publishEvent(returnEvent);
194 if (eventCounter1.incrementAndGet() == NUMBER_OF_MESSAGES)
195 {
196 whenFinished1.countDown();
197 }
198 }
199 };
200 bean1.setEventCallback(callback);
201
202 TestSubscriptionEventBean bean2 = (TestSubscriptionEventBean) muleContext.getRegistry().lookupObject(
203 "testSubscribingEventBean2");
204 assertNotNull(bean2);
205
206 Latch whenFinished2 = new Latch();
207 bean2.setEventCallback(new CountingEventCallback(eventCounter2, NUMBER_OF_MESSAGES, whenFinished2));
208
209
210 this.doSend("vm://event.multicaster", "Test Spring MuleEvent", NUMBER_OF_MESSAGES);
211
212 whenFinished1.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
213 whenFinished2.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
214 assertEquals(NUMBER_OF_MESSAGES, eventCounter1.get());
215 assertEquals(NUMBER_OF_MESSAGES, eventCounter2.get());
216 }
217
218 public void testPublishOnly() throws Exception
219 {
220 final MuleApplicationEvent event = new MuleApplicationEvent("MuleEvent from a spring bean",
221 "vm://testBean2");
222
223 TestSubscriptionEventBean bean2 = (TestSubscriptionEventBean) muleContext.getRegistry().lookupObject(
224 "testSubscribingEventBean2");
225 assertNotNull(bean2);
226
227 Latch whenFinished = new Latch();
228 bean2.setEventCallback(new CountingEventCallback(eventCounter1, NUMBER_OF_MESSAGES, whenFinished));
229
230
231 this.doPublish(event, NUMBER_OF_MESSAGES);
232
233 whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
234 assertEquals(NUMBER_OF_MESSAGES, eventCounter1.get());
235 }
236
237 public void testPublishWithEventAwareTransformer() throws Exception
238 {
239 CountDownLatch transformerLatch = new CountDownLatch(1);
240
241 TestEventAwareTransformer trans = new TestEventAwareTransformer();
242 trans.setLatch(transformerLatch);
243 muleContext.getRegistry().registerTransformer(trans);
244
245 MuleApplicationEvent event = new MuleApplicationEvent("MuleEvent from a spring bean",
246 "vm://testBean2?transformers=dummyTransformer");
247
248 TestSubscriptionEventBean bean2 = (TestSubscriptionEventBean) muleContext.getRegistry().lookupObject(
249 "testSubscribingEventBean2");
250 assertNotNull(bean2);
251
252 Latch whenFinished = new Latch();
253 bean2.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));
254
255
256 this.doPublish(event, 1);
257
258 whenFinished.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
259 assertTrue(transformerLatch.await(DEFAULT_LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
260 assertEquals(1, eventCounter1.get());
261 }
262
263
264 protected void doPublish(final ApplicationEvent event, final int count)
265 {
266 Runnable publisher = new Runnable()
267 {
268 public void run()
269 {
270 for (int i = 0; i < count; i++)
271 {
272 ApplicationContext context = null;
273 try
274 {
275 context = ((MuleEventMulticaster) muleContext.getRegistry().lookupObject(
276 "applicationEventMulticaster")).applicationContext;
277 context.publishEvent(event);
278 }
279 catch (IllegalArgumentException e)
280 {
281
282 e.printStackTrace();
283 }
284 catch (SecurityException e)
285 {
286
287 e.printStackTrace();
288 }
289 }
290 }
291 };
292
293 Executors.newSingleThreadExecutor().execute(publisher);
294 }
295
296
297 protected void doSend(final String url, final Object payload, final int count)
298 {
299 Runnable sender = new Runnable()
300 {
301 public void run()
302 {
303 try
304 {
305 MuleClient client = new MuleClient(muleContext);
306 for (int i = 0; i < count; i++)
307 {
308 client.send(url, payload, null);
309 }
310 }
311 catch (MuleException ex)
312 {
313 fail(ExceptionUtils.getStackTrace(ex));
314 }
315 }
316 };
317
318
319 Executors.newSingleThreadExecutor().execute(sender);
320 }
321
322
323
324
325
326
327
328 public static class CountingEventCallback implements EventCallback
329 {
330 private final AtomicInteger counter;
331 private final int maxCount;
332 private final CountDownLatch finished;
333
334 public CountingEventCallback(AtomicInteger counter, int maxCount, CountDownLatch whenFinished)
335 {
336 super();
337 this.counter = counter;
338 this.maxCount = maxCount;
339 this.finished = whenFinished;
340 }
341
342 public void eventReceived(MuleEventContext context, Object o) throws Exception
343 {
344
345
346
347 if (!(o instanceof ContextRefreshedEvent))
348 {
349 if (counter.incrementAndGet() == maxCount && finished != null)
350 {
351 finished.countDown();
352 }
353 }
354 }
355 }
356
357
358
359
360
361 public static class TestEventAwareTransformer extends AbstractMessageTransformer
362 {
363 private CountDownLatch latch;
364
365 public TestEventAwareTransformer()
366 {
367 this.setName("dummyTransformer");
368 }
369
370 @Override
371 public Object clone() throws CloneNotSupportedException
372 {
373 TestEventAwareTransformer clone = (TestEventAwareTransformer) super.clone();
374
375
376
377 clone.setLatch(latch);
378 return clone;
379 }
380
381 public CountDownLatch getLatch()
382 {
383 return latch;
384 }
385
386 public void setLatch(CountDownLatch latch)
387 {
388 this.latch = latch;
389 }
390
391 @Override
392 public Object transformMessage(MuleMessage message, String outputEncoding)
393 {
394 assertNotNull(message);
395
396 if (latch != null)
397 {
398 latch.countDown();
399 }
400
401 return message;
402 }
403 }
404
405
406
407
408 public static class TestApplicationEvent extends ApplicationEvent
409 {
410 private static final long serialVersionUID = 1L;
411
412 public TestApplicationEvent(Object source)
413 {
414 super(source);
415 }
416 }
417
418 }