1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.http.components;
12
13 import org.mule.DefaultMuleMessage;
14 import org.mule.RequestContext;
15 import org.mule.api.MuleEvent;
16 import org.mule.api.MuleException;
17 import org.mule.api.MuleMessage;
18 import org.mule.api.lifecycle.InitialisationException;
19 import org.mule.api.routing.filter.Filter;
20 import org.mule.component.AbstractComponent;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.routing.filters.MessagePropertyFilter;
23 import org.mule.transport.NullPayload;
24 import org.mule.util.expression.ExpressionEvaluator;
25 import org.mule.util.expression.ExpressionEvaluatorManager;
26
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37
38
39
40
41
42 public class RestServiceWrapper extends AbstractComponent
43 {
44
45 public static final String GET = "GET";
46 public static final String CONTENT_TYPE = "Content-Type";
47 public static final String CONTENT_TYPE_VALUE = "application/x-www-form-urlencoded";
48 public static final String HTTP_METHOD = "http.method";
49
50
51
52
53 protected transient Log logger = LogFactory.getLog(getClass());
54
55 private String serviceUrl;
56 private Map requiredParams = new HashMap();
57 private Map optionalParams = new HashMap();
58 private String httpMethod = "GET";
59 private List payloadParameterNames;
60 private Filter errorFilter;
61
62 public String getServiceUrl()
63 {
64 return serviceUrl;
65 }
66
67 public void setServiceUrl(String serviceUrl)
68 {
69 this.serviceUrl = serviceUrl;
70 }
71
72
73 public Map getRequiredParams()
74 {
75 return requiredParams;
76 }
77
78
79
80
81
82
83
84
85
86 public void setRequiredParams(Map requiredParams)
87 {
88 this.requiredParams = requiredParams;
89 }
90
91
92
93
94
95
96
97
98 public Map getOptionalParams()
99 {
100 return optionalParams;
101 }
102
103 public void setOptionalParams(Map optionalParams)
104 {
105 this.optionalParams = optionalParams;
106 }
107
108 public String getHttpMethod()
109 {
110 return httpMethod;
111 }
112
113 public void setHttpMethod(String httpMethod)
114 {
115 this.httpMethod = httpMethod;
116 }
117
118 public List getPayloadParameterNames()
119 {
120 return payloadParameterNames;
121 }
122
123 public void setPayloadParameterNames(List payloadParameterNames)
124 {
125 this.payloadParameterNames = payloadParameterNames;
126 }
127
128 public Filter getFilter()
129 {
130 return errorFilter;
131 }
132
133 public void setFilter(Filter errorFilter)
134 {
135 this.errorFilter = errorFilter;
136 }
137
138
139 protected void doInitialise() throws InitialisationException
140 {
141 if (serviceUrl == null)
142 {
143 throw new InitialisationException(CoreMessages.objectIsNull("serviceUrl"), this);
144 }
145 else if (!ExpressionEvaluatorManager.isValidExpression(serviceUrl))
146 {
147 try
148 {
149 new URL(serviceUrl);
150 }
151 catch (MalformedURLException e)
152 {
153 throw new InitialisationException(e, this);
154 }
155 }
156
157 if (errorFilter == null)
158 {
159
160 errorFilter = new MessagePropertyFilter("http.status!=200");
161 logger.info("Setting default error filter to MessagePropertyFilter('http.status!=200')");
162 }
163 }
164
165 public MuleMessage doOnCall(MuleEvent event) throws Exception
166 {
167 Object requestBody;
168
169 Object request = event.transformMessage();
170 String tempUrl = serviceUrl;
171 MuleMessage result;
172 if (ExpressionEvaluatorManager.isValidExpression(serviceUrl))
173 {
174 tempUrl = ExpressionEvaluatorManager.parse(serviceUrl, event.getMessage(), true);
175 }
176
177 StringBuffer urlBuffer = new StringBuffer(tempUrl);
178
179 if (GET.equalsIgnoreCase(this.httpMethod))
180 {
181 requestBody = NullPayload.getInstance();
182
183 setRESTParams(urlBuffer, event.getMessage(), request, requiredParams, false, null);
184 setRESTParams(urlBuffer, event.getMessage(), request, optionalParams, true, null);
185 }
186 else
187
188 {
189 StringBuffer requestBodyBuffer = new StringBuffer();
190 event.getMessage().setProperty(CONTENT_TYPE, CONTENT_TYPE_VALUE);
191 setRESTParams(urlBuffer, event.getMessage(), request, requiredParams, false, requestBodyBuffer);
192 setRESTParams(urlBuffer, event.getMessage(), request, optionalParams, true, requestBodyBuffer);
193 requestBody = requestBodyBuffer.toString();
194 }
195
196 tempUrl = urlBuffer.toString();
197 logger.info("Invoking REST service: " + tempUrl);
198
199 event.getMessage().setProperty(HTTP_METHOD, httpMethod);
200
201 result = RequestContext.getEventContext().sendEvent(
202 new DefaultMuleMessage(requestBody, event.getMessage()), tempUrl);
203 if (isErrorPayload(result))
204 {
205 handleException(new RestServiceException(CoreMessages.failedToInvokeRestService(tempUrl), result),
206 result);
207 }
208
209 return result;
210 }
211
212 private String getSeparator(String url)
213 {
214 String sep;
215
216 if (url.indexOf("?") > -1)
217 {
218 sep = "&";
219 }
220 else
221 {
222 sep = "?";
223 }
224
225 return sep;
226 }
227
228 private String updateSeparator(String sep)
229 {
230 if (sep.compareTo("?") == 0 || sep.compareTo("") == 0)
231 {
232 return ("&");
233 }
234
235 return sep;
236 }
237
238
239
240
241
242 private void setRESTParams(StringBuffer url,
243 MuleMessage msg,
244 Object body,
245 Map args,
246 boolean optional,
247 StringBuffer requestBodyBuffer)
248 {
249 String sep;
250
251 if (requestBodyBuffer == null)
252 {
253 sep = getSeparator(url.toString());
254 }
255 else
256 {
257 sep = "";
258 }
259
260 for (Iterator iterator = args.entrySet().iterator(); iterator.hasNext();)
261 {
262 Map.Entry entry = (Map.Entry) iterator.next();
263 String name = (String) entry.getKey();
264 String exp = (String) entry.getValue();
265 Object value = ExpressionEvaluatorManager.evaluate(exp, msg);
266
267 if (value == null)
268 {
269 if (!optional)
270 {
271 throw new IllegalArgumentException(CoreMessages.propertyIsNotSetOnEvent(exp).toString());
272 }
273 }
274 else if (requestBodyBuffer != null)
275 {
276 requestBodyBuffer.append(sep);
277 requestBodyBuffer.append(name).append('=').append(value);
278 }
279 else
280 {
281 url.append(sep);
282 url.append(name).append('=').append(value);
283 }
284
285 sep = updateSeparator(sep);
286 }
287
288 if (!optional && payloadParameterNames != null)
289 {
290 if (body instanceof Object[])
291 {
292 Object[] requestArray = (Object[]) body;
293 for (int i = 0; i < payloadParameterNames.size(); i++)
294 {
295 if (requestBodyBuffer != null)
296 {
297 requestBodyBuffer.append(sep).append(payloadParameterNames.get(i)).append('=').append(
298 requestArray[i].toString());
299 }
300 else
301 {
302 url.append(sep).append(payloadParameterNames.get(i)).append('=').append(
303 requestArray[i].toString());
304 }
305
306 sep = updateSeparator(sep);
307 }
308 }
309 else
310 {
311 if (payloadParameterNames.get(0) != null)
312 {
313 if (requestBodyBuffer != null)
314 {
315 requestBodyBuffer.append(payloadParameterNames.get(0)).append('=').append(body.toString());
316 }
317 else
318 {
319 url.append(sep).append(payloadParameterNames.get(0)).append('=').append(body.toString());
320 }
321 }
322 }
323 }
324 }
325
326 protected boolean isErrorPayload(MuleMessage message)
327 {
328 return errorFilter != null && errorFilter.accept(message);
329 }
330
331 protected void handleException(RestServiceException e, MuleMessage result) throws Exception
332 {
333 throw e;
334 }
335
336
337 protected void doOnEvent(MuleEvent event)
338 {
339 try
340 {
341 onCall(event);
342 }
343 catch (MuleException e)
344 {
345 logger.error(e);
346 }
347 }
348
349
350 protected void doDispose()
351 {
352
353 }
354
355
356 protected void doStart() throws MuleException
357 {
358
359 }
360
361
362 protected void doStop() throws MuleException
363 {
364
365 }
366 }