1
2
3
4
5
6
7 package org.mule.tck.functional;
8
9 import org.mule.RequestContext;
10 import org.mule.api.MuleContext;
11 import org.mule.api.MuleEventContext;
12 import org.mule.api.MuleException;
13 import org.mule.api.MuleMessage;
14 import org.mule.api.context.MuleContextAware;
15 import org.mule.api.lifecycle.Callable;
16 import org.mule.api.lifecycle.Disposable;
17 import org.mule.api.lifecycle.Initialisable;
18 import org.mule.api.lifecycle.Startable;
19 import org.mule.api.lifecycle.Stoppable;
20 import org.mule.tck.exceptions.FunctionalTestException;
21 import org.mule.util.NumberUtils;
22 import org.mule.util.StringMessageUtils;
23 import org.mule.util.SystemUtils;
24
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class FunctionalTestComponent implements Callable, Initialisable, Disposable, MuleContextAware, Receiveable, Startable, Stoppable
48 {
49 protected transient Log logger = LogFactory.getLog(getClass());
50
51 public static final int STREAM_SAMPLE_SIZE = 4;
52 public static final int STREAM_BUFFER_SIZE = 4096;
53 private EventCallback eventCallback;
54 private Object returnData = null;
55 private boolean throwException = false;
56 private boolean enableMessageHistory = true;
57 private boolean enableNotifications = true;
58 private boolean doInboundTransform = true;
59 private String appendString;
60 private Class<? extends Throwable> exceptionToThrow;
61 private long waitTime = 0;
62 private boolean logMessageDetails = false;
63 private String id = "<none>";
64 private MuleContext muleContext;
65 private static List<LifecycleCallback> lifecycleCallbacks = new ArrayList<LifecycleCallback>();
66
67
68
69
70
71
72
73 private List<Object> messageHistory;
74
75 @SuppressWarnings("unchecked")
76 public void initialise()
77 {
78 if (enableMessageHistory)
79 {
80 messageHistory = new CopyOnWriteArrayList();
81 }
82 for (LifecycleCallback callback : lifecycleCallbacks)
83 {
84 callback.onTransition(id, Initialisable.PHASE_NAME);
85 }
86 }
87
88 public void start() throws MuleException
89 {
90 for (LifecycleCallback callback : lifecycleCallbacks)
91 {
92 callback.onTransition(id, Startable.PHASE_NAME);
93 }
94 }
95
96 public void setMuleContext(MuleContext context)
97 {
98 this.muleContext = context;
99 }
100
101 public void stop() throws MuleException
102 {
103 for (LifecycleCallback callback : lifecycleCallbacks)
104 {
105 callback.onTransition(id, Stoppable.PHASE_NAME);
106 }
107 }
108
109 public void dispose()
110 {
111 for (LifecycleCallback callback : lifecycleCallbacks)
112 {
113 callback.onTransition(id, Disposable.PHASE_NAME);
114 }
115 }
116
117
118
119
120 public Object onCall(MuleEventContext context) throws Exception
121 {
122 if (isThrowException())
123 {
124 throwException();
125 }
126 return process(getMessageFromContext(context), context);
127 }
128
129 private Object getMessageFromContext(MuleEventContext context) throws MuleException
130 {
131 if (isDoInboundTransform())
132 {
133 Object o = context.getMessage().getPayload();
134 if (getAppendString() != null && !(o instanceof String))
135 {
136 o = context.transformMessageToString();
137 }
138 return o;
139 }
140 else if (getAppendString()!=null)
141 {
142 return context.getMessageAsString();
143 }
144 else
145 {
146 return context.getMessage().getPayload();
147 }
148 }
149
150
151
152
153
154
155
156
157
158 public Object onReceive(Object data) throws Exception
159 {
160 MuleEventContext context = RequestContext.getEventContext();
161
162 if (isThrowException())
163 {
164 throwException();
165 }
166 return process(data, context);
167 }
168
169
170
171
172
173
174
175
176 protected void throwException() throws Exception
177 {
178 if (getExceptionToThrow() != null)
179 {
180 throw (Exception)getExceptionToThrow().newInstance();
181 }
182 else
183 {
184 throw new FunctionalTestException();
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197 protected String append(String contents, MuleMessage message)
198 {
199 return contents + muleContext.getExpressionManager().parse(appendString, message);
200 }
201
202
203
204
205
206
207
208
209
210
211 protected Object process(Object data, MuleEventContext context) throws Exception
212 {
213
214 if (enableMessageHistory)
215 {
216 messageHistory.add(data);
217 }
218
219 if (logger.isInfoEnabled())
220 {
221 String msg = StringMessageUtils.getBoilerPlate("Message Received in service: "
222 + context.getFlowConstruct().getName() + ". Content is: "
223 + StringMessageUtils.truncate(data.toString(), 100, true), '*', 80);
224
225 logger.info(msg);
226 }
227
228 final MuleMessage message = context.getMessage();
229 if (isLogMessageDetails() && logger.isInfoEnabled())
230 {
231 StringBuilder sb = new StringBuilder();
232
233 sb.append("Full Message payload: ").append(SystemUtils.LINE_SEPARATOR);
234 sb.append(message.getPayload()).append(SystemUtils.LINE_SEPARATOR);
235 sb.append(StringMessageUtils.headersToString(message));
236 logger.info(sb.toString());
237 }
238
239 if (eventCallback != null)
240 {
241 eventCallback.eventReceived(context, this);
242 }
243
244 Object replyMessage;
245 if (returnData != null)
246 {
247 if (returnData instanceof String && muleContext.getExpressionManager().isExpression(returnData.toString()))
248 {
249 replyMessage = muleContext.getExpressionManager().parse(returnData.toString(), message);
250 }
251 else
252 {
253 replyMessage = returnData;
254 }
255 }
256 else
257 {
258 if (appendString != null)
259 {
260 replyMessage = append(data.toString(), message);
261 }
262 else
263 {
264 replyMessage = data;
265 }
266 }
267
268 if (isEnableNotifications())
269 {
270 muleContext.fireNotification(
271 new FunctionalTestNotification(context, replyMessage, FunctionalTestNotification.EVENT_RECEIVED));
272 }
273
274
275 if (waitTime > 0)
276 {
277 try
278 {
279 Thread.sleep(waitTime);
280 }
281 catch (InterruptedException e)
282 {
283 logger.info("FunctionalTestComponent waitTime was interrupted");
284 }
285 }
286 return replyMessage;
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 public EventCallback getEventCallback()
304 {
305 return eventCallback;
306 }
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 public void setEventCallback(EventCallback eventCallback)
323 {
324 this.eventCallback = eventCallback;
325 }
326
327
328
329
330
331
332
333
334 public Object getReturnData()
335 {
336 return returnData;
337 }
338
339
340
341
342
343
344
345
346 public void setReturnData(Object returnData)
347 {
348 this.returnData = returnData;
349 }
350
351
352
353
354
355
356
357
358
359 public boolean isThrowException()
360 {
361 return throwException;
362 }
363
364
365
366
367
368
369
370
371
372 public void setThrowException(boolean throwException)
373 {
374 this.throwException = throwException;
375 }
376
377 public boolean isEnableMessageHistory()
378 {
379 return enableMessageHistory;
380 }
381
382 public void setEnableMessageHistory(boolean enableMessageHistory)
383 {
384 this.enableMessageHistory = enableMessageHistory;
385 }
386
387
388
389
390
391 public int getReceivedMessagesCount()
392 {
393 if (messageHistory != null)
394 {
395 return messageHistory.size();
396 }
397 else
398 {
399 return NumberUtils.INTEGER_MINUS_ONE.intValue();
400 }
401 }
402
403
404
405
406
407
408 public Object getReceivedMessage(int number)
409 {
410 Object message = null;
411 if (messageHistory != null)
412 {
413 if (number <= messageHistory.size())
414 {
415 message = messageHistory.get(number - 1);
416 }
417 }
418 return message;
419 }
420
421
422
423
424 public Object getLastReceivedMessage()
425 {
426 if (messageHistory != null)
427 {
428 return messageHistory.get(messageHistory.size() - 1);
429 }
430 else
431 {
432 return null;
433 }
434 }
435
436 public String getAppendString()
437 {
438 return appendString;
439 }
440
441 public void setAppendString(String appendString)
442 {
443 this.appendString = appendString;
444 }
445
446 public boolean isEnableNotifications()
447 {
448 return enableNotifications;
449 }
450
451 public void setEnableNotifications(boolean enableNotifications)
452 {
453 this.enableNotifications = enableNotifications;
454 }
455
456 public Class<? extends Throwable> getExceptionToThrow()
457 {
458 return exceptionToThrow;
459 }
460
461 public void setExceptionToThrow(Class<? extends Throwable> exceptionToThrow)
462 {
463 this.exceptionToThrow = exceptionToThrow;
464 }
465
466 public long getWaitTime()
467 {
468 return waitTime;
469 }
470
471 public void setWaitTime(long waitTime)
472 {
473 this.waitTime = waitTime;
474 }
475
476 public boolean isDoInboundTransform()
477 {
478 return doInboundTransform;
479 }
480
481 public void setDoInboundTransform(boolean doInboundTransform)
482 {
483 this.doInboundTransform = doInboundTransform;
484 }
485
486 public boolean isLogMessageDetails()
487 {
488 return logMessageDetails;
489 }
490
491 public void setLogMessageDetails(boolean logMessageDetails)
492 {
493 this.logMessageDetails = logMessageDetails;
494 }
495
496 public void setId(String id)
497 {
498 this.id = id;
499 }
500
501 public static void addLifecycleCallback(LifecycleCallback callback)
502 {
503 lifecycleCallbacks.add(callback);
504 }
505
506 public static void removeLifecycleCallback(LifecycleCallback callback)
507 {
508 lifecycleCallbacks.remove(callback);
509 }
510
511 public interface LifecycleCallback
512 {
513 void onTransition(String name, String newPhase);
514 }
515 }