001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.systest.ws.addressing;
019:
020: import java.lang.reflect.UndeclaredThrowableException;
021: import java.net.URL;
022: import java.util.HashMap;
023: import java.util.List;
024: import java.util.Map;
025:
026: import javax.xml.bind.JAXBElement;
027: import javax.xml.namespace.QName;
028: import javax.xml.ws.BindingProvider;
029: import javax.xml.ws.ProtocolException;
030:
031: import org.apache.cxf.Bus;
032: import org.apache.cxf.BusFactory;
033: import org.apache.cxf.bus.spring.SpringBusFactory;
034: import org.apache.cxf.interceptor.Interceptor;
035: import org.apache.cxf.jaxws.ServiceImpl;
036: import org.apache.cxf.jaxws.support.ServiceDelegateAccessor;
037: import org.apache.cxf.testutil.common.AbstractClientServerTestBase;
038: import org.apache.cxf.ws.addressing.AddressingProperties;
039: import org.apache.cxf.ws.addressing.AddressingPropertiesImpl;
040: import org.apache.cxf.ws.addressing.AttributedURIType;
041: import org.apache.cxf.ws.addressing.ContextUtils;
042: import org.apache.cxf.ws.addressing.EndpointReferenceType;
043: import org.apache.cxf.ws.addressing.Names;
044: import org.apache.cxf.ws.addressing.ReferenceParametersType;
045: import org.apache.cxf.ws.addressing.soap.VersionTransformer;
046: import org.apache.cxf.wsdl.EndpointReferenceUtils;
047: import org.apache.hello_world_soap_http.BadRecordLitFault;
048: import org.apache.hello_world_soap_http.Greeter;
049: import org.apache.hello_world_soap_http.NoSuchCodeLitFault;
050: import org.apache.hello_world_soap_http.SOAPService;
051: import org.junit.After;
052: import org.junit.AfterClass;
053: import org.junit.Before;
054: import org.junit.BeforeClass;
055: import org.junit.Ignore;
056: import org.junit.Test;
057:
058: import static org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES;
059:
060: /**
061: * Tests the addition of WS-Addressing Message Addressing Properties.
062: */
063: public abstract class MAPTestBase extends AbstractClientServerTestBase
064: implements VerificationCache {
065:
066: protected static Bus staticBus;
067:
068: static final String INBOUND_KEY = "inbound";
069: static final String OUTBOUND_KEY = "outbound";
070:
071: static final QName CUSTOMER_NAME = new QName(
072: "http://example.org/customer", "CustomerKey", "customer");
073: static final String CUSTOMER_KEY = "Key#123456789";
074:
075: private static MAPVerifier mapVerifier;
076: private static HeaderVerifier headerVerifier;
077:
078: private static final QName SERVICE_NAME = new QName(
079: "http://apache.org/hello_world_soap_http",
080: "SOAPServiceAddressing");
081: private static final String NOWHERE = "http://nowhere.nada.nothing.nought:5555";
082: private static final String DECOUPLED = "http://localhost:9999/decoupled_endpoint";
083:
084: private static Map<Object, Map<String, String>> messageIDs = new HashMap<Object, Map<String, String>>();
085: protected Greeter greeter;
086: private String verified;
087:
088: @BeforeClass
089: public static void startServers() throws Exception {
090: // special case handling for WS-Addressing system test to avoid
091: // UUID related issue when server is run as separate process
092: // via maven on Win2k
093: boolean inProcess = "Windows 2000".equals(System
094: .getProperty("os.name"));
095: assertTrue("server did not launch correctly", launchServer(
096: Server.class, inProcess));
097: }
098:
099: @AfterClass
100: public static void shutdownBus() throws Exception {
101: staticBus.shutdown(true);
102: }
103:
104: private void addInterceptors(List<Interceptor> chain,
105: Interceptor[] interceptors) {
106: for (int i = 0; i < interceptors.length; i++) {
107: chain.add(interceptors[i]);
108: }
109: }
110:
111: private void removeInterceptors(List<Interceptor> chain,
112: Interceptor[] interceptors) {
113: for (int i = 0; i < interceptors.length; i++) {
114: chain.add(interceptors[i]);
115: }
116: }
117:
118: public abstract String getConfigFileName();
119:
120: @Before
121: public void setUp() throws Exception {
122: //super.setUp();
123:
124: if (staticBus == null) {
125: SpringBusFactory bf = new SpringBusFactory();
126: staticBus = bf.createBus(getConfigFileName());
127: BusFactory.setDefaultBus(staticBus);
128: }
129:
130: messageIDs.clear();
131: mapVerifier = new MAPVerifier();
132: headerVerifier = new HeaderVerifier();
133: Interceptor[] interceptors = { mapVerifier, headerVerifier };
134: addInterceptors(staticBus.getInInterceptors(), interceptors);
135: addInterceptors(staticBus.getOutInterceptors(), interceptors);
136: addInterceptors(staticBus.getOutFaultInterceptors(),
137: interceptors);
138: addInterceptors(staticBus.getInFaultInterceptors(),
139: interceptors);
140:
141: EndpointReferenceType target = EndpointReferenceUtils
142: .getEndpointReference(Server.ADDRESS);
143: ReferenceParametersType params = ContextUtils.WSA_OBJECT_FACTORY
144: .createReferenceParametersType();
145: JAXBElement<String> param = new JAXBElement<String>(
146: CUSTOMER_NAME, String.class, CUSTOMER_KEY);
147: params.getAny().add(param);
148: target.setReferenceParameters(params);
149: URL wsdl = getClass().getResource("/wsdl/hello_world.wsdl");
150: ServiceImpl serviceImpl = ServiceDelegateAccessor
151: .get(new SOAPService(wsdl, SERVICE_NAME));
152: greeter = serviceImpl.getPort(target, Greeter.class);
153:
154: mapVerifier.verificationCache = this ;
155: headerVerifier.verificationCache = this ;
156: }
157:
158: @After
159: public void tearDown() throws Exception {
160: Interceptor[] interceptors = { mapVerifier, headerVerifier };
161: removeInterceptors(staticBus.getInInterceptors(), interceptors);
162: removeInterceptors(staticBus.getOutInterceptors(), interceptors);
163: removeInterceptors(staticBus.getOutFaultInterceptors(),
164: interceptors);
165: removeInterceptors(staticBus.getInFaultInterceptors(),
166: interceptors);
167:
168: mapVerifier = null;
169: headerVerifier = null;
170: verified = null;
171: messageIDs.clear();
172: }
173:
174: //--Tests
175: @Test
176: public void testImplicitMAPs() throws Exception {
177: try {
178: String greeting = greeter.greetMe("implicit1");
179: assertEquals("unexpected response received from service",
180: "Hello implicit1", greeting);
181: checkVerification();
182: greeting = greeter.greetMe("implicit2");
183: assertEquals("unexpected response received from service",
184: "Hello implicit2", greeting);
185: checkVerification();
186: } catch (UndeclaredThrowableException ex) {
187: throw (Exception) ex.getCause();
188: }
189: }
190:
191: @Test
192: @Ignore
193: public void testExplicitMAPs() throws Exception {
194: try {
195: Map<String, Object> requestContext = ((BindingProvider) greeter)
196: .getRequestContext();
197: AddressingProperties maps = new AddressingPropertiesImpl();
198: AttributedURIType id = ContextUtils
199: .getAttributedURI("urn:uuid:12345");
200: maps.setMessageID(id);
201: requestContext.put(CLIENT_ADDRESSING_PROPERTIES, maps);
202: String greeting = greeter.greetMe("explicit1");
203: assertEquals("unexpected response received from service",
204: "Hello explicit1", greeting);
205: checkVerification();
206:
207: // the previous addition to the request context impacts
208: // on all subsequent invocations on this proxy => a duplicate
209: // message ID fault is expected
210: try {
211: greeter.greetMe("explicit2");
212: fail("expected ProtocolException on duplicate message ID");
213: } catch (ProtocolException pe) {
214: assertTrue("expected duplicate message ID failure",
215: "Duplicate Message ID urn:uuid:12345".equals(pe
216: .getMessage()));
217: checkVerification();
218: }
219:
220: // clearing the message ID ensure a duplicate is not sent
221: maps.setMessageID(null);
222: maps.setRelatesTo(ContextUtils.getRelatesTo(id.getValue()));
223: greeting = greeter.greetMe("explicit3");
224: assertEquals("unexpected response received from service",
225: "Hello explicit3", greeting);
226: } catch (UndeclaredThrowableException ex) {
227: throw (Exception) ex.getCause();
228: }
229: }
230:
231: @Test
232: @Ignore
233: public void testFaultTo() throws Exception {
234: try {
235: String greeting = greeter.greetMe("warmup");
236: assertEquals("unexpected response received from service",
237: "Hello warmup", greeting);
238: checkVerification();
239:
240: Map<String, Object> requestContext = ((BindingProvider) greeter)
241: .getRequestContext();
242: AddressingProperties maps = new AddressingPropertiesImpl();
243: maps.setReplyTo(EndpointReferenceUtils
244: .getEndpointReference(NOWHERE));
245: maps.setFaultTo(EndpointReferenceUtils
246: .getEndpointReference(DECOUPLED));
247: requestContext.put(CLIENT_ADDRESSING_PROPERTIES, maps);
248: try {
249: greeter.testDocLitFault("BadRecordLitFault");
250: fail("expected fault from service");
251: } catch (BadRecordLitFault brlf) {
252: checkVerification();
253: } catch (UndeclaredThrowableException ex) {
254: throw (Exception) ex.getCause();
255: }
256: } catch (UndeclaredThrowableException ex) {
257: throw (Exception) ex.getCause();
258: }
259: }
260:
261: @Test
262: public void testOneway() throws Exception {
263: try {
264: greeter.greetMeOneWay("implicit_oneway1");
265: checkVerification();
266: } catch (UndeclaredThrowableException ex) {
267: throw (Exception) ex.getCause();
268: }
269: }
270:
271: @Test
272: public void testApplicationFault() throws Exception {
273: try {
274: greeter.testDocLitFault("BadRecordLitFault");
275: fail("expected fault from service");
276: } catch (BadRecordLitFault brlf) {
277: //checkVerification();
278: } catch (UndeclaredThrowableException ex) {
279: throw (Exception) ex.getCause();
280: }
281: String greeting = greeter.greetMe("intra-fault");
282: assertEquals("unexpected response received from service",
283: "Hello intra-fault", greeting);
284: try {
285: greeter.testDocLitFault("NoSuchCodeLitFault");
286: fail("expected NoSuchCodeLitFault");
287: } catch (NoSuchCodeLitFault nsclf) {
288: //checkVerification();
289: } catch (UndeclaredThrowableException ex) {
290: throw (Exception) ex.getCause();
291: }
292: }
293:
294: @Test
295: public void testVersioning() throws Exception {
296: try {
297: // expect two MAPs instances versioned with 200408, i.e. for both
298: // the partial and full responses
299: mapVerifier.expectedExposedAs
300: .add(VersionTransformer.Names200408.WSA_NAMESPACE_NAME);
301: mapVerifier.expectedExposedAs
302: .add(VersionTransformer.Names200408.WSA_NAMESPACE_NAME);
303: String greeting = greeter.greetMe("versioning1");
304: assertEquals("unexpected response received from service",
305: "Hello versioning1", greeting);
306: checkVerification();
307: greeting = greeter.greetMe("versioning2");
308: assertEquals("unexpected response received from service",
309: "Hello versioning2", greeting);
310: checkVerification();
311: } catch (UndeclaredThrowableException ex) {
312: throw (Exception) ex.getCause();
313: }
314: }
315:
316: //--VerificationCache implementation
317:
318: public void put(String verification) {
319: if (verification != null) {
320: verified = verified == null ? verification : verified
321: + "; " + verification;
322: }
323: }
324:
325: //--Verification methods called by handlers
326:
327: /**
328: * Verify presence of expected MAPs.
329: *
330: * @param maps the MAPs to verify
331: * @param checkPoint the check point
332: * @return null if all expected MAPs present, otherwise an error string.
333: */
334: protected static String verifyMAPs(AddressingProperties maps,
335: Object checkPoint) {
336: if (maps == null) {
337: return "expected MAPs";
338: }
339: //String rt = maps.getReplyTo() != null ? maps.getReplyTo().getAddress().getValue() : "null";
340: //System.out.println("verifying MAPs: " + maps
341: // + " id: " + maps.getMessageID().getValue()
342: // + " to: " + maps.getTo().getValue()
343: // + " reply to: " + rt);
344: // MessageID
345: String id = maps.getMessageID().getValue();
346: if (id == null) {
347: return "expected MessageID MAP";
348: }
349: if (!id.startsWith("urn:uuid")) {
350: return "bad URN format in MessageID MAP: " + id;
351: }
352: // ensure MessageID is unique for this check point
353: Map<String, String> checkPointMessageIDs = messageIDs
354: .get(checkPoint);
355: if (checkPointMessageIDs != null) {
356: if (checkPointMessageIDs.containsKey(id)) {
357: //return "MessageID MAP duplicate: " + id;
358: return null;
359: }
360: } else {
361: checkPointMessageIDs = new HashMap<String, String>();
362: messageIDs.put(checkPoint, checkPointMessageIDs);
363: }
364: checkPointMessageIDs.put(id, id);
365: // To
366: if (maps.getTo() == null) {
367: return "expected To MAP";
368: }
369: return null;
370: }
371:
372: /**
373: * Verify presence of expected MAP headers.
374: *
375: * @param wsaHeaders a list of the wsa:* headers present in the SOAP
376: * message
377: * @param parial true if partial response
378: * @return null if all expected headers present, otherwise an error string.
379: */
380: protected static String verifyHeaders(List<String> wsaHeaders,
381: boolean partial, boolean requestLeg) {
382: //System.out.println("verifying headers: " + wsaHeaders);
383: String ret = null;
384: if (!wsaHeaders.contains(Names.WSA_MESSAGEID_NAME)) {
385: ret = "expected MessageID header";
386: }
387: if (!wsaHeaders.contains(Names.WSA_TO_NAME)) {
388: ret = "expected To header";
389: }
390:
391: if (!(wsaHeaders.contains(Names.WSA_REPLYTO_NAME) || wsaHeaders
392: .contains(Names.WSA_RELATESTO_NAME))) {
393: ret = "expected ReplyTo or RelatesTo header";
394: }
395: if (partial) {
396: if (!wsaHeaders.contains(Names.WSA_FROM_NAME)) {
397: ret = "expected From header";
398: }
399: } else {
400: // REVISIT Action missing from full response
401: //if (!wsaHeaders.contains(Names.WSA_ACTION_NAME)) {
402: // ret = "expected Action header";
403: //}
404: }
405: if (requestLeg
406: && !(wsaHeaders.contains(CUSTOMER_NAME.getLocalPart()))) {
407: ret = "expected CustomerKey header";
408: }
409: return ret;
410: }
411:
412: private void checkVerification() {
413: assertNull("MAP/Header verification failed: " + verified,
414: verified);
415: }
416: }
|