1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.cxf;
12
13 import org.mule.RequestContext;
14 import org.mule.api.DefaultMuleException;
15 import org.mule.api.ExceptionPayload;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleException;
18 import org.mule.api.MuleMessage;
19 import org.mule.api.config.MuleProperties;
20 import org.mule.api.endpoint.EndpointNotFoundException;
21 import org.mule.api.endpoint.EndpointURI;
22 import org.mule.api.lifecycle.InitialisationException;
23 import org.mule.api.lifecycle.Lifecycle;
24 import org.mule.api.transformer.TransformerException;
25 import org.mule.api.transport.OutputHandler;
26 import org.mule.config.i18n.MessageFactory;
27 import org.mule.message.DefaultExceptionPayload;
28 import org.mule.module.cxf.support.DelegatingOutputStream;
29 import org.mule.module.xml.stax.StaxSource;
30 import org.mule.processor.AbstractInterceptingMessageProcessor;
31 import org.mule.transformer.types.DataTypeFactory;
32 import org.mule.transport.http.HttpConnector;
33 import org.mule.transport.http.HttpConstants;
34 import org.mule.util.StringUtils;
35
36 import java.io.ByteArrayInputStream;
37 import java.io.ByteArrayOutputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.OutputStream;
41 import java.io.Reader;
42
43 import javax.xml.stream.XMLStreamReader;
44 import javax.xml.transform.Source;
45 import javax.xml.transform.dom.DOMSource;
46
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.apache.cxf.Bus;
50 import org.apache.cxf.endpoint.Server;
51 import org.apache.cxf.message.ExchangeImpl;
52 import org.apache.cxf.message.Message;
53 import org.apache.cxf.message.MessageImpl;
54 import org.apache.cxf.service.model.EndpointInfo;
55 import org.apache.cxf.staxutils.StaxUtils;
56 import org.apache.cxf.transport.local.LocalConduit;
57 import org.apache.cxf.transports.http.QueryHandler;
58 import org.apache.cxf.transports.http.QueryHandlerRegistry;
59 import org.apache.cxf.wsdl.http.AddressType;
60 import org.w3c.dom.Document;
61 import org.w3c.dom.Node;
62
63
64
65
66
67
68
69 public class CxfInboundMessageProcessor extends AbstractInterceptingMessageProcessor implements Lifecycle
70 {
71
72
73
74 protected transient Log logger = LogFactory.getLog(getClass());
75
76 protected Bus bus;
77
78
79 protected String transportClass;
80
81 protected Server server;
82
83 private boolean proxy;
84
85 public void initialise() throws InitialisationException
86 {
87 if (bus == null)
88 {
89 throw new InitialisationException(
90 MessageFactory.createStaticMessage("No CXF bus instance, this component has not been initialized properly."),
91 this);
92 }
93
94 if (server == null)
95 {
96 throw new InitialisationException(
97 MessageFactory.createStaticMessage("No CXF Server instance, this component has not been initialized properly."),
98 this);
99 }
100 }
101
102 public void stop() throws MuleException
103 {
104 if (server != null)
105 {
106 server.stop();
107 }
108 }
109
110 public void start() throws MuleException
111 {
112
113 server.start();
114 }
115
116 public void dispose()
117 {
118 }
119
120 public MuleEvent process(MuleEvent event) throws MuleException
121 {
122
123 String requestPath = parseHttpRequestProperty(event.getMessage().getInboundProperty(
124 HttpConnector.HTTP_REQUEST_PROPERTY, StringUtils.EMPTY));
125 try
126 {
127 if (requestPath.indexOf('?') > -1)
128 {
129 return generateWSDLOrXSD(event, requestPath);
130 }
131 else
132 {
133 return sendToDestination(event);
134 }
135 }
136 catch (IOException e)
137 {
138 throw new DefaultMuleException(e);
139 }
140 }
141
142 private String parseHttpRequestProperty(String request)
143 {
144 String uriBase = "";
145
146 if (!(request.contains("?wsdl")) && (!(request.contains("?xsd"))))
147 {
148 int qIdx = request.indexOf('?');
149 if (qIdx > -1)
150 {
151 uriBase = request.substring(0, qIdx);
152 }
153 }
154 else
155 {
156 uriBase = request;
157 }
158
159 return uriBase;
160 }
161
162 protected MuleEvent generateWSDLOrXSD(MuleEvent event, String req)
163 throws EndpointNotFoundException, IOException
164 {
165
166 String ctxUri = event.getMessage().getInboundProperty(HttpConnector.HTTP_CONTEXT_PATH_PROPERTY);
167 String wsdlUri = getWsdlUri(event, req);
168 String serviceUri = wsdlUri.substring(0, wsdlUri.indexOf('?'));
169
170 EndpointInfo ei = getServer().getEndpoint().getEndpointInfo();
171
172 if (serviceUri != null)
173 {
174 ei.setAddress(serviceUri);
175
176 if (ei.getExtensor(AddressType.class) != null)
177 {
178 ei.getExtensor(AddressType.class).setLocation(serviceUri);
179 }
180 }
181
182 ByteArrayOutputStream out = new ByteArrayOutputStream();
183 String ct = null;
184
185 for (QueryHandler qh : bus.getExtension(QueryHandlerRegistry.class).getHandlers())
186 {
187 if (qh.isRecognizedQuery(wsdlUri, ctxUri, ei))
188 {
189 ct = qh.getResponseContentType(wsdlUri, ctxUri);
190 qh.writeResponse(wsdlUri, ctxUri, ei, out);
191 out.flush();
192 }
193 }
194
195 String msg;
196 if (ct == null)
197 {
198 ct = "text/plain";
199 msg = "No query handler found for URL.";
200 }
201 else
202 {
203 msg = out.toString();
204 }
205
206 event.getMessage().setPayload(msg);
207 event.getMessage().setProperty(HttpConstants.HEADER_CONTENT_TYPE, ct);
208 return event;
209 }
210
211 private String getWsdlUri(MuleEvent event, String reqPath)
212 {
213 EndpointURI epUri = event.getEndpoint().getEndpointURI();
214 String host = event.getMessage().getInboundProperty("Host", epUri.getHost());
215 String ctx = event.getMessage().getInboundProperty(HttpConnector.HTTP_REQUEST_PROPERTY);
216 return epUri.getScheme() + "://" + host + ctx;
217 }
218
219 protected MuleEvent sendToDestination(MuleEvent event) throws MuleException, IOException
220 {
221 try
222 {
223 final MessageImpl m = new MessageImpl();
224 final MuleMessage muleReqMsg = event.getMessage();
225 String method = muleReqMsg.getInboundProperty(HttpConnector.HTTP_METHOD_PROPERTY);
226
227 String ct = muleReqMsg.getInboundProperty(HttpConstants.HEADER_CONTENT_TYPE);
228 if (ct != null)
229 {
230 m.put(Message.CONTENT_TYPE, ct);
231 }
232
233 String path = muleReqMsg.getInboundProperty(HttpConnector.HTTP_REQUEST_PATH_PROPERTY);
234 if (path == null)
235 {
236 path = "";
237 }
238
239 if (method != null)
240 {
241 m.put(Message.HTTP_REQUEST_METHOD, method);
242 m.put(Message.PATH_INFO, path);
243 Object basePath = muleReqMsg.getInboundProperty(HttpConnector.HTTP_CONTEXT_PATH_PROPERTY);
244 m.put(Message.BASE_PATH, basePath);
245
246 method = method.toUpperCase();
247 }
248
249 if (!"GET".equals(method))
250 {
251 Object payload = event.getMessage().getPayload();
252
253 setPayload(event, m, payload);
254 }
255
256
257 String soapAction = getSoapAction(event.getMessage());
258 m.put(org.mule.module.cxf.SoapConstants.SOAP_ACTION_PROPERTY_CAPS, soapAction);
259
260 org.apache.cxf.transport.Destination d = server.getDestination();
261
262
263 m.put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
264 m.put(MuleProperties.MULE_EVENT_PROPERTY, RequestContext.getEvent());
265 m.setDestination(d);
266
267 ExchangeImpl exchange = new ExchangeImpl();
268 exchange.setInMessage(m);
269 m.put(CxfConstants.MULE_EVENT, event);
270
271
272
273 exchange.put(CxfConstants.MULE_EVENT, event);
274
275
276
277 d.getMessageObserver().onMessage(m);
278
279
280 MuleEvent responseEvent = (MuleEvent) exchange.get(CxfConstants.MULE_EVENT);
281
282
283
284 if (responseEvent == null || !event.getEndpoint().getExchangePattern().hasResponse())
285 {
286 return null;
287 }
288
289 MuleMessage muleResMsg = responseEvent.getMessage();
290 muleResMsg.setPayload(getRessponseOutputHandler(m));
291
292
293 Message faultMsg = m.getExchange().getOutFaultMessage();
294 if (faultMsg != null)
295 {
296 Exception ex = faultMsg.getContent(Exception.class);
297 if (ex != null)
298 {
299 ExceptionPayload exceptionPayload = new DefaultExceptionPayload(new Exception(""));
300 event.getMessage().setExceptionPayload(exceptionPayload);
301 muleResMsg.setOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY, 500);
302 }
303 }
304
305 return responseEvent;
306 }
307 catch (MuleException e)
308 {
309 logger.warn("Could not dispatch message to CXF!", e);
310 throw e;
311 }
312 }
313
314 @Override
315 public MuleEvent processNext(MuleEvent event) throws MuleException
316 {
317 return next.process(event);
318 }
319
320 protected OutputHandler getRessponseOutputHandler(final MessageImpl m)
321 {
322 OutputHandler outputHandler = new OutputHandler()
323 {
324 public void write(MuleEvent event, OutputStream out) throws IOException
325 {
326 Message outFaultMessage = m.getExchange().getOutFaultMessage();
327 Message outMessage = m.getExchange().getOutMessage();
328
329 Message contentMsg = null;
330 if (outFaultMessage != null && outFaultMessage.getContent(OutputStream.class) != null)
331 {
332 contentMsg = outFaultMessage;
333 }
334 else if (outMessage != null)
335 {
336 contentMsg = outMessage;
337 }
338
339 if (contentMsg == null)
340 {
341 return;
342 }
343
344 DelegatingOutputStream delegate = contentMsg.getContent(DelegatingOutputStream.class);
345 out.write(((ByteArrayOutputStream) delegate.getOutputStream()).toByteArray());
346 delegate.setOutputStream(out);
347
348 out.flush();
349
350 contentMsg.getInterceptorChain().resume();
351 }
352
353 };
354 return outputHandler;
355 }
356
357 private void setPayload(MuleEvent ctx, final MessageImpl m, Object payload) throws TransformerException
358 {
359 if (payload instanceof InputStream)
360 {
361 m.put(Message.ENCODING, ctx.getEncoding());
362 m.setContent(InputStream.class, payload);
363 }
364 else if (payload instanceof Reader)
365 {
366 m.setContent(XMLStreamReader.class, StaxUtils.createXMLStreamReader((Reader) payload));
367 }
368 else if (payload instanceof byte[])
369 {
370 m.setContent(InputStream.class, new ByteArrayInputStream((byte[]) payload));
371 }
372 else if (payload instanceof StaxSource)
373 {
374 m.setContent(XMLStreamReader.class, ((StaxSource) payload).getXMLStreamReader());
375 }
376 else if (payload instanceof Source)
377 {
378 m.setContent(XMLStreamReader.class, StaxUtils.createXMLStreamReader((Source) payload));
379 }
380 else if (payload instanceof XMLStreamReader)
381 {
382 m.setContent(XMLStreamReader.class, payload);
383 }
384 else if (payload instanceof Document)
385 {
386 DOMSource source = new DOMSource((Node) payload);
387 m.setContent(XMLStreamReader.class, StaxUtils.createXMLStreamReader(source));
388 }
389 else
390 {
391 InputStream is = (InputStream) ctx.transformMessage(DataTypeFactory.create(InputStream.class));
392 m.put(Message.ENCODING, ctx.getEncoding());
393 m.setContent(InputStream.class, is);
394 }
395 }
396
397
398
399
400
401
402
403
404 protected InputStream getMessageStream(MuleEvent context) throws MuleException
405 {
406 InputStream is;
407 Object eventMsgPayload = context.getMessage().getPayload();
408
409 if (eventMsgPayload instanceof InputStream)
410 {
411 is = (InputStream) eventMsgPayload;
412 }
413 else
414 {
415 is = (InputStream) context.transformMessage(DataTypeFactory.create(InputStream.class));
416 }
417 return is;
418 }
419
420 protected String getSoapAction(MuleMessage message)
421 {
422 String action = message.getInboundProperty(SoapConstants.SOAP_ACTION_PROPERTY);
423
424 if (action != null && action.startsWith("\"") && action.endsWith("\"") && action.length() >= 2)
425 {
426 action = action.substring(1, action.length() - 1);
427 }
428
429 return action;
430 }
431
432 public Bus getBus()
433 {
434 return bus;
435 }
436
437 public void setBus(Bus bus)
438 {
439 this.bus = bus;
440 }
441
442 public Server getServer()
443 {
444 return server;
445 }
446
447 public void setServer(Server server)
448 {
449 this.server = server;
450 }
451
452 public void setProxy(boolean proxy)
453 {
454 this.proxy = proxy;
455 }
456
457 public boolean isProxy()
458 {
459 return proxy;
460 }
461 }