0001: /**
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: */package org.apache.cxf.systest.ws.rm;
0019:
0020: import java.math.BigInteger;
0021: import java.util.Iterator;
0022: import java.util.List;
0023: import java.util.concurrent.Executor;
0024: import java.util.concurrent.Executors;
0025: import java.util.logging.Logger;
0026:
0027: import javax.xml.ws.WebServiceException;
0028:
0029: import org.apache.cxf.Bus;
0030: import org.apache.cxf.BusFactory;
0031: import org.apache.cxf.binding.soap.Soap11;
0032: import org.apache.cxf.binding.soap.SoapFault;
0033: import org.apache.cxf.bus.spring.SpringBusFactory;
0034: import org.apache.cxf.endpoint.Client;
0035: import org.apache.cxf.frontend.ClientProxy;
0036: import org.apache.cxf.greeter_control.Control;
0037: import org.apache.cxf.greeter_control.ControlService;
0038: import org.apache.cxf.greeter_control.Greeter;
0039: import org.apache.cxf.greeter_control.GreeterService;
0040: import org.apache.cxf.interceptor.Interceptor;
0041: import org.apache.cxf.message.Message;
0042: import org.apache.cxf.phase.AbstractPhaseInterceptor;
0043: import org.apache.cxf.phase.Phase;
0044: import org.apache.cxf.systest.ws.util.ConnectionHelper;
0045: import org.apache.cxf.systest.ws.util.InMessageRecorder;
0046: import org.apache.cxf.systest.ws.util.MessageFlow;
0047: import org.apache.cxf.systest.ws.util.MessageRecorder;
0048: import org.apache.cxf.systest.ws.util.OutMessageRecorder;
0049: import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
0050: import org.apache.cxf.transport.http.HTTPConduit;
0051: import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
0052: import org.apache.cxf.ws.rm.RMConstants;
0053: import org.apache.cxf.ws.rm.RMContextUtils;
0054: import org.apache.cxf.ws.rm.RMInInterceptor;
0055: import org.apache.cxf.ws.rm.RMManager;
0056: import org.apache.cxf.ws.rm.RMOutInterceptor;
0057: import org.apache.cxf.ws.rm.RMProperties;
0058: import org.apache.cxf.ws.rm.soap.RMSoapInterceptor;
0059: import org.junit.After;
0060: import org.junit.BeforeClass;
0061: import org.junit.Ignore;
0062: import org.junit.Test;
0063:
0064: /**
0065: * Tests the addition of WS-RM properties to application messages and the
0066: * exchange of WS-RM protocol messages.
0067: */
0068: public class SequenceTest extends AbstractBusClientServerTestBase {
0069:
0070: private static final Logger LOG = Logger
0071: .getLogger(SequenceTest.class.getName());
0072: // private static final String APP_NAMESPACE ="http://celtix.objectweb.org/greeter_control";
0073: // private static final String GREETMEONEWAY_ACTION = APP_NAMESPACE +
0074: // "/types/Greeter/greetMeOneWay";
0075: // private static final String GREETME_ACTION = APP_NAMESPACE +
0076: // "/types/Greeter/greetMe";
0077: // private static final String GREETME_RESPONSE_ACTION = GREETME_ACTION +
0078: // "Response";
0079: private static final String GREETMEONEWAY_ACTION = null;
0080: private static final String GREETME_ACTION = null;
0081: private static final String GREETME_RESPONSE_ACTION = null;
0082:
0083: private static int decoupledEndpointPort = 10000;
0084: private static String decoupledEndpoint;
0085:
0086: private Bus controlBus;
0087: private Control control;
0088: private Bus greeterBus;
0089: private Greeter greeter;
0090: private OutMessageRecorder outRecorder;
0091: private InMessageRecorder inRecorder;
0092:
0093: private boolean testAll = true;
0094: private boolean doTestOnewayAnonymousAcks = testAll;
0095: private boolean doTestOnewayDeferredAnonymousAcks = testAll;
0096: private boolean doTestOnewayDeferredNonAnonymousAcks = testAll;
0097: private boolean doTestOnewayAnonymousAcksSequenceLength1 = testAll;
0098: private boolean doTestOnewayAnonymousAcksSuppressed = testAll;
0099: private boolean doTestOnewayAnonymousAcksSuppressedAsyncExecutor = testAll;
0100: private boolean doTestTwowayNonAnonymous = testAll;
0101: private boolean doTestTwowayNonAnonymousEndpointSpecific = testAll;
0102: private boolean doTestTwowayNonAnonymousDeferred = testAll;
0103: private boolean doTestTwowayNonAnonymousMaximumSequenceLength2 = testAll;
0104: private boolean doTestTwowayAtMostOnce = testAll;
0105: private boolean doTestUnknownSequence = testAll;
0106: private boolean doTestInactivityTimeout = testAll;
0107: private boolean doTestOnewayMessageLoss = testAll;
0108: private boolean doTestOnewayMessageLossAsyncExecutor = testAll;
0109: private boolean doTestTwowayMessageLoss = testAll;
0110: private boolean doTestTwowayMessageLossAsyncExecutor = testAll;
0111: private boolean doTestTwowayNonAnonymousNoOffer = testAll;
0112: private boolean doTestConcurrency = testAll;
0113: private boolean doTestMultiClientOneway = testAll;
0114: private boolean doTestMultiClientTwoway = testAll;
0115: private boolean doTestServerSideMessageLoss = testAll;
0116: private boolean doTestTerminateOnShutdown = testAll;
0117:
0118: @BeforeClass
0119: public static void startServers() throws Exception {
0120: assertTrue("server did not launch correctly",
0121: launchServer(Server.class));
0122: }
0123:
0124: @After
0125: public void tearDown() {
0126: stopGreeter();
0127: stopControl();
0128: }
0129:
0130: /**
0131: * Server is configured with RM interceptors, client without;
0132: * Addressing interceptors are installed on either side.
0133: * The (oneway) application request should be dispatched straight to the
0134: * implementor.
0135: */
0136: @Test
0137: @Ignore
0138: public void testRMServerPlainClient() throws Exception {
0139:
0140: SpringBusFactory bf = new SpringBusFactory();
0141:
0142: controlBus = bf.createBus();
0143: BusFactory.setDefaultBus(controlBus);
0144:
0145: ControlService cs = new ControlService();
0146: control = cs.getControlPort();
0147:
0148: assertTrue(
0149: "Failed to start greeter",
0150: control
0151: .startGreeter("org/apache/cxf/systest/ws/rm/rminterceptors.xml"));
0152:
0153: greeterBus = bf
0154: .createBus("org/apache/cxf/systest/ws/rm/rminterceptors.xml");
0155: BusFactory.setDefaultBus(greeterBus);
0156: removeRMInterceptors(greeterBus.getOutInterceptors());
0157: removeRMInterceptors(greeterBus.getOutFaultInterceptors());
0158: removeRMInterceptors(greeterBus.getInInterceptors());
0159: removeRMInterceptors(greeterBus.getInFaultInterceptors());
0160: LOG
0161: .fine("Initialised greeter bus with addressing but without RM interceptors");
0162:
0163: outRecorder = new OutMessageRecorder();
0164: greeterBus.getOutInterceptors().add(outRecorder);
0165: inRecorder = new InMessageRecorder();
0166: greeterBus.getInInterceptors().add(inRecorder);
0167:
0168: GreeterService gs = new GreeterService();
0169: greeter = gs.getGreeterPort();
0170: LOG.fine("Created greeter client.");
0171:
0172: ConnectionHelper.setKeepAliveConnection(greeter, true);
0173:
0174: greeter.greetMeOneWay("once");
0175:
0176: }
0177:
0178: // --- tests ---
0179:
0180: @Test
0181: public void testOnewayAnonymousAcks() throws Exception {
0182: if (!doTestOnewayAnonymousAcks) {
0183: return;
0184: }
0185: init("org/apache/cxf/systest/ws/rm/rminterceptors.xml");
0186:
0187: greeter.greetMeOneWay("once");
0188: greeter.greetMeOneWay("twice");
0189: greeter.greetMeOneWay("thrice");
0190:
0191: // three application messages plus createSequence
0192:
0193: awaitMessages(4, 4);
0194:
0195: MessageFlow mf = new MessageFlow(outRecorder
0196: .getOutboundMessages(), inRecorder.getInboundMessages());
0197:
0198: mf.verifyMessages(4, true);
0199: String[] expectedActions = new String[] {
0200: RMConstants.getCreateSequenceAction(),
0201: GREETMEONEWAY_ACTION, GREETMEONEWAY_ACTION,
0202: GREETMEONEWAY_ACTION };
0203: mf.verifyActions(expectedActions, true);
0204: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0205: true);
0206:
0207: // createSequenceResponse plus 3 partial responses
0208:
0209: mf.verifyMessages(4, false);
0210: expectedActions = new String[] {
0211: RMConstants.getCreateSequenceResponseAction(),
0212: RMConstants.getSequenceAcknowledgmentAction(),
0213: RMConstants.getSequenceAcknowledgmentAction(),
0214: RMConstants.getSequenceAcknowledgmentAction() };
0215: mf.verifyActions(expectedActions, false);
0216: mf.verifyMessageNumbers(
0217: new String[] { null, null, null, null }, false);
0218: mf.verifyAcknowledgements(new boolean[] { false, true, true,
0219: true }, false);
0220: }
0221:
0222: @Test
0223: public void testOnewayDeferredAnonymousAcks() throws Exception {
0224: if (!doTestOnewayDeferredAnonymousAcks) {
0225: return;
0226: }
0227: init("org/apache/cxf/systest/ws/rm/deferred.xml");
0228:
0229: greeter.greetMeOneWay("once");
0230: greeter.greetMeOneWay("twice");
0231:
0232: try {
0233: Thread.sleep(3 * 1000);
0234: } catch (InterruptedException ex) {
0235: // ignore
0236: }
0237:
0238: greeter.greetMeOneWay("thrice");
0239:
0240: awaitMessages(4, 4);
0241: MessageFlow mf = new MessageFlow(outRecorder
0242: .getOutboundMessages(), inRecorder.getInboundMessages());
0243:
0244: // three application messages plus createSequence
0245: mf.verifyMessages(4, true);
0246: String[] expectedActions = new String[] {
0247: RMConstants.getCreateSequenceAction(),
0248: GREETMEONEWAY_ACTION, GREETMEONEWAY_ACTION,
0249: GREETMEONEWAY_ACTION };
0250: mf.verifyActions(expectedActions, true);
0251: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0252: true);
0253:
0254: // createSequenceResponse message plus 3 partial responses, only the
0255: // last one should include a sequence acknowledgment
0256:
0257: mf.verifyMessages(4, false);
0258: expectedActions = new String[] {
0259: RMConstants.getCreateSequenceResponseAction(), null,
0260: null, RMConstants.getSequenceAcknowledgmentAction() };
0261: mf.verifyActions(expectedActions, false);
0262: mf.verifyMessageNumbers(
0263: new String[] { null, null, null, null }, false);
0264: mf.verifyAcknowledgements(new boolean[] { false, false, false,
0265: true }, false);
0266: }
0267:
0268: @Test
0269: public void testOnewayDeferredNonAnonymousAcks() throws Exception {
0270: if (!doTestOnewayDeferredNonAnonymousAcks) {
0271: return;
0272: }
0273: init("org/apache/cxf/systest/ws/rm/deferred.xml", true);
0274:
0275: greeter.greetMeOneWay("once");
0276: greeter.greetMeOneWay("twice");
0277:
0278: // CreateSequence plus two greetMeOneWay requests
0279:
0280: awaitMessages(3, 4);
0281: MessageFlow mf = new MessageFlow(outRecorder
0282: .getOutboundMessages(), inRecorder.getInboundMessages());
0283:
0284: mf.verifyMessages(3, true);
0285: String[] expectedActions = new String[] {
0286: RMConstants.getCreateSequenceAction(),
0287: GREETMEONEWAY_ACTION, GREETMEONEWAY_ACTION };
0288: mf.verifyActions(expectedActions, true);
0289: mf.verifyMessageNumbers(new String[] { null, "1", "2" }, true);
0290:
0291: // CreateSequenceResponse plus three partial responses, no
0292: // acknowledgments included
0293:
0294: mf.verifyMessages(4, false);
0295: mf.verifyMessageNumbers(new String[4], false);
0296: mf.verifyAcknowledgements(new boolean[4], false);
0297:
0298: mf.verifyPartialResponses(3);
0299: mf.purgePartialResponses();
0300:
0301: expectedActions = new String[] { RMConstants
0302: .getCreateSequenceResponseAction() };
0303: mf.verifyActionsIgnoringPartialResponses(expectedActions);
0304: mf.purge();
0305:
0306: try {
0307: Thread.sleep(3 * 1000);
0308: } catch (InterruptedException ex) {
0309: // ignore
0310: }
0311:
0312: // a standalone acknowledgement should have been sent from the server
0313: // side by now
0314:
0315: awaitMessages(0, 1);
0316: mf.reset(outRecorder.getOutboundMessages(), inRecorder
0317: .getInboundMessages());
0318:
0319: mf.verifyMessages(0, true);
0320: mf.verifyMessages(1, false);
0321: mf.verifyAcknowledgements(new boolean[] { true }, false);
0322:
0323: }
0324:
0325: @Test
0326: public void testOnewayAnonymousAcksSequenceLength1()
0327: throws Exception {
0328: if (!doTestOnewayAnonymousAcksSequenceLength1) {
0329: return;
0330: }
0331: init("org/apache/cxf/systest/ws/rm/seqlength1.xml");
0332:
0333: greeter.greetMeOneWay("once");
0334: greeter.greetMeOneWay("twice");
0335:
0336: // two application messages plus two createSequence plus two
0337: // terminateSequence
0338:
0339: awaitMessages(6, 6);
0340:
0341: MessageFlow mf = new MessageFlow(outRecorder
0342: .getOutboundMessages(), inRecorder.getInboundMessages());
0343:
0344: mf.verifyMessages(6, true);
0345: String[] expectedActions = new String[] {
0346: RMConstants.getCreateSequenceAction(),
0347: GREETMEONEWAY_ACTION,
0348: RMConstants.getTerminateSequenceAction(),
0349: RMConstants.getCreateSequenceAction(),
0350: GREETMEONEWAY_ACTION,
0351: RMConstants.getTerminateSequenceAction() };
0352: mf.verifyActions(expectedActions, true);
0353: mf.verifyMessageNumbers(new String[] { null, "1", null, null,
0354: "1", null }, true);
0355: mf.verifyLastMessage(new boolean[] { false, true, false, false,
0356: true, false }, true);
0357:
0358: // createSequenceResponse message plus partial responses to
0359: // greetMeOneWay and terminateSequence ||: 2
0360:
0361: mf.verifyMessages(6, false);
0362:
0363: expectedActions = new String[] {
0364: RMConstants.getCreateSequenceResponseAction(),
0365: RMConstants.getSequenceAcknowledgmentAction(), null,
0366: RMConstants.getCreateSequenceResponseAction(),
0367: RMConstants.getSequenceAcknowledgmentAction(), null };
0368: mf.verifyActions(expectedActions, false);
0369: mf.verifyMessageNumbers(new String[] { null, null, null, null,
0370: null, null }, false);
0371: mf.verifyLastMessage(new boolean[] { false, false, false,
0372: false, false, false }, false);
0373: mf.verifyAcknowledgements(new boolean[] { false, true, false,
0374: false, true, false }, false);
0375: }
0376:
0377: @Test
0378: public void testOnewayAnonymousAcksSuppressed() throws Exception {
0379: if (!doTestOnewayAnonymousAcksSuppressed) {
0380: return;
0381: }
0382: testOnewayAnonymousAcksSuppressed(null);
0383: }
0384:
0385: @Test
0386: public void testOnewayAnonymousAcksSuppressedAsyncExecutor()
0387: throws Exception {
0388: if (!doTestOnewayAnonymousAcksSuppressedAsyncExecutor) {
0389: return;
0390: }
0391: testOnewayAnonymousAcksSuppressed(Executors
0392: .newSingleThreadExecutor());
0393: }
0394:
0395: private void testOnewayAnonymousAcksSuppressed(Executor executor)
0396: throws Exception {
0397:
0398: init("org/apache/cxf/systest/ws/rm/suppressed.xml", false,
0399: executor);
0400:
0401: greeter.greetMeOneWay("once");
0402: greeter.greetMeOneWay("twice");
0403: greeter.greetMeOneWay("thrice");
0404:
0405: // three application messages plus createSequence
0406:
0407: awaitMessages(4, 4, 2000);
0408:
0409: MessageFlow mf = new MessageFlow(outRecorder
0410: .getOutboundMessages(), inRecorder.getInboundMessages());
0411:
0412: mf.verifyMessages(4, true);
0413: String[] expectedActions = new String[] {
0414: RMConstants.getCreateSequenceAction(),
0415: GREETMEONEWAY_ACTION, GREETMEONEWAY_ACTION,
0416: GREETMEONEWAY_ACTION };
0417: mf.verifyActions(expectedActions, true);
0418: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0419: true);
0420:
0421: // createSequenceResponse plus 3 partial responses, none of which
0422: // contain an acknowledgment
0423:
0424: mf.verifyMessages(4, false);
0425: mf.verifyPartialResponses(3, new boolean[3]);
0426: mf.purgePartialResponses();
0427:
0428: expectedActions = new String[] { RMConstants
0429: .getCreateSequenceResponseAction() };
0430: mf.verifyActions(expectedActions, false);
0431:
0432: mf.purge();
0433: assertEquals(0, outRecorder.getOutboundMessages().size());
0434: assertEquals(0, inRecorder.getInboundMessages().size());
0435:
0436: // allow resends to kick in
0437: // await multiple of 3 resends to avoid shutting down server
0438: // in the course of retransmission - this is harmless but pollutes test output
0439:
0440: awaitMessages(3, 0, 7500);
0441:
0442: }
0443:
0444: @Test
0445: public void testTwowayNonAnonymous() throws Exception {
0446: if (!doTestTwowayNonAnonymous) {
0447: return;
0448: }
0449: init("org/apache/cxf/systest/ws/rm/rminterceptors.xml", true);
0450:
0451: greeter.greetMe("one");
0452: greeter.greetMe("two");
0453: greeter.greetMe("three");
0454:
0455: // CreateSequence and three greetMe messages
0456: // TODO there should be partial responses to the decoupled responses!
0457:
0458: awaitMessages(4, 8);
0459:
0460: MessageFlow mf = new MessageFlow(outRecorder
0461: .getOutboundMessages(), inRecorder.getInboundMessages());
0462:
0463: mf.verifyMessages(4, true);
0464: String[] expectedActions = new String[] {
0465: RMConstants.getCreateSequenceAction(), GREETME_ACTION,
0466: GREETME_ACTION, GREETME_ACTION };
0467: mf.verifyActions(expectedActions, true);
0468: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0469: true);
0470: mf.verifyLastMessage(
0471: new boolean[] { false, false, false, false }, true);
0472: mf.verifyAcknowledgements(new boolean[] { false, false, true,
0473: true }, true);
0474:
0475: // createSequenceResponse plus 3 greetMeResponse messages plus
0476: // one partial response for each of the four messages
0477: // the first partial response should no include an acknowledgement, the other three should
0478:
0479: mf.verifyMessages(8, false);
0480: mf.verifyPartialResponses(4, new boolean[4]);
0481:
0482: mf.purgePartialResponses();
0483:
0484: expectedActions = new String[] {
0485: RMConstants.getCreateSequenceResponseAction(),
0486: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION,
0487: GREETME_RESPONSE_ACTION };
0488: mf.verifyActions(expectedActions, false);
0489: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0490: false);
0491: mf.verifyLastMessage(new boolean[4], false);
0492: mf.verifyAcknowledgements(new boolean[] { false, true, true,
0493: true }, false);
0494: }
0495:
0496: // the same as above but using endpoint specific interceptor configuration
0497:
0498: @Test
0499: public void testTwowayNonAnonymousEndpointSpecific()
0500: throws Exception {
0501: if (!doTestTwowayNonAnonymousEndpointSpecific) {
0502: return;
0503: }
0504: init(
0505: "org/apache/cxf/systest/ws/rm/twoway-endpoint-specific.xml",
0506: true);
0507:
0508: greeter.greetMe("one");
0509: greeter.greetMe("two");
0510: greeter.greetMe("three");
0511:
0512: // CreateSequence and three greetMe messages
0513: // TODO there should be partial responses to the decoupled responses!
0514:
0515: awaitMessages(4, 8);
0516:
0517: MessageFlow mf = new MessageFlow(outRecorder
0518: .getOutboundMessages(), inRecorder.getInboundMessages());
0519:
0520: mf.verifyMessages(4, true);
0521: String[] expectedActions = new String[] {
0522: RMConstants.getCreateSequenceAction(), GREETME_ACTION,
0523: GREETME_ACTION, GREETME_ACTION };
0524: mf.verifyActions(expectedActions, true);
0525: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0526: true);
0527: mf.verifyLastMessage(
0528: new boolean[] { false, false, false, false }, true);
0529: mf.verifyAcknowledgements(new boolean[] { false, false, true,
0530: true }, true);
0531:
0532: // createSequenceResponse plus 3 greetMeResponse messages plus
0533: // one partial response for each of the four messages
0534: // the first partial response should no include an acknowledgement, the other three should
0535:
0536: mf.verifyMessages(8, false);
0537: mf.verifyPartialResponses(4, new boolean[4]);
0538:
0539: mf.purgePartialResponses();
0540:
0541: expectedActions = new String[] {
0542: RMConstants.getCreateSequenceResponseAction(),
0543: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION,
0544: GREETME_RESPONSE_ACTION };
0545: mf.verifyActions(expectedActions, false);
0546: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3" },
0547: false);
0548: mf.verifyLastMessage(new boolean[4], false);
0549: mf.verifyAcknowledgements(new boolean[] { false, true, true,
0550: true }, false);
0551: }
0552:
0553: @Test
0554: public void testTwowayNonAnonymousDeferred() throws Exception {
0555: if (!doTestTwowayNonAnonymousDeferred) {
0556: return;
0557: }
0558: init("org/apache/cxf/systest/ws/rm/deferred.xml", true);
0559:
0560: greeter.greetMe("one");
0561: greeter.greetMe("two");
0562:
0563: // CreateSequence and three greetMe messages, no acknowledgments
0564: // included
0565:
0566: awaitMessages(3, 6);
0567: MessageFlow mf = new MessageFlow(outRecorder
0568: .getOutboundMessages(), inRecorder.getInboundMessages());
0569:
0570: mf.verifyMessages(3, true);
0571: String[] expectedActions = new String[] {
0572: RMConstants.getCreateSequenceAction(), GREETME_ACTION,
0573: GREETME_ACTION };
0574: mf.verifyActions(expectedActions, true);
0575: mf.verifyMessageNumbers(new String[] { null, "1", "2" }, true);
0576: mf.verifyLastMessage(new boolean[3], true);
0577: mf.verifyAcknowledgements(new boolean[3], true);
0578:
0579: // CreateSequenceResponse plus 2 greetMeResponse messages plus
0580: // one partial response for each of the three messages no acknowledgments
0581: // included
0582:
0583: mf.verifyMessages(6, false);
0584: mf.verifyLastMessage(new boolean[6], false);
0585: mf.verifyAcknowledgements(new boolean[6], false);
0586:
0587: mf.verifyPartialResponses(3);
0588: mf.purgePartialResponses();
0589: expectedActions = new String[] {
0590: RMConstants.getCreateSequenceResponseAction(),
0591: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION };
0592: mf.verifyActions(expectedActions, false);
0593: mf.verifyMessageNumbers(new String[] { null, "1", "2" }, false);
0594: mf.purge();
0595:
0596: // one standalone acknowledgement should have been sent from the client and one
0597: // should have been received from the server
0598:
0599: awaitMessages(1, 0);
0600: mf.reset(outRecorder.getOutboundMessages(), inRecorder
0601: .getInboundMessages());
0602:
0603: mf.verifyMessageNumbers(new String[1], true);
0604: mf.verifyLastMessage(new boolean[1], true);
0605: mf.verifyAcknowledgements(new boolean[] { true }, true);
0606:
0607: }
0608:
0609: /**
0610: * A maximum sequence length of 2 is configured for the client only (server allows 10).
0611: * However, as we use the defaults regarding the including and acceptance
0612: * for inbound sequence offers and correlate offered sequences that are
0613: * included in a CreateSequence request and accepted with those that are
0614: * created on behalf of such a request, the server also tries terminate its
0615: * sequences. Note that as part of the sequence termination exchange a
0616: * standalone sequence acknowledgment needs to be sent regardless of whether
0617: * or nor acknowledgments are delivered steadily with every response.
0618: */
0619: @Test
0620: public void testTwowayNonAnonymousMaximumSequenceLength2()
0621: throws Exception {
0622:
0623: if (!doTestTwowayNonAnonymousMaximumSequenceLength2) {
0624: return;
0625: }
0626: init("org/apache/cxf/systest/ws/rm/seqlength10.xml", true);
0627:
0628: RMManager manager = greeterBus.getExtension(RMManager.class);
0629: assertEquals("Unexpected maximum sequence length.",
0630: BigInteger.TEN, manager.getSourcePolicy()
0631: .getSequenceTerminationPolicy().getMaxLength());
0632: manager.getSourcePolicy().getSequenceTerminationPolicy()
0633: .setMaxLength(new BigInteger("2"));
0634:
0635: greeter.greetMe("one");
0636: greeter.greetMe("two");
0637: greeter.greetMe("three");
0638:
0639: awaitMessages(7, 13, 5000);
0640: MessageFlow mf = new MessageFlow(outRecorder
0641: .getOutboundMessages(), inRecorder.getInboundMessages());
0642:
0643: mf.verifyMessages(7, true);
0644: String[] expectedActions = new String[] {
0645: RMConstants.getCreateSequenceAction(), GREETME_ACTION,
0646: GREETME_ACTION,
0647: RMConstants.getTerminateSequenceAction(),
0648: RMConstants.getSequenceAckAction(),
0649: RMConstants.getCreateSequenceAction(), GREETME_ACTION };
0650: mf.verifyActions(expectedActions, true);
0651: mf.verifyMessageNumbers(new String[] { null, "1", "2", null,
0652: null, null, "1" }, true);
0653: mf.verifyLastMessage(new boolean[] { false, false, true, false,
0654: false, false, false }, true);
0655: mf.verifyAcknowledgements(new boolean[] { false, false, true,
0656: false, true, false, false }, true);
0657:
0658: // 7 partial responses plus 2 full responses to CreateSequence requests
0659: // plus 3 full responses to greetMe requests plus server originiated
0660: // TerminateSequence request
0661:
0662: mf.verifyMessages(13, false);
0663:
0664: mf.verifyPartialResponses(7);
0665:
0666: mf.purgePartialResponses();
0667:
0668: expectedActions = new String[] {
0669: RMConstants.getCreateSequenceResponseAction(),
0670: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION,
0671: RMConstants.getTerminateSequenceAction(),
0672: RMConstants.getCreateSequenceResponseAction(),
0673: GREETME_RESPONSE_ACTION };
0674: mf.verifyActions(expectedActions, false);
0675: mf.verifyMessageNumbers(new String[] { null, "1", "2", null,
0676: null, "1" }, false);
0677: boolean[] expected = new boolean[6];
0678: expected[2] = true;
0679: mf.verifyLastMessage(expected, false);
0680: expected[1] = true;
0681: expected[5] = true;
0682: mf.verifyAcknowledgements(expected, false);
0683: }
0684:
0685: @Test
0686: public void testTwowayAtMostOnce() throws Exception {
0687: if (!doTestTwowayAtMostOnce) {
0688: return;
0689: }
0690:
0691: init("org/apache/cxf/systest/ws/rm/atmostonce.xml");
0692:
0693: class MessageNumberInterceptor extends AbstractPhaseInterceptor {
0694: public MessageNumberInterceptor() {
0695: super (Phase.USER_LOGICAL);
0696: }
0697:
0698: public void handleMessage(Message m) {
0699: RMProperties rmps = RMContextUtils
0700: .retrieveRMProperties(m, true);
0701: if (null != rmps && null != rmps.getSequence()) {
0702: rmps.getSequence().setMessageNumber(BigInteger.ONE);
0703: }
0704: }
0705: }
0706: greeterBus.getOutInterceptors().add(
0707: new MessageNumberInterceptor());
0708: RMManager manager = greeterBus.getExtension(RMManager.class);
0709: manager.getRMAssertion().getBaseRetransmissionInterval()
0710: .setMilliseconds(new BigInteger("2000"));
0711:
0712: greeter.greetMe("one");
0713: try {
0714: greeter.greetMe("two");
0715: fail("Expected fault.");
0716: } catch (WebServiceException ex) {
0717: SoapFault sf = (SoapFault) ex.getCause();
0718: assertEquals("Unexpected fault code.", Soap11.getInstance()
0719: .getReceiver(), sf.getFaultCode());
0720: assertNull("Unexpected sub code.", sf.getSubCode());
0721: assertTrue("Unexpected reason.", sf.getReason().endsWith(
0722: "has already been delivered."));
0723: }
0724:
0725: // wait for resend to occur
0726:
0727: awaitMessages(3, 3, 5000);
0728:
0729: MessageFlow mf = new MessageFlow(outRecorder
0730: .getOutboundMessages(), inRecorder.getInboundMessages());
0731:
0732: // Expected outbound:
0733: // CreateSequence
0734: // + two requests
0735:
0736: String[] expectedActions = new String[3];
0737: expectedActions[0] = RMConstants.getCreateSequenceAction();
0738: for (int i = 1; i < expectedActions.length; i++) {
0739: expectedActions[i] = GREETME_ACTION;
0740: }
0741: mf.verifyActions(expectedActions, true);
0742: mf.verifyMessageNumbers(new String[] { null, "1", "1" }, true);
0743: mf.verifyLastMessage(new boolean[3], true);
0744: mf.verifyAcknowledgements(new boolean[3], true);
0745:
0746: // Expected inbound:
0747: // createSequenceResponse
0748: // + 1 response without acknowledgement
0749: // + 1 fault
0750:
0751: mf.verifyMessages(3, false);
0752: expectedActions = new String[] {
0753: RMConstants.getCreateSequenceResponseAction(), null,
0754: null };
0755: mf.verifyActions(expectedActions, false);
0756: mf
0757: .verifyMessageNumbers(new String[] { null, "1", null },
0758: false);
0759: mf.verifyAcknowledgements(new boolean[3], false);
0760:
0761: }
0762:
0763: @Test
0764: public void testUnknownSequence() throws Exception {
0765: if (!doTestUnknownSequence) {
0766: return;
0767: }
0768:
0769: init("org/apache/cxf/systest/ws/rm/rminterceptors.xml");
0770:
0771: class SequenceIdInterceptor extends AbstractPhaseInterceptor {
0772: public SequenceIdInterceptor() {
0773: super (Phase.USER_LOGICAL);
0774: }
0775:
0776: public void handleMessage(Message m) {
0777: RMProperties rmps = RMContextUtils
0778: .retrieveRMProperties(m, true);
0779: if (null != rmps && null != rmps.getSequence()) {
0780: rmps.getSequence().getIdentifier().setValue(
0781: "UNKNOWN");
0782: }
0783: }
0784: }
0785: greeterBus.getOutInterceptors()
0786: .add(new SequenceIdInterceptor());
0787: RMManager manager = greeterBus.getExtension(RMManager.class);
0788: manager.getRMAssertion().getBaseRetransmissionInterval()
0789: .setMilliseconds(new BigInteger("2000"));
0790:
0791: try {
0792: greeter.greetMe("one");
0793: fail("Expected fault.");
0794: } catch (WebServiceException ex) {
0795: SoapFault sf = (SoapFault) ex.getCause();
0796: assertEquals("Unexpected fault code.", Soap11.getInstance()
0797: .getSender(), sf.getFaultCode());
0798: assertNull("Unexpected sub code.", sf.getSubCode());
0799: assertTrue("Unexpected reason.", sf.getReason().endsWith(
0800: "is not a known Sequence identifier."));
0801: }
0802:
0803: // the third inbound message has a SequenceFault header
0804: MessageFlow mf = new MessageFlow(outRecorder
0805: .getOutboundMessages(), inRecorder.getInboundMessages());
0806: mf.verifySequenceFault(RMConstants
0807: .getUnknownSequenceFaultCode(), false, 1);
0808: }
0809:
0810: @Test
0811: public void testInactivityTimeout() throws Exception {
0812: if (!doTestInactivityTimeout) {
0813: return;
0814: }
0815:
0816: init("org/apache/cxf/systest/ws/rm/inactivity-timeout.xml");
0817:
0818: greeter.greetMe("one");
0819:
0820: try {
0821: Thread.sleep(500);
0822: } catch (InterruptedException ex) {
0823: // ignore
0824: }
0825:
0826: try {
0827: greeter.greetMe("two");
0828: fail("Expected fault.");
0829: } catch (WebServiceException ex) {
0830: SoapFault sf = (SoapFault) ex.getCause();
0831: assertEquals("Unexpected fault code.", Soap11.getInstance()
0832: .getSender(), sf.getFaultCode());
0833: assertNull("Unexpected sub code.", sf.getSubCode());
0834: assertTrue("Unexpected reason.", sf.getReason().endsWith(
0835: "is not a known Sequence identifier."));
0836: }
0837:
0838: awaitMessages(3, 3, 5000);
0839:
0840: MessageFlow mf = new MessageFlow(outRecorder
0841: .getOutboundMessages(), inRecorder.getInboundMessages());
0842:
0843: // Expected outbound:
0844: // CreateSequence
0845: // + two requests (second request does not include acknowledgement for first response as
0846: // in the meantime the client has terminated the sequence
0847:
0848: String[] expectedActions = new String[3];
0849: expectedActions[0] = RMConstants.getCreateSequenceAction();
0850: for (int i = 1; i < expectedActions.length; i++) {
0851: expectedActions[i] = GREETME_ACTION;
0852: }
0853: mf.verifyActions(expectedActions, true);
0854: mf.verifyMessageNumbers(new String[] { null, "1", "2" }, true);
0855: mf.verifyLastMessage(new boolean[3], true);
0856: mf.verifyAcknowledgements(
0857: new boolean[] { false, false, false }, true);
0858:
0859: // Expected inbound:
0860: // createSequenceResponse
0861: // + 1 response with acknowledgement
0862: // + 1 fault without acknowledgement
0863:
0864: mf.verifyMessages(3, false);
0865: expectedActions = new String[] {
0866: RMConstants.getCreateSequenceResponseAction(), null,
0867: null };
0868: mf.verifyActions(expectedActions, false);
0869: mf
0870: .verifyMessageNumbers(new String[] { null, "1", null },
0871: false);
0872: mf.verifyAcknowledgements(new boolean[] { false, true, false },
0873: false);
0874:
0875: // the third inbound message has a SequenceFault header
0876:
0877: mf.verifySequenceFault(RMConstants
0878: .getUnknownSequenceFaultCode(), false, 2);
0879:
0880: }
0881:
0882: @Test
0883: public void testOnewayMessageLoss() throws Exception {
0884: if (!doTestOnewayMessageLoss) {
0885: return;
0886: }
0887: testOnewayMessageLoss(null);
0888: }
0889:
0890: @Test
0891: public void testOnewayMessageLossAsyncExecutor() throws Exception {
0892: if (!doTestOnewayMessageLossAsyncExecutor) {
0893: return;
0894: }
0895: testOnewayMessageLoss(Executors.newSingleThreadExecutor());
0896: }
0897:
0898: private void testOnewayMessageLoss(Executor executor)
0899: throws Exception {
0900:
0901: init("org/apache/cxf/systest/ws/rm/message-loss.xml", false,
0902: executor);
0903:
0904: greeterBus.getOutInterceptors().add(new MessageLossSimulator());
0905: RMManager manager = greeterBus.getExtension(RMManager.class);
0906: manager.getRMAssertion().getBaseRetransmissionInterval()
0907: .setMilliseconds(new BigInteger("2000"));
0908:
0909: greeter.greetMeOneWay("one");
0910: greeter.greetMeOneWay("two");
0911: greeter.greetMeOneWay("three");
0912: greeter.greetMeOneWay("four");
0913:
0914: awaitMessages(7, 5, 10000);
0915:
0916: MessageFlow mf = new MessageFlow(outRecorder
0917: .getOutboundMessages(), inRecorder.getInboundMessages());
0918:
0919: // Expected outbound:
0920: // CreateSequence
0921: // + 4 greetMe messages
0922: // + at least 2 resends (message may be resent multiple times depending
0923: // on the timing of the ACKs)
0924:
0925: String[] expectedActions = new String[7];
0926: expectedActions[0] = RMConstants.getCreateSequenceAction();
0927: for (int i = 1; i < expectedActions.length; i++) {
0928: expectedActions[i] = GREETMEONEWAY_ACTION;
0929: }
0930: mf.verifyActions(expectedActions, true);
0931: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3",
0932: "4", "2", "4" }, true, false);
0933: mf.verifyLastMessage(new boolean[7], true);
0934: mf.verifyAcknowledgements(new boolean[7], true);
0935:
0936: // Expected inbound:
0937: // createSequenceResponse
0938: // + 2 partial responses to successfully transmitted messages
0939: // + 2 partial responses to resent messages
0940:
0941: mf.verifyMessages(5, false);
0942: expectedActions = new String[] {
0943: RMConstants.getCreateSequenceResponseAction(),
0944: RMConstants.getSequenceAcknowledgmentAction(),
0945: RMConstants.getSequenceAcknowledgmentAction(),
0946: RMConstants.getSequenceAcknowledgmentAction(),
0947: RMConstants.getSequenceAcknowledgmentAction() };
0948: mf.verifyActions(expectedActions, false);
0949: mf.verifyMessageNumbers(new String[] { null, null, null, null,
0950: null }, false);
0951: mf.verifyAcknowledgements(new boolean[] { false, true, true,
0952: true, true }, false);
0953:
0954: }
0955:
0956: @Test
0957: public void testTwowayMessageLoss() throws Exception {
0958: if (!doTestTwowayMessageLoss) {
0959: return;
0960: }
0961: testTwowayMessageLoss(null);
0962: }
0963:
0964: @Test
0965: public void testTwowayMessageLossAsyncExecutor() throws Exception {
0966: if (!doTestTwowayMessageLossAsyncExecutor) {
0967: return;
0968: }
0969: testTwowayMessageLoss(Executors.newSingleThreadExecutor());
0970: }
0971:
0972: private void testTwowayMessageLoss(Executor executor)
0973: throws Exception {
0974:
0975: init("org/apache/cxf/systest/ws/rm/message-loss.xml", true,
0976: executor);
0977:
0978: greeterBus.getOutInterceptors().add(new MessageLossSimulator());
0979: RMManager manager = greeterBus.getExtension(RMManager.class);
0980: manager.getRMAssertion().getBaseRetransmissionInterval()
0981: .setMilliseconds(new BigInteger("2000"));
0982:
0983: greeter.greetMe("one");
0984: greeter.greetMe("two");
0985: greeter.greetMe("three");
0986: greeter.greetMe("four");
0987:
0988: awaitMessages(7, 10, 10000);
0989:
0990: MessageFlow mf = new MessageFlow(outRecorder
0991: .getOutboundMessages(), inRecorder.getInboundMessages());
0992:
0993: // Expected outbound:
0994: // CreateSequence
0995: // + 4 greetMe messages
0996: // + 2 resends
0997:
0998: String[] expectedActions = new String[7];
0999: expectedActions[0] = RMConstants.getCreateSequenceAction();
1000: for (int i = 1; i < expectedActions.length; i++) {
1001: expectedActions[i] = GREETME_ACTION;
1002: }
1003: mf.verifyActions(expectedActions, true);
1004: mf.verifyMessageNumbers(new String[] { null, "1", "2", "2",
1005: "3", "4", "4" }, true);
1006: mf.verifyLastMessage(new boolean[7], true);
1007: boolean[] expectedAcks = new boolean[7];
1008: for (int i = 2; i < expectedAcks.length; i++) {
1009: expectedAcks[i] = true;
1010: }
1011: mf.verifyAcknowledgements(expectedAcks, true);
1012:
1013: // Expected inbound:
1014: // createSequenceResponse
1015: // + 4 greetMeResponse actions (to original or resent)
1016: // + 5 partial responses (to CSR & each of the initial greetMe messages)
1017: // + at least 2 further partial response (for each of the resends)
1018:
1019: mf.verifyPartialResponses(5);
1020: mf.purgePartialResponses();
1021:
1022: expectedActions = new String[] {
1023: RMConstants.getCreateSequenceResponseAction(),
1024: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION,
1025: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION };
1026: mf.verifyActions(expectedActions, false);
1027: mf.verifyMessageNumbers(
1028: new String[] { null, "1", "2", "3", "4" }, false);
1029: mf.verifyAcknowledgements(new boolean[] { false, true, true,
1030: true, true }, false);
1031:
1032: }
1033:
1034: @Test
1035: public void testTwowayNonAnonymousNoOffer() throws Exception {
1036: if (!doTestTwowayNonAnonymousNoOffer) {
1037: return;
1038: }
1039: init("org/apache/cxf/systest/ws/rm/no-offer.xml", true);
1040:
1041: greeter.greetMe("one");
1042: // greeter.greetMe("two");
1043:
1044: // Outbound expected:
1045: // CreateSequence + greetMe + CreateSequenceResponse = 3 messages
1046:
1047: awaitMessages(3, 6);
1048: MessageFlow mf = new MessageFlow(outRecorder
1049: .getOutboundMessages(), inRecorder.getInboundMessages());
1050:
1051: mf.verifyMessages(3, true);
1052: String[] expectedActions = new String[] {
1053: RMConstants.getCreateSequenceAction(), GREETME_ACTION,
1054: RMConstants.getCreateSequenceResponseAction() };
1055: mf.verifyActions(expectedActions, true);
1056: mf.verifyMessageNumbers(new String[] { null, "1", null }, true);
1057: mf.verifyLastMessage(new boolean[] { false, false, false },
1058: true);
1059: mf.verifyAcknowledgements(
1060: new boolean[] { false, false, false }, true);
1061:
1062: mf.verifyPartialResponses(3, new boolean[3]);
1063: mf.purgePartialResponses();
1064:
1065: expectedActions = new String[] {
1066: RMConstants.getCreateSequenceResponseAction(),
1067: RMConstants.getCreateSequenceAction(),
1068: GREETME_RESPONSE_ACTION };
1069: mf.verifyActions(expectedActions, false);
1070: mf
1071: .verifyMessageNumbers(new String[] { null, null, "1" },
1072: false);
1073: mf.verifyAcknowledgements(
1074: new boolean[] { false, false, false }, false);
1075: }
1076:
1077: @Test
1078: public void testConcurrency() throws Exception {
1079: if (!doTestConcurrency) {
1080: return;
1081: }
1082: init("org/apache/cxf/systest/ws/rm/rminterceptors.xml", true);
1083:
1084: for (int i = 0; i < 5; i++) {
1085: greeter.greetMeAsync(Integer.toString(i));
1086: }
1087:
1088: // CreateSequence and five greetMe messages
1089: // full and partial responses to each
1090:
1091: awaitMessages(6, 12, 7500);
1092: MessageFlow mf = new MessageFlow(outRecorder
1093: .getOutboundMessages(), inRecorder.getInboundMessages());
1094:
1095: mf.verifyMessages(6, true);
1096: String[] expectedActions = new String[6];
1097: expectedActions[0] = RMConstants.getCreateSequenceAction();
1098: for (int i = 1; i < expectedActions.length; i++) {
1099: expectedActions[i] = GREETME_ACTION;
1100: }
1101: mf.verifyActions(expectedActions, true);
1102: }
1103:
1104: @Test
1105: public void testMultiClientOneway() throws Exception {
1106: if (!doTestMultiClientOneway) {
1107: return;
1108: }
1109:
1110: SpringBusFactory bf = new SpringBusFactory();
1111: String cfgResource = "org/apache/cxf/systest/ws/rm/rminterceptors.xml";
1112: initControl(bf, cfgResource);
1113:
1114: class ClientThread extends Thread {
1115:
1116: Greeter greeter;
1117: Bus greeterBus;
1118: InMessageRecorder inRecorder;
1119: OutMessageRecorder outRecorder;
1120: String id;
1121:
1122: ClientThread(SpringBusFactory bf, String cfgResource, int n) {
1123: SequenceTest.this .initGreeter(bf, cfgResource, false,
1124: null);
1125: greeter = SequenceTest.this .greeter;
1126: greeterBus = SequenceTest.this .greeterBus;
1127: inRecorder = SequenceTest.this .inRecorder;
1128: outRecorder = SequenceTest.this .outRecorder;
1129: id = "client " + n;
1130: }
1131:
1132: public void run() {
1133: greeter.greetMeOneWay(id + ": once");
1134: greeter.greetMeOneWay(id + ": twice");
1135: greeter.greetMeOneWay(id + ": thrice");
1136:
1137: // three application messages plus createSequence
1138:
1139: awaitMessages(4, 4);
1140: }
1141: }
1142:
1143: ClientThread clients[] = new ClientThread[2];
1144:
1145: try {
1146: for (int i = 0; i < clients.length; i++) {
1147: clients[i] = new ClientThread(bf, cfgResource, i);
1148: }
1149:
1150: for (int i = 0; i < clients.length; i++) {
1151: clients[i].start();
1152: }
1153:
1154: for (int i = 0; i < clients.length; i++) {
1155: clients[i].join();
1156: MessageFlow mf = new MessageFlow(clients[i].outRecorder
1157: .getOutboundMessages(), clients[i].inRecorder
1158: .getInboundMessages());
1159:
1160: mf.verifyMessages(4, true);
1161: String[] expectedActions = new String[] {
1162: RMConstants.getCreateSequenceAction(),
1163: GREETMEONEWAY_ACTION, GREETMEONEWAY_ACTION,
1164: GREETMEONEWAY_ACTION };
1165: mf.verifyActions(expectedActions, true);
1166: mf.verifyMessageNumbers(new String[] { null, "1", "2",
1167: "3" }, true);
1168:
1169: // createSequenceResponse plus 3 partial responses
1170:
1171: mf.verifyMessages(4, false);
1172: expectedActions = new String[] {
1173: RMConstants.getCreateSequenceResponseAction(),
1174: RMConstants.getSequenceAcknowledgmentAction(),
1175: RMConstants.getSequenceAcknowledgmentAction(),
1176: RMConstants.getSequenceAcknowledgmentAction() };
1177: mf.verifyActions(expectedActions, false);
1178: mf.verifyMessageNumbers(new String[] { null, null,
1179: null, null }, false);
1180: mf.verifyAcknowledgements(new boolean[] { false, true,
1181: true, true }, false);
1182:
1183: }
1184: } finally {
1185: for (int i = 0; i < clients.length; i++) {
1186: greeter = clients[i].greeter;
1187: greeterBus = clients[i].greeterBus;
1188: stopGreeter();
1189: }
1190: greeter = null;
1191: }
1192: }
1193:
1194: @Test
1195: public void testMultiClientTwoway() throws Exception {
1196: if (!doTestMultiClientTwoway) {
1197: return;
1198: }
1199:
1200: SpringBusFactory bf = new SpringBusFactory();
1201: String cfgResource = "org/apache/cxf/systest/ws/rm/rminterceptors.xml";
1202: initControl(bf, cfgResource);
1203:
1204: class ClientThread extends Thread {
1205:
1206: Greeter greeter;
1207: Bus greeterBus;
1208: InMessageRecorder inRecorder;
1209: OutMessageRecorder outRecorder;
1210: String id;
1211:
1212: ClientThread(SpringBusFactory bf, String cfgResource, int n) {
1213: SequenceTest.this .initGreeter(bf, cfgResource, true,
1214: null);
1215: greeter = SequenceTest.this .greeter;
1216: greeterBus = SequenceTest.this .greeterBus;
1217: inRecorder = SequenceTest.this .inRecorder;
1218: outRecorder = SequenceTest.this .outRecorder;
1219: id = "client " + n;
1220: }
1221:
1222: public void run() {
1223: greeter.greetMe(id + ": a");
1224: greeter.greetMe(id + ": b");
1225: greeter.greetMe(id + ": c");
1226:
1227: // three application messages plus createSequence
1228:
1229: awaitMessages(4, 8);
1230: }
1231: }
1232:
1233: ClientThread clients[] = new ClientThread[2];
1234:
1235: try {
1236: for (int i = 0; i < clients.length; i++) {
1237: clients[i] = new ClientThread(bf, cfgResource, i);
1238: }
1239:
1240: for (int i = 0; i < clients.length; i++) {
1241: clients[i].start();
1242: }
1243:
1244: for (int i = 0; i < clients.length; i++) {
1245: clients[i].join();
1246: MessageFlow mf = new MessageFlow(clients[i].outRecorder
1247: .getOutboundMessages(), clients[i].inRecorder
1248: .getInboundMessages());
1249:
1250: mf.verifyMessages(4, true);
1251: String[] expectedActions = new String[] {
1252: RMConstants.getCreateSequenceAction(),
1253: GREETME_ACTION, GREETME_ACTION, GREETME_ACTION };
1254: mf.verifyActions(expectedActions, true);
1255: mf.verifyMessageNumbers(new String[] { null, "1", "2",
1256: "3" }, true);
1257: mf.verifyLastMessage(new boolean[] { false, false,
1258: false, false }, true);
1259: mf.verifyAcknowledgements(new boolean[] { false, false,
1260: true, true }, true);
1261:
1262: // createSequenceResponse plus 3 greetMeResponse messages plus
1263: // one partial response for each of the four messages
1264: // the first partial response should no include an acknowledgement, the other three should
1265:
1266: mf.verifyMessages(8, false);
1267: mf.verifyPartialResponses(4, new boolean[4]);
1268:
1269: mf.purgePartialResponses();
1270:
1271: expectedActions = new String[] {
1272: RMConstants.getCreateSequenceResponseAction(),
1273: GREETME_RESPONSE_ACTION,
1274: GREETME_RESPONSE_ACTION,
1275: GREETME_RESPONSE_ACTION };
1276: mf.verifyActions(expectedActions, false);
1277: mf.verifyMessageNumbers(new String[] { null, "1", "2",
1278: "3" }, false);
1279: mf.verifyLastMessage(new boolean[4], false);
1280: mf.verifyAcknowledgements(new boolean[] { false, true,
1281: true, true }, false);
1282:
1283: }
1284: } finally {
1285: for (int i = 0; i < clients.length; i++) {
1286: greeter = clients[i].greeter;
1287: greeterBus = clients[i].greeterBus;
1288: stopGreeter();
1289: }
1290: greeter = null;
1291: }
1292: }
1293:
1294: @Test
1295: public void testServerSideMessageLoss() throws Exception {
1296: if (!doTestServerSideMessageLoss) {
1297: return;
1298: }
1299: init("org/apache/cxf/systest/ws/rm/message-loss-server.xml",
1300: true);
1301:
1302: // avoid client side message loss
1303: List<Interceptor> outInterceptors = greeterBus
1304: .getOutInterceptors();
1305: for (Interceptor i : outInterceptors) {
1306: if (i.getClass().equals(MessageLossSimulator.class)) {
1307: outInterceptors.remove(i);
1308: break;
1309: }
1310: }
1311: // avoid client side resends
1312: greeterBus.getExtension(RMManager.class).getRMAssertion()
1313: .getBaseRetransmissionInterval().setMilliseconds(
1314: new BigInteger("60000"));
1315:
1316: greeter.greetMe("one");
1317: greeter.greetMe("two");
1318:
1319: // outbound: CreateSequence and two greetMe messages
1320:
1321: awaitMessages(3, 6);
1322:
1323: MessageFlow mf = new MessageFlow(outRecorder
1324: .getOutboundMessages(), inRecorder.getInboundMessages());
1325:
1326: mf.verifyMessages(3, true);
1327: String[] expectedActions = new String[] {
1328: RMConstants.getCreateSequenceAction(), GREETME_ACTION,
1329: GREETME_ACTION };
1330: mf.verifyActions(expectedActions, true);
1331: mf.verifyMessageNumbers(new String[] { null, "1", "2" }, true);
1332: mf.verifyLastMessage(new boolean[] { false, false, false },
1333: true);
1334: mf.verifyAcknowledgements(new boolean[] { false, false, true },
1335: true);
1336:
1337: // createSequenceResponse plus 2 greetMeResponse messages plus
1338: // one partial response for each of the four messages
1339: // the first partial response should no include an acknowledgement, the other three should
1340:
1341: mf.verifyMessages(6, false);
1342: mf.verifyPartialResponses(3, new boolean[3]);
1343:
1344: mf.purgePartialResponses();
1345:
1346: expectedActions = new String[] {
1347: RMConstants.getCreateSequenceResponseAction(),
1348: GREETME_RESPONSE_ACTION, GREETME_RESPONSE_ACTION };
1349: mf.verifyActions(expectedActions, false);
1350: mf.verifyMessageNumbers(new String[] { null, "1", "2" }, false);
1351: mf.verifyLastMessage(new boolean[3], false);
1352: mf.verifyAcknowledgements(new boolean[] { false, true, true },
1353: false);
1354: }
1355:
1356: @Test
1357: public void testTerminateOnShutdown() throws Exception {
1358: if (!doTestTerminateOnShutdown) {
1359: return;
1360: }
1361: init("org/apache/cxf/systest/ws/rm/terminate-on-shutdown.xml",
1362: true);
1363:
1364: greeter.greetMeOneWay("neutrophil");
1365: greeter.greetMeOneWay("basophil");
1366: greeter.greetMeOneWay("eosinophil");
1367: stopGreeter();
1368:
1369: awaitMessages(6, 8);
1370: MessageFlow mf = new MessageFlow(outRecorder
1371: .getOutboundMessages(), inRecorder.getInboundMessages());
1372:
1373: mf.verifyMessages(6, true);
1374: String[] expectedActions = new String[] {
1375: RMConstants.getCreateSequenceAction(),
1376: GREETMEONEWAY_ACTION, GREETMEONEWAY_ACTION,
1377: GREETMEONEWAY_ACTION,
1378: RMConstants.getLastMessageAction(),
1379: RMConstants.getTerminateSequenceAction() };
1380: mf.verifyActions(expectedActions, true);
1381: mf.verifyMessageNumbers(new String[] { null, "1", "2", "3",
1382: "4", null }, true);
1383:
1384: // inbound: CreateSequenceResponse, out-of-band SequenceAcknowledgement
1385: // plus 6 partial responses
1386:
1387: mf.verifyMessages(8, false);
1388: mf.verifyMessageNumbers(new String[8], false);
1389:
1390: mf.verifyPartialResponses(6);
1391: mf.purgePartialResponses();
1392:
1393: expectedActions = new String[] {
1394: RMConstants.getCreateSequenceResponseAction(),
1395: RMConstants.getSequenceAckAction() };
1396: mf.verifyActions(expectedActions, false);
1397: mf.verifyAcknowledgements(new boolean[] { false, true }, false);
1398:
1399: }
1400:
1401: // --- test utilities ---
1402:
1403: private void init(String cfgResource) {
1404: init(cfgResource, false);
1405: }
1406:
1407: private void init(String cfgResource, boolean useDecoupledEndpoint) {
1408: init(cfgResource, useDecoupledEndpoint, null);
1409: }
1410:
1411: private void init(String cfgResource, boolean useDecoupledEndpoint,
1412: Executor executor) {
1413:
1414: SpringBusFactory bf = new SpringBusFactory();
1415: initControl(bf, cfgResource);
1416: initGreeter(bf, cfgResource, useDecoupledEndpoint, executor);
1417: }
1418:
1419: private void initControl(SpringBusFactory bf, String cfgResource) {
1420: controlBus = bf.createBus();
1421: BusFactory.setDefaultBus(controlBus);
1422:
1423: ControlService cs = new ControlService();
1424: control = cs.getControlPort();
1425:
1426: assertTrue("Failed to start greeter", control
1427: .startGreeter(cfgResource));
1428: }
1429:
1430: private void initGreeter(SpringBusFactory bf, String cfgResource,
1431: boolean useDecoupledEndpoint, Executor executor) {
1432: greeterBus = bf.createBus(cfgResource);
1433: BusFactory.setDefaultBus(greeterBus);
1434: LOG.fine("Initialised greeter bus with configuration: "
1435: + cfgResource);
1436:
1437: outRecorder = new OutMessageRecorder();
1438: greeterBus.getOutInterceptors().add(outRecorder);
1439: inRecorder = new InMessageRecorder();
1440: greeterBus.getInInterceptors().add(inRecorder);
1441:
1442: GreeterService gs = new GreeterService();
1443:
1444: if (null != executor) {
1445: gs.setExecutor(executor);
1446: }
1447:
1448: greeter = gs.getGreeterPort();
1449: LOG.fine("Created greeter client.");
1450:
1451: ConnectionHelper.setKeepAliveConnection(greeter, true);
1452:
1453: if (!useDecoupledEndpoint) {
1454: return;
1455: }
1456:
1457: // programatically configure decoupled endpoint that is guaranteed to
1458: // be unique across all test cases
1459:
1460: decoupledEndpointPort--;
1461: decoupledEndpoint = "http://localhost:" + decoupledEndpointPort
1462: + "/decoupled_endpoint";
1463:
1464: Client c = ClientProxy.getClient(greeter);
1465: HTTPConduit hc = (HTTPConduit) (c.getConduit());
1466: HTTPClientPolicy cp = hc.getClient();
1467: cp.setDecoupledEndpoint(decoupledEndpoint);
1468:
1469: LOG.fine("Using decoupled endpoint: "
1470: + cp.getDecoupledEndpoint());
1471: }
1472:
1473: private void stopGreeter() {
1474: if (null != greeterBus) {
1475: greeterBus.shutdown(true);
1476: greeter = null;
1477: greeterBus = null;
1478: }
1479: }
1480:
1481: private void stopControl() {
1482: if (null != control) {
1483: assertTrue("Failed to stop greeter", control
1484: .stopGreeter(null));
1485: controlBus.shutdown(true);
1486: }
1487: }
1488:
1489: private void awaitMessages(int nExpectedOut, int nExpectedIn) {
1490: awaitMessages(nExpectedOut, nExpectedIn, 10000);
1491: }
1492:
1493: private void awaitMessages(int nExpectedOut, int nExpectedIn,
1494: int timeout) {
1495: MessageRecorder mr = new MessageRecorder(outRecorder,
1496: inRecorder);
1497: mr.awaitMessages(nExpectedOut, nExpectedIn, timeout);
1498: }
1499:
1500: private void removeRMInterceptors(List<Interceptor> interceptors) {
1501: for (Iterator<Interceptor> it = interceptors.iterator(); it
1502: .hasNext();) {
1503: Interceptor i = it.next();
1504: if (i instanceof RMSoapInterceptor
1505: || i instanceof RMOutInterceptor
1506: || i instanceof RMInInterceptor) {
1507: it.remove();
1508: }
1509: }
1510: }
1511: }
|