001: package org.objectweb.celtix.bus.ws.addressing;
002:
003: import java.lang.reflect.Method;
004: import java.util.Iterator;
005: import java.util.List;
006:
007: import javax.wsdl.Binding;
008: import javax.wsdl.Port;
009: import javax.wsdl.extensions.ExtensibilityElement;
010: import javax.xml.namespace.QName;
011: import javax.xml.ws.RequestWrapper;
012: import javax.xml.ws.ResponseWrapper;
013: import javax.xml.ws.handler.LogicalMessageContext;
014: import javax.xml.ws.handler.MessageContext;
015: import static javax.xml.ws.handler.MessageContext.MESSAGE_OUTBOUND_PROPERTY;
016:
017: import junit.framework.TestCase;
018:
019: import org.easymock.EasyMock;
020: import org.easymock.IArgumentMatcher;
021: import org.easymock.IMocksControl;
022:
023: import org.objectweb.celtix.bindings.DataBindingCallback;
024: import org.objectweb.celtix.bindings.ServerBinding;
025: import org.objectweb.celtix.bus.jaxws.JAXBDataBindingCallback;
026: import org.objectweb.celtix.context.OutputStreamMessageContext;
027: import org.objectweb.celtix.transports.ClientTransport;
028: import org.objectweb.celtix.transports.ServerTransport;
029: import org.objectweb.celtix.ws.addressing.AttributedURIType;
030: import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
031:
032: import static org.objectweb.celtix.bus.bindings.soap.SOAPConstants.SOAP_ENV_ENCSTYLE;
033: import static org.objectweb.celtix.context.ObjectMessageContext.METHOD_OBJ;
034: import static org.objectweb.celtix.context.ObjectMessageContext.REQUESTOR_ROLE_PROPERTY;
035: import static org.objectweb.celtix.context.OutputStreamMessageContext.ONEWAY_MESSAGE_TF;
036: import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES;
037: import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_OUTBOUND;
038: import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND;
039: import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND;
040:
041: public class MAPAggregatorTest extends TestCase {
042:
043: private MAPAggregator aggregator;
044: private IMocksControl control;
045: private AddressingPropertiesImpl expectedMAPs;
046: private String expectedTo;
047: private String expectedReplyTo;
048: private String expectedRelatesTo;
049: private String expectedAction;
050:
051: public void setUp() {
052: aggregator = new MAPAggregator();
053: aggregator.init(null);
054: control = EasyMock.createNiceControl();
055: }
056:
057: public void tearDown() {
058: aggregator.destroy();
059: expectedMAPs = null;
060: expectedTo = null;
061: expectedReplyTo = null;
062: expectedRelatesTo = null;
063: expectedAction = null;
064: }
065:
066: public void testRequestorOutboundUsingAddressingMAPsInContext()
067: throws Exception {
068: LogicalMessageContext context = setUpContext(true, true, false,
069: true, true);
070: boolean proceed = aggregator.handleMessage(context);
071: assertTrue("expected dispatch to proceed", proceed);
072: control.verify();
073: aggregator.close(context);
074: }
075:
076: public void testRequestorOutboundUsingAddressingMAPsInContextZeroLengthAction()
077: throws Exception {
078: LogicalMessageContext context = setUpContext(true, true, false,
079: true, true, true);
080: boolean proceed = aggregator.handleMessage(context);
081: assertTrue("expected dispatch to proceed", proceed);
082: control.verify();
083: aggregator.close(context);
084: }
085:
086: public void testRequestorOutboundUsingAddressingMAPsInContextFault()
087: throws Exception {
088: LogicalMessageContext context = setUpContext(true, true, false,
089: true, true);
090: boolean proceed = aggregator.handleFault(context);
091: assertTrue("expected dispatch to proceed", proceed);
092: control.verify();
093: aggregator.close(context);
094: }
095:
096: public void testRequestorOutboundUsingAddressingNoMAPsInContext()
097: throws Exception {
098: LogicalMessageContext context = setUpContext(true, true, false,
099: true, false);
100: boolean proceed = aggregator.handleMessage(context);
101: assertTrue("expected dispatch to proceed", proceed);
102: control.verify();
103: aggregator.close(context);
104: }
105:
106: public void testRequestorOutboundUsingAddressingNoMAPsInContextFault()
107: throws Exception {
108: LogicalMessageContext context = setUpContext(true, true, false,
109: true, false);
110: boolean proceed = aggregator.handleFault(context);
111: assertTrue("expected dispatch to proceed", proceed);
112: control.verify();
113: aggregator.close(context);
114: }
115:
116: public void testRequestorOutboundNotUsingAddressing()
117: throws Exception {
118: LogicalMessageContext context = setUpContext(true, true, false,
119: false);
120: boolean proceed = aggregator.handleMessage(context);
121: assertTrue("expected dispatch to proceed", proceed);
122: control.verify();
123: aggregator.close(context);
124: }
125:
126: public void testRequestorOutboundNotUsingAddressingFault()
127: throws Exception {
128: LogicalMessageContext context = setUpContext(true, true, false,
129: false);
130: boolean proceed = aggregator.handleFault(context);
131: assertTrue("expected dispatch to proceed", proceed);
132: control.verify();
133: aggregator.close(context);
134: }
135:
136: public void testRequestorOutboundOnewayUsingAddressingMAPsInContext()
137: throws Exception {
138: LogicalMessageContext context = setUpContext(true, true, true,
139: true, true);
140: boolean proceed = aggregator.handleMessage(context);
141: assertTrue("expected dispatch to proceed", proceed);
142: control.verify();
143: aggregator.close(context);
144: }
145:
146: public void testRequestorOutboundOnewayUsingAddressingMAPsInContextFault()
147: throws Exception {
148: LogicalMessageContext context = setUpContext(true, true, true,
149: true, true);
150: boolean proceed = aggregator.handleFault(context);
151: assertTrue("expected dispatch to proceed", proceed);
152: control.verify();
153: aggregator.close(context);
154: }
155:
156: public void testRequestorOutboundOnewayUsingAddressingNoMAPsInContext()
157: throws Exception {
158: LogicalMessageContext context = setUpContext(true, true, true,
159: true, false);
160: boolean proceed = aggregator.handleMessage(context);
161: assertTrue("expected dispatch to proceed", proceed);
162: control.verify();
163: aggregator.close(context);
164: }
165:
166: public void testRequestorOutboundOnewayUsingAddressingNoMAPsInContextFault()
167: throws Exception {
168: LogicalMessageContext context = setUpContext(true, true, true,
169: true, false);
170: boolean proceed = aggregator.handleFault(context);
171: assertTrue("expected dispatch to proceed", proceed);
172: control.verify();
173: aggregator.close(context);
174: }
175:
176: public void testRequestorOutboundOnewayNotUsingAddressing()
177: throws Exception {
178: LogicalMessageContext context = setUpContext(true, true, true,
179: false);
180: boolean proceed = aggregator.handleMessage(context);
181: assertTrue("expected dispatch to proceed", proceed);
182: control.verify();
183: aggregator.close(context);
184: }
185:
186: public void testRequestorOutboundOnewayNotUsingAddressingFault()
187: throws Exception {
188: LogicalMessageContext context = setUpContext(true, true, true,
189: false);
190: boolean proceed = aggregator.handleFault(context);
191: assertTrue("expected dispatch to proceed", proceed);
192: control.verify();
193: aggregator.close(context);
194: }
195:
196: public void testResponderInboundValidMAPs() throws Exception {
197: LogicalMessageContext context = setUpContext(false, false,
198: false);
199: boolean proceed = aggregator.handleMessage(context);
200: assertTrue("expected dispatch to proceed", proceed);
201: control.verify();
202: aggregator.close(context);
203: }
204:
205: public void testResponderInboundDecoupled() throws Exception {
206: LogicalMessageContext context = setUpContext(false, false,
207: false, true, false, true);
208: boolean proceed = aggregator.handleMessage(context);
209: assertTrue("expected dispatch to proceed", proceed);
210: control.verify();
211: aggregator.close(context);
212: }
213:
214: public void testResponderInboundOneway() throws Exception {
215: LogicalMessageContext context = setUpContext(false, false,
216: true, true, false, true);
217: boolean proceed = aggregator.handleMessage(context);
218: assertTrue("expected dispatch to proceed", proceed);
219: control.verify();
220: aggregator.close(context);
221: }
222:
223: public void testResponderInboundValidMAPsFault() throws Exception {
224: LogicalMessageContext context = setUpContext(false, false,
225: false);
226: boolean proceed = aggregator.handleFault(context);
227: assertTrue("expected dispatch to proceed", proceed);
228: control.verify();
229: aggregator.close(context);
230: }
231:
232: public void testResponderInboundInvalidMAPs() throws Exception {
233: aggregator.messageIDs.put("urn:uuid:12345", "urn:uuid:12345");
234: LogicalMessageContext context = setUpContext(false, false,
235: false);
236: boolean proceed = aggregator.handleMessage(context);
237: assertFalse("expected dispatch not to proceed", proceed);
238: control.verify();
239: aggregator.close(context);
240: }
241:
242: public void testResponderInboundInvalidMAPsFault() throws Exception {
243: aggregator.messageIDs.put("urn:uuid:12345", "urn:uuid:12345");
244: LogicalMessageContext context = setUpContext(false, false,
245: false);
246: boolean proceed = aggregator.handleFault(context);
247: assertFalse("expected dispatch not to proceed", proceed);
248: control.verify();
249: aggregator.close(context);
250: }
251:
252: public void testResponderOutbound() throws Exception {
253: LogicalMessageContext context = setUpContext(false, true, false);
254: boolean proceed = aggregator.handleMessage(context);
255: assertTrue("expected dispatch to proceed", proceed);
256: control.verify();
257: aggregator.close(context);
258: }
259:
260: public void testResponderOutboundZeroLengthAction()
261: throws Exception {
262: LogicalMessageContext context = setUpContext(false, true,
263: false, false, false, false, true);
264: boolean proceed = aggregator.handleMessage(context);
265: assertTrue("expected dispatch to proceed", proceed);
266: control.verify();
267: aggregator.close(context);
268: }
269:
270: public void testResponderOutboundFault() throws Exception {
271: LogicalMessageContext context = setUpContext(false, true, false);
272: boolean proceed = aggregator.handleFault(context);
273: assertTrue("expected dispatch to proceed", proceed);
274: control.verify();
275: aggregator.close(context);
276: }
277:
278: public void testRequestorInbound() throws Exception {
279: LogicalMessageContext context = setUpContext(true, true, false);
280: boolean proceed = aggregator.handleMessage(context);
281: assertTrue("expected dispatch to proceed", proceed);
282: control.verify();
283: aggregator.close(context);
284: }
285:
286: public void testRequestorInboundFault() throws Exception {
287: LogicalMessageContext context = setUpContext(true, true, false);
288: boolean proceed = aggregator.handleFault(context);
289: assertTrue("expected dispatch to proceed", proceed);
290: control.verify();
291: aggregator.close(context);
292: }
293:
294: private LogicalMessageContext setUpContext(boolean requestor,
295: boolean outbound, boolean oneway) throws Exception {
296: return setUpContext(requestor, outbound, oneway, false, false,
297: false);
298: }
299:
300: private LogicalMessageContext setUpContext(boolean requestor,
301: boolean outbound, boolean oneway, boolean usingAddressing)
302: throws Exception {
303: return setUpContext(requestor, outbound, oneway,
304: usingAddressing, false, false);
305: }
306:
307: private LogicalMessageContext setUpContext(boolean requestor,
308: boolean outbound, boolean oneway, boolean usingAddressing,
309: boolean mapsInContext) throws Exception {
310: return setUpContext(requestor, outbound, oneway,
311: usingAddressing, mapsInContext, false);
312: }
313:
314: private LogicalMessageContext setUpContext(boolean requestor,
315: boolean outbound, boolean oneway, boolean usingAddressing,
316: boolean mapsInContext, boolean decoupled) throws Exception {
317: return setUpContext(requestor, outbound, oneway,
318: usingAddressing, mapsInContext, decoupled, false);
319: }
320:
321: private LogicalMessageContext setUpContext(boolean requestor,
322: boolean outbound, boolean oneway, boolean usingAddressing,
323: boolean mapsInContext, boolean decoupled,
324: boolean zeroLengthAction) throws Exception {
325:
326: LogicalMessageContext context = control
327: .createMock(LogicalMessageContext.class);
328: context.get(MESSAGE_OUTBOUND_PROPERTY);
329: EasyMock.expectLastCall().andReturn(Boolean.valueOf(outbound));
330: context.get(REQUESTOR_ROLE_PROPERTY);
331: EasyMock.expectLastCall().andReturn(Boolean.valueOf(requestor));
332: if (outbound && requestor) {
333: setUpUsingAddressing(context, usingAddressing);
334: if (usingAddressing) {
335: setUpRequestor(context, oneway, mapsInContext,
336: decoupled, zeroLengthAction);
337: }
338: } else if (!requestor) {
339: setUpResponder(context, oneway, outbound, decoupled,
340: zeroLengthAction);
341: }
342: control.replay();
343: return context;
344: }
345:
346: private void setUpUsingAddressing(LogicalMessageContext context,
347: boolean usingAddressing) {
348: Port port = control.createMock(Port.class);
349: aggregator.clientTransport = control
350: .createMock(ClientTransport.class);
351: aggregator.clientTransport.getPort();
352: EasyMock.expectLastCall().andReturn(port);
353: List portExts = control.createMock(List.class);
354: port.getExtensibilityElements();
355: EasyMock.expectLastCall().andReturn(portExts);
356: Iterator portItr = control.createMock(Iterator.class);
357: portExts.iterator();
358: EasyMock.expectLastCall().andReturn(portItr);
359: Binding binding = control.createMock(Binding.class);
360: port.getBinding();
361: EasyMock.expectLastCall().andReturn(binding);
362: List bindingExts = control.createMock(List.class);
363: binding.getExtensibilityElements();
364: EasyMock.expectLastCall().andReturn(bindingExts);
365: Iterator bindingItr = control.createMock(Iterator.class);
366: bindingExts.iterator();
367: EasyMock.expectLastCall().andReturn(bindingItr);
368: portItr.hasNext();
369: EasyMock.expectLastCall().andReturn(Boolean.TRUE);
370: ExtensibilityElement ext = control
371: .createMock(ExtensibilityElement.class);
372: portItr.next();
373: EasyMock.expectLastCall().andReturn(ext);
374: QName elementType = usingAddressing ? Names.WSAW_USING_ADDRESSING_QNAME
375: : SOAP_ENV_ENCSTYLE;
376: ext.getElementType();
377: EasyMock.expectLastCall().andReturn(elementType);
378: if (!usingAddressing) {
379: portItr.hasNext();
380: EasyMock.expectLastCall().andReturn(Boolean.FALSE);
381: bindingItr.hasNext();
382: EasyMock.expectLastCall().andReturn(Boolean.FALSE);
383: }
384: }
385:
386: private void setUpRequestor(LogicalMessageContext context,
387: boolean oneway, boolean mapsInContext, boolean decoupled,
388: boolean zeroLengthAction) throws Exception {
389: context.get(REQUESTOR_ROLE_PROPERTY);
390: EasyMock.expectLastCall().andReturn(Boolean.TRUE);
391: AddressingPropertiesImpl maps = mapsInContext ? new AddressingPropertiesImpl()
392: : null;
393: if (zeroLengthAction) {
394: maps.setAction(ContextUtils.getAttributedURI(""));
395: }
396: context.get(CLIENT_ADDRESSING_PROPERTIES);
397: EasyMock.expectLastCall().andReturn(maps);
398: Method method = SEI.class.getMethod("op", new Class[0]);
399: if (!zeroLengthAction) {
400: context.get(METHOD_OBJ);
401: EasyMock.expectLastCall().andReturn(method);
402: context.get(REQUESTOR_ROLE_PROPERTY);
403: EasyMock.expectLastCall().andReturn(Boolean.TRUE);
404: expectedAction = "http://foo/bar/SEI/opRequest";
405: }
406: context.get(REQUESTOR_ROLE_PROPERTY);
407: EasyMock.expectLastCall().andReturn(Boolean.TRUE);
408: context.get(ONEWAY_MESSAGE_TF);
409: EasyMock.expectLastCall().andReturn(Boolean.valueOf(oneway));
410: EasyMock.eq(CLIENT_ADDRESSING_PROPERTIES_OUTBOUND);
411: expectedMAPs = maps;
412: expectedTo = Names.WSA_NONE_ADDRESS;
413: expectedReplyTo = oneway ? Names.WSA_NONE_ADDRESS
414: : Names.WSA_ANONYMOUS_ADDRESS;
415: EasyMock.reportMatcher(new MAPMatcher());
416: context.put(CLIENT_ADDRESSING_PROPERTIES_OUTBOUND,
417: mapsInContext ? maps : new AddressingPropertiesImpl());
418: EasyMock.expectLastCall().andReturn(null);
419: context.setScope(CLIENT_ADDRESSING_PROPERTIES_OUTBOUND,
420: MessageContext.Scope.HANDLER);
421: }
422:
423: private void setUpResponder(LogicalMessageContext context,
424: boolean oneway, boolean outbound, boolean decoupled,
425: boolean zeroLengthAction) throws Exception {
426: context.get(REQUESTOR_ROLE_PROPERTY);
427: EasyMock.expectLastCall().andReturn(Boolean.FALSE);
428: AddressingPropertiesImpl maps = new AddressingPropertiesImpl();
429: EndpointReferenceType replyTo = new EndpointReferenceType();
430: replyTo
431: .setAddress(ContextUtils
432: .getAttributedURI(decoupled ? "http://localhost:9999/decoupled"
433: : Names.WSA_ANONYMOUS_ADDRESS));
434: maps.setReplyTo(replyTo);
435: AttributedURIType id = ContextUtils
436: .getAttributedURI("urn:uuid:12345");
437: maps.setMessageID(id);
438: if (zeroLengthAction) {
439: maps.setAction(ContextUtils.getAttributedURI(""));
440: }
441: context.get(SERVER_ADDRESSING_PROPERTIES_INBOUND);
442: EasyMock.expectLastCall().andReturn(maps);
443: if (oneway || decoupled) {
444: context.get(ONEWAY_MESSAGE_TF);
445: EasyMock.expectLastCall()
446: .andReturn(Boolean.valueOf(oneway));
447: aggregator.serverBinding = control
448: .createMock(ServerBinding.class);
449: aggregator.serverTransport = control
450: .createMock(ServerTransport.class);
451: OutputStreamMessageContext outputContext = control
452: .createMock(OutputStreamMessageContext.class);
453: aggregator.serverTransport.rebase(context, replyTo);
454: EasyMock.expectLastCall().andReturn(outputContext);
455: DataBindingCallback callback = new JAXBDataBindingCallback(
456: null, DataBindingCallback.Mode.PARTS, ContextUtils
457: .getJAXBContext());
458: EasyMock.reportMatcher(new PartialResponseMatcher());
459: EasyMock.reportMatcher(new PartialResponseMatcher());
460: aggregator.serverBinding.partialResponse(outputContext,
461: callback);
462: EasyMock.expectLastCall();
463: }
464: if (outbound || aggregator.messageIDs.size() > 0) {
465: if (!zeroLengthAction) {
466: Method method = SEI.class.getMethod("op", new Class[0]);
467: context.get(METHOD_OBJ);
468: EasyMock.expectLastCall().andReturn(method);
469: context.get(REQUESTOR_ROLE_PROPERTY);
470: EasyMock.expectLastCall().andReturn(Boolean.FALSE);
471: expectedAction = "http://foo/bar/SEI/opResponse";
472: }
473: context.get(REQUESTOR_ROLE_PROPERTY);
474: EasyMock.expectLastCall().andReturn(Boolean.FALSE);
475: context.get(SERVER_ADDRESSING_PROPERTIES_INBOUND);
476: EasyMock.expectLastCall().andReturn(maps);
477: EasyMock.eq(SERVER_ADDRESSING_PROPERTIES_OUTBOUND);
478: expectedTo = Names.WSA_ANONYMOUS_ADDRESS;
479: expectedRelatesTo = maps.getMessageID().getValue();
480: EasyMock.reportMatcher(new MAPMatcher());
481: context.put(SERVER_ADDRESSING_PROPERTIES_OUTBOUND,
482: new AddressingPropertiesImpl());
483: EasyMock.expectLastCall().andReturn(null);
484: context.setScope(SERVER_ADDRESSING_PROPERTIES_OUTBOUND,
485: MessageContext.Scope.HANDLER);
486: }
487: }
488:
489: private final class MAPMatcher implements IArgumentMatcher {
490: public boolean matches(Object obj) {
491: if (obj instanceof AddressingPropertiesImpl) {
492: AddressingPropertiesImpl other = (AddressingPropertiesImpl) obj;
493: return compareExpected(other);
494: }
495: return false;
496: }
497:
498: public void appendTo(StringBuffer buffer) {
499: buffer.append("MAPs did not match");
500: }
501:
502: private boolean compareExpected(AddressingPropertiesImpl other) {
503: boolean ret = false;
504: if (expectedMAPs == null || expectedMAPs == other) {
505: boolean toOK = expectedTo == null
506: || expectedTo.equals(other.getTo().getValue());
507: boolean replyToOK = expectedReplyTo == null
508: || expectedReplyTo.equals(other.getReplyTo()
509: .getAddress().getValue());
510: boolean relatesToOK = expectedRelatesTo == null
511: || expectedRelatesTo.equals(other
512: .getRelatesTo().getValue());
513: boolean actionOK = expectedAction == null
514: || expectedAction.equals(other.getAction()
515: .getValue());
516: boolean messageIdOK = other.getMessageID() != null;
517: ret = toOK && replyToOK && relatesToOK && actionOK
518: && messageIdOK;
519: }
520: return ret;
521: }
522: }
523:
524: private final class PartialResponseMatcher implements
525: IArgumentMatcher {
526: public boolean matches(Object obj) {
527: return true;
528: }
529:
530: public void appendTo(StringBuffer buffer) {
531: buffer.append("partial response args did not match");
532: }
533: }
534:
535: private static interface SEI {
536: @RequestWrapper(targetNamespace="http://foo/bar",className="SEI",localName="opRequest")
537: @ResponseWrapper(targetNamespace="http://foo/bar",className="SEI",localName="opResponse")
538: String op();
539: }
540: }
|