1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ws.addressing.handler;
17
18 import java.net.MalformedURLException;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23
24 import javax.xml.namespace.QName;
25 import javax.xml.rpc.Call;
26 import javax.xml.rpc.JAXRPCException;
27 import javax.xml.rpc.Service;
28 import javax.xml.rpc.ServiceException;
29 import javax.xml.rpc.ServiceFactory;
30 import javax.xml.rpc.handler.MessageContext;
31 import javax.xml.rpc.handler.soap.SOAPMessageContext;
32 import javax.xml.soap.Node;
33 import javax.xml.soap.SOAPBody;
34 import javax.xml.soap.SOAPConnection;
35 import javax.xml.soap.SOAPConnectionFactory;
36 import javax.xml.soap.SOAPElement;
37 import javax.xml.soap.SOAPException;
38 import javax.xml.soap.SOAPMessage;
39 import javax.xml.transform.TransformerFactory;
40
41 import org.apache.axis.message.addressing.Action;
42 import org.apache.axis.message.addressing.AddressingHeaders;
43 import org.apache.axis.message.addressing.AddressingVersion;
44 import org.apache.axis.message.addressing.AttributedURI;
45 import org.apache.axis.message.addressing.Constants;
46 import org.apache.axis.message.addressing.EndpointReference;
47 import org.apache.axis.message.addressing.MessageID;
48 import org.apache.axis.message.addressing.To;
49 import org.apache.axis.message.addressing.util.AddressingUtils;
50 import org.apache.axis.types.URI;
51 import org.apache.axis.types.URI.MalformedURIException;
52 import org.apache.commons.logging.Log;
53 import org.apache.commons.logging.LogFactory;
54
55
56
57
58
59
60
61
62
63
64 public class ServerSideAddressingHandler extends AbstractAddressingHandler {
65
66
67
68
69 private static final Log LOG = LogFactory.getLog(ServerSideAddressingHandler.class);
70
71
72
73
74
75 public static final FactoryThreadLocal TRANSFORMER_FACTORY = new FactoryThreadLocal();
76
77
78
79
80 @Override
81 public boolean handleRequest(MessageContext msgContext) {
82 SOAPMessageContext soapMsgContext = (SOAPMessageContext) msgContext;
83 try {
84 SOAPMessage msg = soapMsgContext.getMessage();
85 if (msg == null) {
86 return CONTINUE_HANDLER_CHAIN_PROCESSING;
87 }
88 AddressingHeaders headers = new AddressingHeaders(msg.getSOAPPart().getEnvelope(),
89 getActor(), true, isRemoveHeadersEnabled(), false, getReferencePropertyQNames());
90
91 if (headers.getTo() == null) {
92
93 return CONTINUE_HANDLER_CHAIN_PROCESSING;
94 }
95 if (headers.getAction() == null) {
96
97 LOG.debug("WSA request to endpoint " + headers.getTo()
98 + " is missing the required wsa:Action header.");
99 }
100 msgContext.setProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS, headers);
101
102
103
104 setTargetService(soapMsgContext, headers);
105 } catch (Exception e) {
106 if (LOG.isDebugEnabled()) {
107 e.printStackTrace();
108 }
109 throw new JAXRPCException("Unexpected error in handleRequest()", e);
110 }
111 return CONTINUE_HANDLER_CHAIN_PROCESSING;
112 }
113
114
115
116
117 @Override
118 public boolean handleResponse(MessageContext ctx) {
119 SOAPMessageContext soapMsgContext = (SOAPMessageContext) ctx;
120 try {
121 SOAPMessage msg = soapMsgContext.getMessage();
122 if (msg == null) {
123 return CONTINUE_HANDLER_CHAIN_PROCESSING;
124 }
125
126 AddressingVersion version = AddressingUtils.getAddressingVersion(ctx);
127
128 AddressingHeaders reqHeaders = (AddressingHeaders) ctx
129 .getProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS);
130
131 if (reqHeaders == null) {
132
133 return CONTINUE_HANDLER_CHAIN_PROCESSING;
134 }
135 AddressingHeaders resHeaders = AddressingUtils.getResponseHeaders(ctx);
136 resHeaders.setSetMustUnderstand(isMustUnderstandEnabled(ctx));
137 processFromHeader(reqHeaders, resHeaders);
138 processActionHeader(reqHeaders, resHeaders);
139 processToHeader(version, reqHeaders, resHeaders);
140 processRelatesToHeader(version, reqHeaders, resHeaders);
141 processMessageIdHeader(resHeaders);
142 resHeaders.toEnvelope(msg.getSOAPPart().getEnvelope(), getActor());
143 processReplyToHeader(reqHeaders, soapMsgContext);
144 } catch (Exception e) {
145 if (LOG.isDebugEnabled()) {
146 e.printStackTrace();
147 }
148 throw new JAXRPCException("Unexpected error in handleResponse()", e);
149 }
150 return CONTINUE_HANDLER_CHAIN_PROCESSING;
151 }
152
153
154
155
156 @Override
157 public boolean handleFault(MessageContext ctx) {
158 SOAPMessageContext soapMsgContext = (SOAPMessageContext) ctx;
159 AddressingVersion version = AddressingUtils.getAddressingVersion(ctx);
160
161 try {
162 AddressingHeaders reqHeaders = (AddressingHeaders) ctx
163 .getProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS);
164 if (reqHeaders == null) {
165
166 return CONTINUE_HANDLER_CHAIN_PROCESSING;
167 }
168 AddressingHeaders resHeaders = AddressingUtils.getResponseHeaders(ctx);
169 processFromHeader(reqHeaders, resHeaders);
170 resHeaders.setAction(new Action(version.getFaultActionURI()));
171 addRelatesToHeader(version, reqHeaders, resHeaders);
172 addMessageIdHeader(resHeaders);
173 addAddressingHeadersToSOAPEnvelope(soapMsgContext, resHeaders);
174 processFaultToHeader(reqHeaders, soapMsgContext);
175 } catch (Exception e) {
176 if (LOG.isDebugEnabled()) {
177 e.printStackTrace();
178 }
179 throw new JAXRPCException("Unexpected error in handleFault()", e);
180 }
181 return CONTINUE_HANDLER_CHAIN_PROCESSING;
182 }
183
184
185
186
187
188
189
190
191 protected void forwardMessage(SOAPMessageContext ctx, EndpointReference ref) {
192 try {
193 SOAPConnection soapConn = SOAPConnectionFactory.newInstance().createConnection();
194 soapConn.call(ctx.getMessage(), new URL(ref.getAddress().toString()));
195 soapConn.close();
196 SOAPBody responseBody = ctx.getMessage().getSOAPPart().getEnvelope().getBody();
197 removeAllChildElements(responseBody);
198 } catch (SOAPException e) {
199 throw new JAXRPCException("Failed to forward SOAP message.", e);
200 } catch (MalformedURLException e) {
201 throw new JAXRPCException("Failed to forward SOAP message.", e);
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 protected Service getService(MessageContext ctx) throws ServiceException {
221 return ServiceFactory.newInstance().createService(new QName(""));
222 }
223
224
225
226
227
228
229
230
231
232 protected void configureCall(Call call, SOAPMessageContext oldContext) {
233
234 }
235
236
237
238
239
240
241
242
243
244 protected String getTargetServiceName(AddressingHeaders headers) throws Exception {
245 To toURI = headers.getTo();
246 if (toURI == null) {
247 return null;
248 }
249 String to = toURI.getPath();
250 if (to == null) {
251 return null;
252 }
253
254 return (to.substring(to.lastIndexOf('/') + 1));
255 }
256
257
258
259
260
261
262
263
264 protected void setTargetService(SOAPMessageContext ctx, AddressingHeaders headers)
265 throws Exception {
266
267 }
268
269
270
271
272
273
274
275
276 private void processFromHeader(AddressingHeaders reqHeaders,
277 AddressingHeaders resHeaders) {
278 EndpointReference fromEPR = resHeaders.getFrom();
279 if (fromEPR == null) {
280 To toURI = reqHeaders.getTo();
281 if (toURI != null) {
282 fromEPR = new EndpointReference(toURI);
283 fromEPR.setProperties(reqHeaders.getReferenceProperties());
284 resHeaders.setFrom(fromEPR);
285 }
286 }
287 }
288
289
290
291
292
293
294
295
296 private void processActionHeader(AddressingHeaders reqHeaders,
297 AddressingHeaders resHeaders) throws URI.MalformedURIException {
298 Action action = resHeaders.getAction();
299 if (action == null) {
300
301 action = reqHeaders.getAction();
302 if (action != null) {
303 resHeaders
304 .setAction(new Action(new URI(action.toString() + "Response")));
305 }
306 }
307 }
308
309
310
311
312
313
314
315
316
317 private void processToHeader(AddressingVersion version, AddressingHeaders reqHeaders,
318 AddressingHeaders resHeaders) throws MalformedURIException {
319 if (resHeaders.getFrom() == null && reqHeaders.getFrom() != null) {
320 resHeaders.setTo(reqHeaders.getFrom().getAddress());
321 } else {
322 resHeaders.setTo(new To(version.getAnonymousRoleURI()));
323 }
324 }
325
326
327
328
329
330
331
332
333
334 private void processRelatesToHeader(AddressingVersion version,
335 AddressingHeaders reqHeaders, AddressingHeaders resHeaders)
336 throws MalformedURIException {
337 MessageID msgID = reqHeaders.getMessageID();
338 if (msgID != null) {
339 resHeaders.addRelatesTo(msgID.toString(), version.getResponseRelationshipType());
340 }
341 }
342
343
344
345
346
347
348 private void processMessageIdHeader(AddressingHeaders resHeaders)
349 throws URI.MalformedURIException {
350 resHeaders.setMessageID(createMessageID());
351 }
352
353
354
355
356
357
358
359
360 private void processReplyToHeader(AddressingHeaders reqHeaders,
361 SOAPMessageContext ctx) throws Exception {
362 EndpointReference replyTo = reqHeaders.getReplyTo();
363 if (replyTo != null) {
364 AttributedURI address = replyTo.getAddress();
365 if (address != null) {
366 String uri = address.toString();
367 if (uri != null && !uri.equals(AddressingUtils.getAnonymousRoleURI(ctx))) {
368 forwardMessage(ctx, replyTo);
369 }
370 }
371 }
372 }
373
374
375
376
377
378
379
380
381
382 private void addAddressingHeadersToSOAPEnvelope(SOAPMessageContext soapMsgContext,
383 AddressingHeaders resHeaders) throws Exception {
384 SOAPMessage msg = soapMsgContext.getMessage();
385 if (msg == null) {
386 throw new JAXRPCException("Unable to get response message from message context.");
387 }
388 resHeaders.toEnvelope(msg.getSOAPPart().getEnvelope());
389 }
390
391
392
393
394
395
396
397
398 private void processFaultToHeader(AddressingHeaders reqHeaders,
399 SOAPMessageContext soapMsgContext) throws Exception {
400 EndpointReference faultTo = reqHeaders.getFaultTo();
401 if (faultTo != null) {
402 AttributedURI address = faultTo.getAddress();
403 if (address != null && address.toString() != null) {
404 forwardMessage(soapMsgContext, faultTo);
405 }
406 }
407 }
408
409
410
411
412
413
414
415
416
417 private void addRelatesToHeader(AddressingVersion version,
418 AddressingHeaders reqHeaders, AddressingHeaders resHeaders)
419 throws MalformedURIException {
420 MessageID msgID = reqHeaders.getMessageID();
421 if (msgID != null) {
422 resHeaders.addRelatesTo(msgID.toString(), version.getResponseRelationshipType());
423 }
424 }
425
426
427
428
429
430
431
432 private void addMessageIdHeader(AddressingHeaders resHeaders)
433 throws URI.MalformedURIException {
434 MessageID msgID = new MessageID(new URI("uuid:" + generateUUId()));
435 resHeaders.setMessageID(msgID);
436 }
437
438
439
440
441
442
443
444 protected static void removeAllChildElements(SOAPElement soapElem) {
445 Iterator<?> iter = soapElem.getChildElements();
446
447
448 List<?> children = toList(iter);
449 for (int i = 0; i < children.size(); i++) {
450 Node child = (Node) children.get(i);
451 if (child.getParentElement() != null) {
452 child.detachNode();
453 child.recycleNode();
454 }
455 }
456 }
457
458
459
460
461
462
463
464
465 private static <T> List<T> toList(Iterator<T> iter) {
466 List<T> list = new ArrayList<T>();
467 if (iter != null) {
468 while (iter.hasNext()) {
469 list.add(iter.next());
470 }
471 }
472 return list;
473 }
474
475
476
477
478
479
480 private static final class FactoryThreadLocal extends ThreadLocal<TransformerFactory> {
481
482
483
484 @Override
485 protected synchronized TransformerFactory initialValue() {
486 return TransformerFactory.newInstance();
487 }
488 }
489 }