1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.MessageExchangePattern;
15 import org.mule.OptimizedRequestContext;
16 import org.mule.ResponseOutputStream;
17 import org.mule.api.MuleEvent;
18 import org.mule.api.MuleException;
19 import org.mule.api.MuleMessage;
20 import org.mule.api.MuleSession;
21 import org.mule.api.config.MuleProperties;
22 import org.mule.api.construct.FlowConstruct;
23 import org.mule.api.context.WorkManager;
24 import org.mule.api.endpoint.EndpointURI;
25 import org.mule.api.endpoint.InboundEndpoint;
26 import org.mule.api.lifecycle.CreateException;
27 import org.mule.api.lifecycle.InitialisationException;
28 import org.mule.api.processor.MessageProcessor;
29 import org.mule.api.routing.filter.FilterUnacceptedException;
30 import org.mule.api.transaction.Transaction;
31 import org.mule.api.transformer.Transformer;
32 import org.mule.api.transport.Connector;
33 import org.mule.api.transport.MessageReceiver;
34 import org.mule.api.transport.PropertyScope;
35 import org.mule.api.transport.ReplyToHandler;
36 import org.mule.context.notification.EndpointMessageNotification;
37 import org.mule.session.DefaultMuleSession;
38 import org.mule.session.LegacySessionHandler;
39 import org.mule.transaction.TransactionCoordination;
40 import org.mule.util.ClassUtils;
41 import org.mule.util.ObjectUtils;
42
43 import java.io.OutputStream;
44 import java.util.List;
45
46 import org.apache.commons.lang.SerializationException;
47
48
49
50
51
52
53 public abstract class AbstractMessageReceiver extends AbstractTransportMessageHandler implements MessageReceiver
54 {
55
56
57
58 protected FlowConstruct flowConstruct;
59
60
61
62
63
64
65 protected MessageProcessor listener;
66
67
68
69
70
71 protected String receiverKey = null;
72
73
74
75
76
77
78
79 private EndpointURI endpointUri;
80
81 protected List<Transformer> defaultInboundTransformers;
82 protected List<Transformer> defaultResponseTransformers;
83
84 protected ReplyToHandler replyToHandler;
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public AbstractMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
99 throws CreateException
100 {
101 super(endpoint);
102
103 if (flowConstruct == null)
104 {
105 throw new IllegalArgumentException("FlowConstruct cannot be null");
106 }
107 this.flowConstruct = flowConstruct;
108 }
109
110 @Override
111 protected ConnectableLifecycleManager createLifecycleManager()
112 {
113 return new ConnectableLifecycleManager<MessageReceiver>(getReceiverKey(), this);
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 @Override
130 public final void initialise() throws InitialisationException
131 {
132 endpointUri = endpoint.getEndpointURI();
133
134 defaultInboundTransformers = connector.getDefaultInboundTransformers(endpoint);
135 defaultResponseTransformers = connector.getDefaultResponseTransformers(endpoint);
136
137 replyToHandler = getReplyToHandler();
138
139 super.initialise();
140 }
141
142 public FlowConstruct getFlowConstruct()
143 {
144 return flowConstruct;
145 }
146
147 public final MuleEvent routeMessage(MuleMessage message) throws MuleException
148 {
149 Transaction tx = TransactionCoordination.getInstance().getTransaction();
150 return routeMessage(message, tx, null);
151 }
152
153 public final MuleEvent routeMessage(MuleMessage message, Transaction trans)
154 throws MuleException
155 {
156 return routeMessage(message, trans, null);
157 }
158
159 public final MuleEvent routeMessage(MuleMessage message,
160 Transaction trans,
161 OutputStream outputStream) throws MuleException
162 {
163 return routeMessage(message, new DefaultMuleSession(connector.getMuleContext()), trans,
164 outputStream);
165 }
166
167 public final MuleEvent routeMessage(MuleMessage message,
168 MuleSession session,
169 Transaction trans,
170 OutputStream outputStream) throws MuleException
171 {
172
173 final Object o = message.getInboundProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY);
174 if (ObjectUtils.getBoolean(o, false) && !endpoint.getExchangePattern().hasResponse())
175 {
176 logger.warn("MuleClient.send() was used but inbound endpoint "
177 + endpoint.getEndpointURI().getUri().toString()
178 + " is not 'request-response'. No response will be returned.");
179 }
180
181 message.removeProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, PropertyScope.INBOUND);
182 String rootId = message.getInboundProperty(MuleProperties.MULE_ROOT_MESSAGE_ID_PROPERTY);
183 if (rootId != null)
184 {
185 message.setMessageRootId(rootId);
186 message.removeProperty(MuleProperties.MULE_ROOT_MESSAGE_ID_PROPERTY, PropertyScope.INBOUND);
187 }
188 MuleEvent muleEvent = createMuleEvent(message, outputStream);
189 muleEvent = OptimizedRequestContext.unsafeSetEvent(muleEvent);
190
191 if (!endpoint.isDisableTransportTransformer())
192 {
193 applyInboundTransformers(muleEvent);
194 }
195 MuleEvent resultEvent = listener.process(muleEvent);
196 if (resultEvent != null && resultEvent.getMessage() != null
197 && resultEvent.getMessage().getExceptionPayload() != null
198 && resultEvent.getMessage().getExceptionPayload().getException() instanceof FilterUnacceptedException)
199 {
200 handleUnacceptedFilter(muleEvent.getMessage());
201 return muleEvent;
202 }
203
204 if (resultEvent != null)
205 {
206
207 MuleSession resultSession = new DefaultMuleSession(resultEvent.getSession(), resultEvent.getMuleContext());
208 resultSession.setSecurityContext(null);
209 connector.getSessionHandler().storeSessionInfoToMessage(resultSession, resultEvent.getMessage());
210 }
211
212 if (endpoint.getExchangePattern()== MessageExchangePattern.REQUEST_RESPONSE && resultEvent != null && resultEvent.getMessage() != null && !endpoint.isDisableTransportTransformer())
213 {
214 applyResponseTransformers(resultEvent);
215 }
216
217 if (connector.isEnableMessageEvents() && endpoint.getExchangePattern().hasResponse() && resultEvent != null)
218 {
219 connector.fireNotification(new EndpointMessageNotification(
220 resultEvent.getMessage(), endpoint, resultEvent
221 .getFlowConstruct(),
222 EndpointMessageNotification.MESSAGE_RESPONSE));
223 }
224
225 return resultEvent;
226 }
227
228 protected void applyInboundTransformers(MuleEvent event) throws MuleException
229 {
230 event.getMessage().applyTransformers(event, defaultInboundTransformers);
231 }
232
233 protected void applyResponseTransformers(MuleEvent event) throws MuleException
234 {
235 event.getMessage().applyTransformers(event, defaultResponseTransformers);
236 }
237
238 protected MuleMessage handleUnacceptedFilter(MuleMessage message)
239 {
240 if (logger.isDebugEnabled())
241 {
242 String messageId;
243 messageId = message.getUniqueId();
244 logger.debug("Message " + messageId + " failed to pass filter on endpoint: " + endpoint
245 + ". Message is being ignored");
246 }
247 return message;
248 }
249
250 protected MuleEvent createMuleEvent(MuleMessage message, OutputStream outputStream)
251 throws MuleException
252 {
253 ResponseOutputStream ros = null;
254 if (outputStream != null)
255 {
256 if (outputStream instanceof ResponseOutputStream)
257 {
258 ros = (ResponseOutputStream) outputStream;
259 }
260 else
261 {
262 ros = new ResponseOutputStream(outputStream);
263 }
264 }
265 MuleSession session;
266 try
267 {
268 session = connector.getSessionHandler().retrieveSessionInfoFromMessage(message);
269 }
270 catch (SerializationException se)
271 {
272 try
273 {
274
275 session = new LegacySessionHandler().retrieveSessionInfoFromMessage(message);
276 }
277 catch (Exception e)
278 {
279
280 throw se;
281 }
282 }
283 if (session != null)
284 {
285 session.setFlowConstruct(flowConstruct);
286 }
287 else
288 {
289 session = new DefaultMuleSession(flowConstruct, connector.getMuleContext());
290 }
291 if (message.getReplyTo() != null)
292 {
293 return new DefaultMuleEvent(message, getEndpoint(),session, replyToHandler, ros);
294
295 }
296 else
297 {
298 return new DefaultMuleEvent(message, getEndpoint(), session, null, ros);
299 }
300 }
301
302 public EndpointURI getEndpointURI()
303 {
304 return endpointUri;
305 }
306
307 @Override
308 public String getConnectionDescription()
309 {
310 return endpoint.getEndpointURI().toString();
311 }
312
313 protected String getConnectEventId()
314 {
315 return connector.getName() + ".receiver (" + endpoint.getEndpointURI() + ")";
316 }
317
318
319 public void setReceiverKey(String receiverKey)
320 {
321 this.receiverKey = receiverKey;
322 }
323
324 public String getReceiverKey()
325 {
326 return receiverKey;
327 }
328
329 @Override
330 public InboundEndpoint getEndpoint()
331 {
332 return (InboundEndpoint) super.getEndpoint();
333 }
334
335
336 public void setEndpoint(InboundEndpoint endpoint)
337 {
338 super.setEndpoint(endpoint);
339 }
340
341 @Override
342 protected WorkManager getWorkManager()
343 {
344 try
345 {
346 return connector.getReceiverWorkManager();
347 }
348 catch (MuleException e)
349 {
350 logger.error(e);
351 return null;
352 }
353 }
354
355 @Override
356 public String toString()
357 {
358 final StringBuffer sb = new StringBuffer(80);
359 sb.append(ClassUtils.getSimpleName(this.getClass()));
360 sb.append("{this=").append(Integer.toHexString(System.identityHashCode(this)));
361 sb.append(", receiverKey=").append(receiverKey);
362 sb.append(", endpoint=").append(endpoint.getEndpointURI());
363 sb.append('}');
364 return sb.toString();
365 }
366
367 public void setListener(MessageProcessor processor)
368 {
369 this.listener = processor;
370 }
371
372 @Override
373 protected void doDispose()
374 {
375 this.listener = null;
376 this.flowConstruct = null;
377 super.doDispose();
378 }
379
380 protected ReplyToHandler getReplyToHandler()
381 {
382 return ((AbstractConnector) endpoint.getConnector()).getReplyToHandler(endpoint);
383 }
384 }