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