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