1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
package org.mule.transport.http.transformers; |
8 | |
|
9 | |
import org.mule.RequestContext; |
10 | |
import org.mule.api.MuleEvent; |
11 | |
import org.mule.api.MuleMessage; |
12 | |
import org.mule.api.config.MuleProperties; |
13 | |
import org.mule.api.transformer.TransformerException; |
14 | |
import org.mule.api.transport.OutputHandler; |
15 | |
import org.mule.api.transport.PropertyScope; |
16 | |
import org.mule.message.ds.StringDataSource; |
17 | |
import org.mule.transformer.AbstractMessageTransformer; |
18 | |
import org.mule.transformer.types.DataTypeFactory; |
19 | |
import org.mule.transport.NullPayload; |
20 | |
import org.mule.transport.http.HttpConnector; |
21 | |
import org.mule.transport.http.HttpConstants; |
22 | |
import org.mule.transport.http.PatchMethod; |
23 | |
import org.mule.transport.http.StreamPayloadRequestEntity; |
24 | |
import org.mule.transport.http.i18n.HttpMessages; |
25 | |
import org.mule.util.IOUtils; |
26 | |
import org.mule.util.ObjectUtils; |
27 | |
import org.mule.util.SerializationUtils; |
28 | |
import org.mule.util.StringUtils; |
29 | |
|
30 | |
import java.io.InputStream; |
31 | |
import java.io.Serializable; |
32 | |
import java.io.UnsupportedEncodingException; |
33 | |
import java.net.URI; |
34 | |
import java.net.URISyntaxException; |
35 | |
import java.net.URLEncoder; |
36 | |
import java.util.Iterator; |
37 | |
import java.util.Map; |
38 | |
|
39 | |
import javax.activation.DataHandler; |
40 | |
import javax.activation.FileDataSource; |
41 | |
import javax.activation.URLDataSource; |
42 | |
|
43 | |
import org.apache.commons.httpclient.HttpMethod; |
44 | |
import org.apache.commons.httpclient.HttpVersion; |
45 | |
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; |
46 | |
import org.apache.commons.httpclient.methods.DeleteMethod; |
47 | |
import org.apache.commons.httpclient.methods.EntityEnclosingMethod; |
48 | |
import org.apache.commons.httpclient.methods.GetMethod; |
49 | |
import org.apache.commons.httpclient.methods.HeadMethod; |
50 | |
import org.apache.commons.httpclient.methods.InputStreamRequestEntity; |
51 | |
import org.apache.commons.httpclient.methods.OptionsMethod; |
52 | |
import org.apache.commons.httpclient.methods.PostMethod; |
53 | |
import org.apache.commons.httpclient.methods.PutMethod; |
54 | |
import org.apache.commons.httpclient.methods.StringRequestEntity; |
55 | |
import org.apache.commons.httpclient.methods.TraceMethod; |
56 | |
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource; |
57 | |
import org.apache.commons.httpclient.methods.multipart.FilePart; |
58 | |
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; |
59 | |
import org.apache.commons.httpclient.methods.multipart.Part; |
60 | |
import org.apache.commons.httpclient.methods.multipart.StringPart; |
61 | |
import org.apache.commons.httpclient.params.HttpMethodParams; |
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
public class ObjectToHttpClientMethodRequest extends AbstractMessageTransformer |
68 | |
{ |
69 | |
public ObjectToHttpClientMethodRequest() |
70 | 0 | { |
71 | 0 | setReturnDataType(DataTypeFactory.create(HttpMethod.class)); |
72 | 0 | registerSourceType(DataTypeFactory.MULE_MESSAGE); |
73 | 0 | registerSourceType(DataTypeFactory.BYTE_ARRAY); |
74 | 0 | registerSourceType(DataTypeFactory.STRING); |
75 | 0 | registerSourceType(DataTypeFactory.INPUT_STREAM); |
76 | 0 | registerSourceType(DataTypeFactory.create(OutputHandler.class)); |
77 | 0 | registerSourceType(DataTypeFactory.create(NullPayload.class)); |
78 | 0 | } |
79 | |
|
80 | |
@Override |
81 | |
public Object transformMessage(MuleMessage msg, String outputEncoding) throws TransformerException |
82 | |
{ |
83 | 0 | String method = detectHttpMethod(msg); |
84 | |
try |
85 | |
{ |
86 | |
HttpMethod httpMethod; |
87 | |
|
88 | 0 | if (HttpConstants.METHOD_GET.equals(method)) |
89 | |
{ |
90 | 0 | httpMethod = createGetMethod(msg, outputEncoding); |
91 | |
} |
92 | 0 | else if (HttpConstants.METHOD_POST.equalsIgnoreCase(method)) |
93 | |
{ |
94 | 0 | httpMethod = createPostMethod(msg, outputEncoding); |
95 | |
} |
96 | 0 | else if (HttpConstants.METHOD_PUT.equalsIgnoreCase(method)) |
97 | |
{ |
98 | 0 | httpMethod = createPutMethod(msg, outputEncoding); |
99 | |
} |
100 | 0 | else if (HttpConstants.METHOD_DELETE.equalsIgnoreCase(method)) |
101 | |
{ |
102 | 0 | httpMethod = createDeleteMethod(msg); |
103 | |
} |
104 | 0 | else if (HttpConstants.METHOD_HEAD.equalsIgnoreCase(method)) |
105 | |
{ |
106 | 0 | httpMethod = createHeadMethod(msg); |
107 | |
} |
108 | 0 | else if (HttpConstants.METHOD_OPTIONS.equalsIgnoreCase(method)) |
109 | |
{ |
110 | 0 | httpMethod = createOptionsMethod(msg); |
111 | |
} |
112 | 0 | else if (HttpConstants.METHOD_TRACE.equalsIgnoreCase(method)) |
113 | |
{ |
114 | 0 | httpMethod = createTraceMethod(msg); |
115 | |
} |
116 | 0 | else if (HttpConstants.METHOD_PATCH.equalsIgnoreCase(method)) |
117 | |
{ |
118 | 0 | httpMethod = createPatchMethod(msg); |
119 | |
} |
120 | |
else |
121 | |
{ |
122 | 0 | throw new TransformerException(HttpMessages.unsupportedMethod(method)); |
123 | |
} |
124 | |
|
125 | |
|
126 | 0 | final HttpMethodParams params = (HttpMethodParams) msg.removeProperty( |
127 | |
HttpConnector.HTTP_PARAMS_PROPERTY, PropertyScope.OUTBOUND); |
128 | 0 | if (params != null) |
129 | |
{ |
130 | 0 | httpMethod.setParams(params); |
131 | |
} |
132 | |
else |
133 | |
{ |
134 | |
|
135 | 0 | final String httpVersion = msg.getOutboundProperty(HttpConnector.HTTP_VERSION_PROPERTY, |
136 | |
HttpConstants.HTTP11); |
137 | 0 | if (HttpConstants.HTTP10.equals(httpVersion)) |
138 | |
{ |
139 | 0 | httpMethod.getParams().setVersion(HttpVersion.HTTP_1_0); |
140 | |
} |
141 | |
else |
142 | |
{ |
143 | 0 | httpMethod.getParams().setVersion(HttpVersion.HTTP_1_1); |
144 | |
} |
145 | |
} |
146 | |
|
147 | 0 | setHeaders(httpMethod, msg); |
148 | |
|
149 | 0 | return httpMethod; |
150 | |
} |
151 | 0 | catch (final Exception e) |
152 | |
{ |
153 | 0 | throw new TransformerException(this, e); |
154 | |
} |
155 | |
} |
156 | |
|
157 | |
protected String detectHttpMethod(MuleMessage msg) |
158 | |
{ |
159 | 0 | String method = msg.getOutboundProperty(HttpConnector.HTTP_METHOD_PROPERTY, null); |
160 | 0 | if (method == null) |
161 | |
{ |
162 | 0 | method = msg.getInvocationProperty(HttpConnector.HTTP_METHOD_PROPERTY, HttpConstants.METHOD_POST); |
163 | |
} |
164 | 0 | return method; |
165 | |
} |
166 | |
|
167 | |
protected HttpMethod createGetMethod(MuleMessage msg, String outputEncoding) throws Exception |
168 | |
{ |
169 | 0 | final Object src = msg.getPayload(); |
170 | |
|
171 | |
|
172 | |
|
173 | 0 | final URI uri = getURI(msg); |
174 | |
HttpMethod httpMethod; |
175 | 0 | String query = uri.getRawQuery(); |
176 | |
|
177 | 0 | httpMethod = new GetMethod(uri.toString()); |
178 | 0 | String paramName = msg.getOutboundProperty(HttpConnector.HTTP_GET_BODY_PARAM_PROPERTY, null); |
179 | 0 | if (paramName != null) |
180 | |
{ |
181 | 0 | paramName = URLEncoder.encode(paramName, outputEncoding); |
182 | |
|
183 | |
String paramValue; |
184 | 0 | Boolean encode = msg.getInvocationProperty(HttpConnector.HTTP_ENCODE_PARAMVALUE); |
185 | 0 | if (encode == null) |
186 | |
{ |
187 | 0 | encode = msg.getOutboundProperty(HttpConnector.HTTP_ENCODE_PARAMVALUE, true); |
188 | |
} |
189 | |
|
190 | 0 | if (encode) |
191 | |
{ |
192 | 0 | paramValue = URLEncoder.encode(src.toString(), outputEncoding); |
193 | |
} |
194 | |
else |
195 | |
{ |
196 | 0 | paramValue = src.toString(); |
197 | |
} |
198 | |
|
199 | 0 | if (!(src instanceof NullPayload) && !StringUtils.EMPTY.equals(src)) |
200 | |
{ |
201 | 0 | if (query == null) |
202 | |
{ |
203 | 0 | query = paramName + "=" + paramValue; |
204 | |
} |
205 | |
else |
206 | |
{ |
207 | 0 | query += "&" + paramName + "=" + paramValue; |
208 | |
} |
209 | |
} |
210 | |
} |
211 | |
|
212 | 0 | httpMethod.setQueryString(query); |
213 | 0 | return httpMethod; |
214 | |
} |
215 | |
|
216 | |
protected HttpMethod createPostMethod(MuleMessage msg, String outputEncoding) throws Exception |
217 | |
{ |
218 | 0 | URI uri = getURI(msg); |
219 | 0 | PostMethod postMethod = new PostMethod(uri.toString()); |
220 | |
|
221 | 0 | String bodyParameterName = getBodyParameterName(msg); |
222 | 0 | Object src = msg.getPayload(); |
223 | 0 | if (src instanceof Map) |
224 | |
{ |
225 | 0 | for (Map.Entry<?, ?> entry : ((Map<?, ?>) src).entrySet()) |
226 | |
{ |
227 | 0 | postMethod.addParameter(entry.getKey().toString(), entry.getValue().toString()); |
228 | |
} |
229 | |
} |
230 | 0 | else if (bodyParameterName != null) |
231 | |
{ |
232 | 0 | postMethod.addParameter(bodyParameterName, src.toString()); |
233 | |
|
234 | |
} |
235 | |
else |
236 | |
{ |
237 | 0 | setupEntityMethod(src, outputEncoding, msg, postMethod); |
238 | |
} |
239 | |
|
240 | 0 | setContentType(msg, postMethod); |
241 | |
|
242 | 0 | return postMethod; |
243 | |
} |
244 | |
|
245 | |
protected String getBodyParameterName(MuleMessage message) |
246 | |
{ |
247 | 0 | String bodyParameter = message.getOutboundProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY); |
248 | 0 | if (bodyParameter == null) |
249 | |
{ |
250 | 0 | bodyParameter = message.getInvocationProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY); |
251 | |
} |
252 | 0 | return bodyParameter; |
253 | |
} |
254 | |
|
255 | |
protected HttpMethod createPutMethod(MuleMessage msg, String outputEncoding) throws Exception |
256 | |
{ |
257 | 0 | URI uri = getURI(msg); |
258 | 0 | PutMethod putMethod = new PutMethod(uri.toString()); |
259 | 0 | setContentType(msg, putMethod); |
260 | |
|
261 | 0 | Object payload = msg.getPayload(); |
262 | 0 | setupEntityMethod(payload, outputEncoding, msg, putMethod); |
263 | |
|
264 | 0 | return putMethod; |
265 | |
} |
266 | |
|
267 | |
private void setContentType(MuleMessage msg, HttpMethod putMethod) |
268 | |
{ |
269 | |
|
270 | 0 | String outgoingContentType = msg.getInvocationProperty(HttpConstants.HEADER_CONTENT_TYPE); |
271 | 0 | if (outgoingContentType != null) |
272 | |
{ |
273 | 0 | putMethod.setRequestHeader(HttpConstants.HEADER_CONTENT_TYPE, outgoingContentType); |
274 | |
} |
275 | 0 | } |
276 | |
|
277 | |
protected HttpMethod createDeleteMethod(MuleMessage message) throws Exception |
278 | |
{ |
279 | 0 | URI uri = getURI(message); |
280 | 0 | return new DeleteMethod(uri.toString()); |
281 | |
} |
282 | |
|
283 | |
protected HttpMethod createHeadMethod(MuleMessage message) throws Exception |
284 | |
{ |
285 | 0 | URI uri = getURI(message); |
286 | 0 | return new HeadMethod(uri.toString()); |
287 | |
} |
288 | |
|
289 | |
protected HttpMethod createOptionsMethod(MuleMessage message) throws Exception |
290 | |
{ |
291 | 0 | URI uri = getURI(message); |
292 | 0 | return new OptionsMethod(uri.toString()); |
293 | |
} |
294 | |
|
295 | |
protected HttpMethod createTraceMethod(MuleMessage message) throws Exception |
296 | |
{ |
297 | 0 | URI uri = getURI(message); |
298 | 0 | return new TraceMethod(uri.toString()); |
299 | |
} |
300 | |
|
301 | |
protected HttpMethod createPatchMethod(MuleMessage message) throws Exception |
302 | |
{ |
303 | 0 | URI uri = getURI(message); |
304 | 0 | return new PatchMethod(uri.toString()); |
305 | |
} |
306 | |
|
307 | |
protected URI getURI(MuleMessage message) throws URISyntaxException, TransformerException |
308 | |
{ |
309 | 0 | String endpointAddress = message.getOutboundProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, null); |
310 | 0 | if (endpointAddress == null) |
311 | |
{ |
312 | 0 | throw new TransformerException( |
313 | |
HttpMessages.eventPropertyNotSetCannotProcessRequest(MuleProperties.MULE_ENDPOINT_PROPERTY), |
314 | |
this); |
315 | |
} |
316 | 0 | return new URI(endpointAddress); |
317 | |
} |
318 | |
|
319 | |
protected void setupEntityMethod(Object src, String encoding, MuleMessage msg, |
320 | |
EntityEnclosingMethod postMethod) throws UnsupportedEncodingException, TransformerException |
321 | |
{ |
322 | |
|
323 | |
|
324 | 0 | if (!(msg.getPayload() instanceof NullPayload)) |
325 | |
{ |
326 | 0 | String outboundMimeType = (String) msg.getProperty(HttpConstants.HEADER_CONTENT_TYPE, |
327 | |
PropertyScope.OUTBOUND); |
328 | 0 | if (outboundMimeType == null) |
329 | |
{ |
330 | 0 | outboundMimeType = (getEndpoint() != null ? getEndpoint().getMimeType() : null); |
331 | |
} |
332 | 0 | if (outboundMimeType == null) |
333 | |
{ |
334 | 0 | outboundMimeType = HttpConstants.DEFAULT_CONTENT_TYPE; |
335 | 0 | logger.info("Content-Type not set on outgoing request, defaulting to: " + outboundMimeType); |
336 | |
} |
337 | |
|
338 | 0 | if (encoding != null && !"UTF-8".equals(encoding.toUpperCase()) |
339 | |
&& outboundMimeType.indexOf("charset") == -1) |
340 | |
{ |
341 | 0 | outboundMimeType += "; charset=" + encoding; |
342 | |
} |
343 | |
|
344 | |
|
345 | |
|
346 | 0 | final String httpVersion = msg.getOutboundProperty(HttpConnector.HTTP_VERSION_PROPERTY, |
347 | |
HttpConstants.HTTP11); |
348 | 0 | if (HttpConstants.HTTP10.equals(httpVersion)) |
349 | |
{ |
350 | |
try |
351 | |
{ |
352 | 0 | src = msg.getPayloadAsBytes(); |
353 | |
} |
354 | 0 | catch (final Exception e) |
355 | |
{ |
356 | 0 | throw new TransformerException(this, e); |
357 | 0 | } |
358 | |
} |
359 | |
|
360 | 0 | if (msg.getOutboundAttachmentNames() != null && msg.getOutboundAttachmentNames().size() > 0) |
361 | |
{ |
362 | |
try |
363 | |
{ |
364 | 0 | postMethod.setRequestEntity(createMultiPart(msg, postMethod)); |
365 | 0 | return; |
366 | |
} |
367 | 0 | catch (final Exception e) |
368 | |
{ |
369 | 0 | throw new TransformerException(this, e); |
370 | |
} |
371 | |
} |
372 | 0 | if (src instanceof String) |
373 | |
{ |
374 | 0 | postMethod.setRequestEntity(new StringRequestEntity(src.toString(), outboundMimeType, encoding)); |
375 | 0 | return; |
376 | |
} |
377 | |
|
378 | 0 | if (src instanceof InputStream) |
379 | |
{ |
380 | 0 | postMethod.setRequestEntity(new InputStreamRequestEntity((InputStream) src, outboundMimeType)); |
381 | |
} |
382 | 0 | else if (src instanceof byte[]) |
383 | |
{ |
384 | 0 | postMethod.setRequestEntity(new ByteArrayRequestEntity((byte[]) src, outboundMimeType)); |
385 | |
} |
386 | 0 | else if (src instanceof OutputHandler) |
387 | |
{ |
388 | 0 | final MuleEvent event = RequestContext.getEvent(); |
389 | 0 | postMethod.setRequestEntity(new StreamPayloadRequestEntity((OutputHandler) src, event)); |
390 | 0 | } |
391 | |
else |
392 | |
{ |
393 | 0 | final byte[] buffer = SerializationUtils.serialize((Serializable) src); |
394 | 0 | postMethod.setRequestEntity(new ByteArrayRequestEntity(buffer, outboundMimeType)); |
395 | |
} |
396 | 0 | } |
397 | 0 | else if (msg.getOutboundAttachmentNames() != null && msg.getOutboundAttachmentNames().size() > 0) |
398 | |
{ |
399 | |
try |
400 | |
{ |
401 | 0 | postMethod.setRequestEntity(createMultiPart(msg, postMethod)); |
402 | |
} |
403 | 0 | catch (Exception e) |
404 | |
{ |
405 | 0 | throw new TransformerException(this, e); |
406 | 0 | } |
407 | |
} |
408 | 0 | } |
409 | |
|
410 | |
protected void setHeaders(HttpMethod httpMethod, MuleMessage msg) throws TransformerException |
411 | |
{ |
412 | 0 | for (String headerName : msg.getOutboundPropertyNames()) |
413 | |
{ |
414 | 0 | String headerValue = ObjectUtils.getString(msg.getOutboundProperty(headerName), null); |
415 | |
|
416 | 0 | if (headerName.startsWith(MuleProperties.PROPERTY_PREFIX)) |
417 | |
{ |
418 | |
|
419 | 0 | headerName = new StringBuffer(30).append("X-").append(headerName).toString(); |
420 | 0 | httpMethod.addRequestHeader(headerName, headerValue); |
421 | |
|
422 | |
} |
423 | 0 | else if (!HttpConstants.RESPONSE_HEADER_NAMES.containsKey(headerName) |
424 | |
&& !HttpConnector.HTTP_INBOUND_PROPERTIES.contains(headerName) |
425 | |
&& !HttpConnector.HTTP_COOKIES_PROPERTY.equals(headerName)) |
426 | |
{ |
427 | |
|
428 | 0 | httpMethod.addRequestHeader(headerName, headerValue); |
429 | |
} |
430 | 0 | } |
431 | 0 | } |
432 | |
|
433 | |
protected MultipartRequestEntity createMultiPart(MuleMessage msg, EntityEnclosingMethod method) |
434 | |
throws Exception |
435 | |
{ |
436 | |
Part[] parts; |
437 | 0 | int i = 0; |
438 | 0 | if (msg.getPayload() instanceof NullPayload) |
439 | |
{ |
440 | 0 | parts = new Part[msg.getOutboundAttachmentNames().size()]; |
441 | |
} |
442 | |
else |
443 | |
{ |
444 | 0 | parts = new Part[msg.getOutboundAttachmentNames().size() + 1]; |
445 | 0 | parts[i++] = new FilePart("payload", new ByteArrayPartSource("payload", msg.getPayloadAsBytes())); |
446 | |
} |
447 | |
|
448 | 0 | for (final Iterator<String> iterator = msg.getOutboundAttachmentNames().iterator(); iterator.hasNext(); i++) |
449 | |
{ |
450 | 0 | final String attachmentNames = iterator.next(); |
451 | 0 | String fileName = attachmentNames; |
452 | 0 | final DataHandler dh = msg.getOutboundAttachment(attachmentNames); |
453 | 0 | if (dh.getDataSource() instanceof StringDataSource) |
454 | |
{ |
455 | 0 | final StringDataSource ds = (StringDataSource) dh.getDataSource(); |
456 | 0 | parts[i] = new StringPart(ds.getName(), IOUtils.toString(ds.getInputStream())); |
457 | 0 | } |
458 | |
else |
459 | |
{ |
460 | 0 | if (dh.getDataSource() instanceof FileDataSource) |
461 | |
{ |
462 | 0 | fileName = ((FileDataSource) dh.getDataSource()).getFile().getName(); |
463 | |
} |
464 | 0 | else if (dh.getDataSource() instanceof URLDataSource) |
465 | |
{ |
466 | 0 | fileName = ((URLDataSource) dh.getDataSource()).getURL().getFile(); |
467 | |
|
468 | 0 | final int x = fileName.lastIndexOf("/"); |
469 | 0 | if (x > -1) |
470 | |
{ |
471 | 0 | fileName = fileName.substring(x + 1); |
472 | |
} |
473 | |
} |
474 | 0 | parts[i] = new FilePart(dh.getName(), new ByteArrayPartSource(fileName, |
475 | |
IOUtils.toByteArray(dh.getInputStream())), dh.getContentType(), null); |
476 | |
} |
477 | |
} |
478 | |
|
479 | 0 | return new MultipartRequestEntity(parts, method.getParams()); |
480 | |
} |
481 | |
} |