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