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