View Javadoc

1   /*
2    * $Id: NoTransformFunctionalTestComponent.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.http.issues;
12  
13  import org.mule.RequestContext;
14  import org.mule.api.DefaultMuleException;
15  import org.mule.api.MuleEventContext;
16  import org.mule.api.lifecycle.Callable;
17  import org.mule.config.i18n.MessageFactory;
18  import org.mule.tck.functional.EventCallback;
19  import org.mule.tck.functional.FunctionalTestNotification;
20  import org.mule.util.StringMessageUtils;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  /**
26   * <code>FunctionalTestComponent</code> is a service that can be used by
27   * functional tests. This service accepts an EventCallback that can be used to
28   * assert the state of the current event.
29   * <p/>
30   * Also, this service fires {@link org.mule.tck.functional.FunctionalTestNotification} via Mule for every message received.
31   * Tests can register with Mule to receive these events by implementing
32   * {@link org.mule.tck.functional.FunctionalTestNotificationListener}.
33   *
34   * @see org.mule.tck.functional.EventCallback
35   * @see org.mule.tck.functional.FunctionalTestNotification
36   * @see org.mule.tck.functional.FunctionalTestNotificationListener
37   */
38  
39  public class NoTransformFunctionalTestComponent implements Callable
40  {
41      protected transient Log logger = LogFactory.getLog(getClass());
42  
43      public static final int STREAM_SAMPLE_SIZE = 4;
44      public static final int STREAM_BUFFER_SIZE = 4096;
45      private EventCallback eventCallback;
46      private Object returnMessage = null;
47      private boolean appendComponentName = false;
48      private boolean throwException = false;
49  
50      /**
51       * {@inheritDoc}
52       */
53      public Object onCall(MuleEventContext context) throws Exception
54      {
55          String contents = context.getMessageAsString();
56          String msg = StringMessageUtils.getBoilerPlate("Message Received in service: "
57                  + context.getFlowConstruct().getName() + ". Content is: "
58                  + StringMessageUtils.truncate(contents, 100, true), '*', 80);
59  
60          logger.info(msg);
61  
62          if (eventCallback != null)
63          {
64              eventCallback.eventReceived(context, this);
65          }
66  
67          Object replyMessage;
68          if (returnMessage != null)
69          {
70              replyMessage = returnMessage;
71          }
72          else
73          {
74              replyMessage = received(contents) + (appendComponentName ? " " + context.getFlowConstruct().getName() : "");
75          }
76  
77          context.getMuleContext().fireNotification(
78                  new FunctionalTestNotification(context, replyMessage, FunctionalTestNotification.EVENT_RECEIVED));
79  
80          if (throwException)
81          {
82              throw new DefaultMuleException(MessageFactory.createStaticMessage("Functional Test Service Exception"));
83          }
84  
85          return replyMessage;
86      }
87  
88      /**
89       * Append " Received" to contents.  Exposed as static method so tests can call to
90       * construct string for comparison.
91       *
92       * @param contents
93       * @return Extended message
94       */
95      public static String received(String contents)
96      {
97          return contents + " Received";
98      }
99  
100     /**
101      * @param data the event data received
102      * @return the processed message
103      * @throws Exception
104      *
105      * @deprecated Not sure why we have this duplicate method here. Need to investigate...
106      */
107     public Object onReceive(Object data) throws Exception
108     {
109         MuleEventContext context = RequestContext.getEventContext();
110 
111         String contents = data.toString();
112         String msg = StringMessageUtils.getBoilerPlate("Message Received in service: "
113                 + context.getFlowConstruct().getName() + ". Content is: "
114                 + StringMessageUtils.truncate(contents, 100, true), '*', 80);
115 
116         logger.info(msg);
117 
118         if (eventCallback != null)
119         {
120             eventCallback.eventReceived(context, this);
121         }
122 
123         Object replyMessage;
124         if (returnMessage != null)
125         {
126             replyMessage = returnMessage;
127         }
128         else
129         {
130             replyMessage = contents + " Received";
131         }
132 
133         context.getMuleContext().fireNotification(
134                 new FunctionalTestNotification(context, replyMessage, FunctionalTestNotification.EVENT_RECEIVED));
135 
136         if (throwException)
137         {
138             if(returnMessage!=null && returnMessage instanceof Exception)
139             {
140                 throw (Exception)returnMessage;
141             }
142             else
143             {
144                 throw new DefaultMuleException(MessageFactory.createStaticMessage("Functional Test Service Exception"));
145             }
146         }
147 
148         return replyMessage;
149     }
150 
151     /**
152      * An event callback is called when a message is received by the service.
153      * An MuleEvent callback isn't strictly required but it is usfal for performing assertions
154      * on the current message being received.
155      * Note that the FunctionalTestComponent should be made a singleton
156      * when using MuleEvent callbacks
157      * <p/>
158      * Another option is to register a {@link org.mule.tck.functional.FunctionalTestNotificationListener} with Mule and this
159      * will deleiver a {@link org.mule.tck.functional.FunctionalTestNotification} for every message received by this service
160      *
161      * @return the callback to call when a message is received
162      * @see org.mule.tck.functional.FunctionalTestNotification
163      * @see org.mule.tck.functional.FunctionalTestNotificationListener
164      */
165     public EventCallback getEventCallback()
166     {
167         return eventCallback;
168     }
169 
170     /**
171      * An event callback is called when a message is received by the service.
172      * An MuleEvent callback isn't strictly required but it is usfal for performing assertions
173      * on the current message being received.
174      * Note that the FunctionalTestComponent should be made a singleton
175      * when using MuleEvent callbacks
176      * <p/>
177      * Another option is to register a {@link org.mule.tck.functional.FunctionalTestNotificationListener} with Mule and this
178      * will deleiver a {@link org.mule.tck.functional.FunctionalTestNotification} for every message received by this service
179      *
180      * @param eventCallback the callback to call when a message is received
181      * @see org.mule.tck.functional.FunctionalTestNotification
182      * @see org.mule.tck.functional.FunctionalTestNotificationListener
183      */
184     public void setEventCallback(EventCallback eventCallback)
185     {
186         this.eventCallback = eventCallback;
187     }
188 
189     /**
190      * Often you will may want to return a fixed message payload to simulate and external system call.
191      * This can be done using the 'returnMessage' property. Note that you can return complex objects by
192      * using the <container-property> element in the Xml configuration.
193      *
194      * @return the message payload to always return from this service instance
195      */
196     public Object getReturnMessage()
197     {
198         return returnMessage;
199     }
200 
201     /**
202      * Often you will may want to return a fixed message payload to simulate and external system call.
203      * This can be done using the 'returnMessage' property. Note that you can return complex objects by
204      * using the <container-property> element in the Xml configuration.
205      *
206      * @param returnMessage the message payload to always return from this service instance
207      */
208     public void setReturnMessage(Object returnMessage)
209     {
210         this.returnMessage = returnMessage;
211     }
212 
213     /**
214      * Sometimes you will want the service to always throw an exception, if this is the case you can
215      * set the 'throwException' property to true.
216      *
217      * @return throwException true if an exception should always be thrown from this instance.
218      *         If the {@link #returnMessage} property is set and is of type
219      *         java.lang.Exception, that exception will be thrown.
220      */
221     public boolean isThrowException()
222     {
223         return throwException;
224     }
225 
226     /**
227      * Sometimes you will want the service to always throw an exception, if this is the case you can
228      * set the 'throwException' property to true.
229      *
230      * @param throwException true if an exception should always be thrown from this instance.
231      *                       If the {@link #returnMessage} property is set and is of type
232      *                       java.lang.Exception, that exception will be thrown.
233      */
234     public void setThrowException(boolean throwException)
235     {
236         this.throwException = throwException;
237     }
238 
239     /**
240      * This will cause the service to append the compoent name to the end of the message
241      * returned from this service. This only works when processing String messages.
242      * This feature is useful when processing multiple messages using a pool of FunctionalTestComponents
243      * to determine who processed the resulting message
244      *
245      * @return true if the service name will be appended to the return message
246      */
247     public boolean isAppendComponentName()
248     {
249         return appendComponentName;
250     }
251 
252     /**
253      * This will cause the service to append the compoent name to the end of the message
254      * returned from this service. This only works when processing String messages.
255      * This feature is useful when processing multiple messages using a pool of FunctionalTestComponents
256      * to determine who processed the resulting message
257      *
258      * @param appendComponentName true if the service name will be appended to the return message
259      */
260     public void setAppendComponentName(boolean appendComponentName)
261     {
262         this.appendComponentName = appendComponentName;
263     }
264 
265 }