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 }