1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.soap.axis.extensions;
12
13 import org.mule.MuleManager;
14 import org.mule.config.MuleProperties;
15 import org.mule.impl.MuleEvent;
16 import org.mule.impl.MuleMessage;
17 import org.mule.impl.RequestContext;
18 import org.mule.impl.endpoint.MuleEndpoint;
19 import org.mule.impl.endpoint.MuleEndpointURI;
20 import org.mule.impl.model.ModelHelper;
21 import org.mule.providers.http.HttpConstants;
22 import org.mule.providers.soap.axis.AxisConnector;
23 import org.mule.providers.soap.axis.extras.AxisCleanAndAddProperties;
24 import org.mule.umo.UMODescriptor;
25 import org.mule.umo.UMOEvent;
26 import org.mule.umo.UMOException;
27 import org.mule.umo.UMOMessage;
28 import org.mule.umo.UMOSession;
29 import org.mule.umo.endpoint.UMOEndpoint;
30 import org.mule.umo.endpoint.UMOEndpointURI;
31 import org.mule.umo.endpoint.UMOImmutableEndpoint;
32 import org.mule.umo.routing.UMOOutboundRouter;
33 import org.mule.umo.routing.UMOOutboundRouterCollection;
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 public void invoke(MessageContext msgContext) throws AxisFault
69 {
70 boolean sync = true;
71 Call call = (Call)msgContext.getProperty("call_object");
72 if (call == null)
73 {
74 throw new IllegalStateException(
75 "The call_object property must be set on the message context to the client Call object");
76 }
77 if (Boolean.TRUE.equals(call.getProperty("axis.one.way")))
78 {
79 sync = false;
80 }
81
82
83
84
85
86 String uri = msgContext.getStrProp(MessageContext.TRANS_URL);
87 UMOImmutableEndpoint requestEndpoint = (UMOImmutableEndpoint)call
88 .getProperty(MuleProperties.MULE_ENDPOINT_PROPERTY);
89 UMOImmutableEndpoint endpoint = null;
90
91
92 if (msgContext.getUsername() != null)
93 {
94 String[] tempEndpoint = uri.split("//");
95 String credentialString = msgContext.getUsername() + ":"
96 + msgContext.getPassword();
97 uri = tempEndpoint[0] + "//" + credentialString + "@" + tempEndpoint[1];
98 try
99 {
100 endpoint = lookupEndpoint(uri);
101 }
102 catch (UMOException e)
103 {
104 requestEndpoint.getConnector().handleException(e);
105 return;
106 }
107 }
108 else
109 {
110 try
111 {
112 endpoint = lookupEndpoint(uri);
113 }
114 catch (UMOException e)
115 {
116 requestEndpoint.getConnector().handleException(e);
117 return;
118 }
119 }
120
121 try
122 {
123 if (requestEndpoint.getConnector() instanceof AxisConnector)
124 {
125 msgContext.setTypeMappingRegistry(((AxisConnector)requestEndpoint.getConnector())
126 .getAxisServer().getTypeMappingRegistry());
127 }
128 Object payload = null;
129 int contentLength = 0;
130 if (msgContext.getRequestMessage().countAttachments() > 0)
131 {
132 File temp = File.createTempFile("soap", ".tmp");
133 temp.deleteOnExit();
134
135 FileOutputStream fos = new FileOutputStream(temp);
136 msgContext.getRequestMessage().writeTo(fos);
137 fos.close();
138 contentLength = (int)temp.length();
139 payload = new FileInputStream(temp);
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 Map props = new HashMap();
150
151 for (Iterator iterator = msgContext.getPropertyNames(); iterator.hasNext();)
152 {
153 String name = (String)iterator.next();
154 if (!name.equals("call_object") && !name.equals("wsdl.service"))
155 {
156 props.put(name, msgContext.getProperty(name));
157 }
158 }
159
160
161
162
163
164
165 if ((RequestContext.getEvent() != null)
166 && (RequestContext.getEvent().getMessage() != null))
167 {
168 props = AxisCleanAndAddProperties.cleanAndAdd(RequestContext.getEventContext());
169 }
170
171
172 String scheme = requestEndpoint.getEndpointURI().getScheme();
173 if (!("vm".equalsIgnoreCase(scheme) || "jms".equalsIgnoreCase(scheme)))
174 {
175 if (call.useSOAPAction())
176 {
177 uri = call.getSOAPActionURI();
178 }
179 props.put("SOAPAction", uri);
180 }
181 if (contentLength > 0)
182 {
183 props.put(HttpConstants.HEADER_CONTENT_LENGTH, Integer.toString(contentLength));
184
185
186
187 }
188
189 if (props.get(HttpConstants.HEADER_CONTENT_TYPE) == null)
190 {
191 props.put(HttpConstants.HEADER_CONTENT_TYPE, "text/xml");
192 }
193 UMOMessage message = new MuleMessage(payload, props);
194 UMOSession session = RequestContext.getEventContext().getSession();
195
196 UMOEvent dispatchEvent = new MuleEvent(message, endpoint, session, sync);
197 logger.info("Making Axis soap request on: " + uri);
198 if (logger.isDebugEnabled())
199 {
200 logger.debug("Soap request is:\n" + payload.toString());
201 }
202 if (sync)
203 {
204
205
206 MuleEndpoint syncEndpoint = new MuleEndpoint(dispatchEvent.getEndpoint());
207 syncEndpoint.setRemoteSync(true);
208 dispatchEvent = new MuleEvent(dispatchEvent.getMessage(), syncEndpoint,
209 dispatchEvent.getSession(), dispatchEvent.isSynchronous());
210
211
212
213
214 UMOMessage result = session.sendEvent(dispatchEvent);
215 if (result != null)
216 {
217 byte[] response = result.getPayloadAsBytes();
218 Message responseMessage = new Message(response);
219 msgContext.setResponseMessage(responseMessage);
220
221 }
222 else
223 {
224 logger
225 .warn("No response message was returned from synchronous call to: " + uri);
226 }
227
228 if (payload instanceof File)
229 {
230 ((File)payload).delete();
231 }
232 }
233 else
234 {
235 session.dispatchEvent(dispatchEvent);
236 }
237 }
238 catch (AxisFault axisFault)
239 {
240 throw axisFault;
241 }
242 catch (Exception e)
243 {
244 throw new AxisFault(e.getMessage(), new Throwable(e));
245 }
246
247 }
248
249 protected UMOEndpoint lookupEndpoint(String uri) throws UMOException
250 {
251 UMODescriptor axis = MuleManager.getInstance().lookupModel(ModelHelper.SYSTEM_MODEL)
252 .getDescriptor(AxisConnector.AXIS_SERVICE_COMPONENT_NAME);
253 UMOEndpointURI endpoint = new MuleEndpointURI(uri);
254 UMOEndpoint ep;
255 if (axis != null)
256 {
257 synchronized (endpointsCache)
258 {
259 ep = (UMOEndpoint)endpointsCache.get(endpoint.getAddress());
260 if (ep == null)
261 {
262 updateEndpointCache(axis.getOutboundRouter());
263 ep = (UMOEndpoint)endpointsCache.get(endpoint.getAddress());
264 if (ep == null)
265 {
266 logger.debug("Dispatch Endpoint uri: " + uri
267 + " not found on the cache. Creating the endpoint instead.");
268 ep = new MuleEndpoint(uri, false);
269 }
270 else
271 {
272 logger.info("Found endpoint: " + uri + " on the Axis service component");
273 }
274 }
275 else
276 {
277 logger.info("Found endpoint: " + uri + " on the Axis service component");
278 }
279 }
280 }
281 else
282 {
283 ep = new MuleEndpoint(uri, false);
284 }
285 return ep;
286 }
287
288 private void updateEndpointCache(UMOOutboundRouterCollection router)
289 {
290 endpointsCache.clear();
291 for (Iterator iterator = router.getRouters().iterator(); iterator.hasNext();)
292 {
293 UMOOutboundRouter r = (UMOOutboundRouter)iterator.next();
294 for (Iterator iterator1 = r.getEndpoints().iterator(); iterator1.hasNext();)
295 {
296 UMOEndpoint endpoint = (UMOEndpoint)iterator1.next();
297 endpointsCache.put(endpoint.getEndpointURI().getAddress(), endpoint);
298 }
299 }
300 }
301 }