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