1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.soap.axis.extensions;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.DefaultMuleMessage;
15 import org.mule.MessageExchangePattern;
16 import org.mule.RequestContext;
17 import org.mule.api.MuleContext;
18 import org.mule.api.MuleEvent;
19 import org.mule.api.MuleException;
20 import org.mule.api.MuleMessage;
21 import org.mule.api.MuleSession;
22 import org.mule.api.config.MuleProperties;
23 import org.mule.api.endpoint.EndpointBuilder;
24 import org.mule.api.endpoint.EndpointURI;
25 import org.mule.api.endpoint.ImmutableEndpoint;
26 import org.mule.api.endpoint.OutboundEndpoint;
27 import org.mule.api.processor.MessageProcessor;
28 import org.mule.api.routing.OutboundRouter;
29 import org.mule.api.routing.OutboundRouterCollection;
30 import org.mule.api.service.Service;
31 import org.mule.endpoint.EndpointURIEndpointBuilder;
32 import org.mule.endpoint.MuleEndpointURI;
33 import org.mule.module.cxf.SoapConstants;
34 import org.mule.session.DefaultMuleSession;
35 import org.mule.transport.http.HttpConstants;
36 import org.mule.transport.soap.axis.AxisConnector;
37 import org.mule.transport.soap.axis.extras.AxisCleanAndAddProperties;
38
39 import java.io.File;
40 import java.io.FileInputStream;
41 import java.io.FileOutputStream;
42 import java.util.HashMap;
43 import java.util.Iterator;
44 import java.util.Map;
45
46 import org.apache.axis.AxisFault;
47 import org.apache.axis.Message;
48 import org.apache.axis.MessageContext;
49 import org.apache.axis.client.Call;
50 import org.apache.axis.handlers.BasicHandler;
51 import org.apache.commons.io.output.ByteArrayOutputStream;
52 import org.apache.commons.logging.Log;
53 import org.apache.commons.logging.LogFactory;
54
55
56
57
58 public class UniversalSender extends BasicHandler
59 {
60
61
62
63 private static final long serialVersionUID = 7943380365092172940L;
64
65
66
67
68 protected transient Log logger = LogFactory.getLog(getClass());
69
70 protected Map endpointsCache = new HashMap();
71
72 protected MuleContext muleContext;
73
74
75 public void invoke(MessageContext msgContext) throws AxisFault
76 {
77 try
78 {
79 boolean sync = true;
80 Call call = (Call)msgContext.getProperty("call_object");
81
82 if (call == null)
83 {
84 throw new IllegalStateException(
85 "The call_object property must be set on the message context to the client Call object");
86 }
87
88 muleContext = (MuleContext)call.getProperty(MuleProperties.MULE_CONTEXT_PROPERTY);
89 if(muleContext==null)
90 {
91 throw new IllegalArgumentException("Property org.mule.MuleContext not set on Axis MessageContext");
92 }
93
94
95 MuleEvent event = (MuleEvent)call.getProperty(MuleProperties.MULE_EVENT_PROPERTY);
96
97 if (Boolean.TRUE.equals(call.getProperty("axis.one.way")))
98 {
99 sync = false;
100 }
101
102
103 String uri = msgContext.getStrProp(MessageContext.TRANS_URL);
104 ImmutableEndpoint requestEndpoint = (ImmutableEndpoint)call
105 .getProperty(MuleProperties.MULE_ENDPOINT_PROPERTY);
106
107 OutboundEndpoint endpoint;
108
109
110 if (msgContext.getUsername() != null)
111 {
112 String[] tempEndpoint = uri.split("//");
113 String credentialString = msgContext.getUsername() + ":"
114 + msgContext.getPassword();
115 uri = tempEndpoint[0] + "//" + credentialString + "@" + tempEndpoint[1];
116 endpoint = lookupEndpoint(uri);
117 }
118 else
119 {
120 endpoint = lookupEndpoint(uri);
121 }
122
123 if (requestEndpoint.getConnector() instanceof AxisConnector)
124 {
125 msgContext.setTypeMappingRegistry(((AxisConnector)requestEndpoint.getConnector())
126 .getAxis().getTypeMappingRegistry());
127 }
128
129 Map<String, Object> props = new HashMap<String, Object>();
130 Object payload;
131 int contentLength = 0;
132 String contentType = null;
133 if (msgContext.getRequestMessage().countAttachments() > 0)
134 {
135 File temp = File.createTempFile("soap", ".tmp");
136 temp.deleteOnExit();
137
138 FileOutputStream fos = new FileOutputStream(temp);
139 msgContext.getRequestMessage().writeTo(fos);
140 fos.close();
141 contentLength = (int)temp.length();
142 payload = new FileInputStream(temp);
143 contentType = "multipart/related";
144 }
145 else
146 {
147 ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
148 msgContext.getRequestMessage().writeTo(baos);
149 baos.close();
150 payload = baos.toByteArray();
151 }
152
153
154 for (Iterator iterator = msgContext.getPropertyNames(); iterator.hasNext();)
155 {
156 String name = (String)iterator.next();
157 if (!name.equals("call_object") && !name.equals("wsdl.service"))
158 {
159 props.put(name, msgContext.getProperty(name));
160 }
161 }
162
163
164
165
166
167
168 if ((RequestContext.getEvent() != null)
169 && (RequestContext.getEvent().getMessage() != null))
170 {
171 props = AxisCleanAndAddProperties.cleanAndAdd(RequestContext.getEventContext());
172 }
173
174
175 String scheme = requestEndpoint.getEndpointURI().getScheme();
176 if (!("vm".equalsIgnoreCase(scheme) || "jms".equalsIgnoreCase(scheme)))
177 {
178 if (call.useSOAPAction())
179 {
180 uri = call.getSOAPActionURI();
181 }
182 props.put(SoapConstants.SOAP_ACTION_PROPERTY_CAPS, uri);
183 }
184 if (contentLength > 0)
185 {
186 props.put(HttpConstants.HEADER_CONTENT_LENGTH, Integer.toString(contentLength));
187
188
189
190 }
191
192
193 if (props.get(HttpConstants.HEADER_CONTENT_TYPE) == null)
194 {
195 if (contentType == null)
196 {
197 contentType = "text/xml";
198 }
199
200 props.put(HttpConstants.HEADER_CONTENT_TYPE, contentType);
201 }
202 MuleMessage message = new DefaultMuleMessage(payload, props, muleContext);
203 MuleSession session;
204
205 if(event != null)
206 {
207 session = event.getSession();
208 }
209 else
210 {
211 session = new DefaultMuleSession(muleContext);
212 }
213
214 logger.info("Making Axis soap request on: " + uri);
215 if (logger.isDebugEnabled())
216 {
217 logger.debug("Soap request is:\n" + new String((payload instanceof byte[] ? (byte[])payload : payload.toString().getBytes())));
218 }
219
220 if (sync)
221 {
222 EndpointBuilder builder = new EndpointURIEndpointBuilder(endpoint);
223 builder.setExchangePattern(MessageExchangePattern.REQUEST_RESPONSE);
224 OutboundEndpoint syncEndpoint = muleContext.getRegistry()
225 .lookupEndpointFactory()
226 .getOutboundEndpoint(builder);
227 MuleEvent dispatchEvent = new DefaultMuleEvent(message, syncEndpoint, session);
228 MuleMessage result = null;
229 MuleEvent resultEvent = syncEndpoint.process(dispatchEvent);
230 if (resultEvent != null)
231 {
232 result = resultEvent.getMessage();
233 }
234
235 if (result != null)
236 {
237 byte[] response = result.getPayloadAsBytes();
238 Message responseMessage = new Message(response);
239 msgContext.setResponseMessage(responseMessage);
240
241 }
242 else
243 {
244 logger
245 .warn("No response message was returned from synchronous call to: " + uri);
246 }
247
248 if (payload instanceof File)
249 {
250 ((File)payload).delete();
251 }
252 }
253 else
254 {
255 MuleEvent dispatchEvent = new DefaultMuleEvent(message, endpoint, session);
256 endpoint.process(dispatchEvent);
257 }
258 }
259 catch (Exception e)
260 {
261 if (e instanceof AxisFault)
262 {
263 throw (AxisFault) e;
264 }
265 else
266 {
267 throw new AxisFault(e.getMessage(), e);
268 }
269 }
270
271 }
272
273 protected OutboundEndpoint lookupEndpoint(String uri) throws MuleException
274 {
275 Service axis = muleContext.getRegistry().lookupService(AxisConnector.AXIS_SERVICE_COMPONENT_NAME);
276 EndpointURI endpoint = new MuleEndpointURI(uri, muleContext);
277
278 OutboundEndpoint ep;
279
280 if (axis != null)
281 {
282 synchronized (endpointsCache)
283 {
284 ep = (OutboundEndpoint) endpointsCache.get(endpoint.getAddress());
285 if (ep == null)
286 {
287 updateEndpointCache((OutboundRouterCollection) axis.getOutboundMessageProcessor());
288 ep = (OutboundEndpoint) endpointsCache.get(endpoint.getAddress());
289 if (ep == null)
290 {
291 logger.debug("Dispatch Endpoint uri: " + uri
292 + " not found on the cache. Creating the endpoint instead.");
293 ep = muleContext.getRegistry().lookupEndpointFactory()
294 .getOutboundEndpoint(uri);
295 }
296 else
297 {
298 logger.info("Found endpoint: " + uri + " on the Axis service component");
299 }
300 }
301 else
302 {
303 logger.info("Found endpoint: " + uri + " on the Axis service component");
304 }
305 }
306 }
307 else
308 {
309 ep = muleContext.getRegistry().lookupEndpointFactory()
310 .getOutboundEndpoint(uri);
311 }
312 return ep;
313 }
314
315 private void updateEndpointCache(OutboundRouterCollection router)
316 {
317 endpointsCache.clear();
318 for (Iterator iterator = router.getRoutes().iterator(); iterator.hasNext();)
319 {
320 OutboundRouter r = (OutboundRouter)iterator.next();
321 for (MessageProcessor mp : r.getRoutes())
322 {
323 if (mp instanceof ImmutableEndpoint)
324 {
325 ImmutableEndpoint endpoint = (ImmutableEndpoint) mp;
326 endpointsCache.put(endpoint.getEndpointURI().getAddress(), endpoint);
327 }
328 }
329 }
330 }
331 }