You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2014/02/13 10:43:25 UTC
svn commit: r1567873 - in /cxf/trunk/rt/frontend/jaxws/src:
main/java/org/apache/cxf/jaxws/ test/java/org/apache/cxf/jaxws/dispatch/
Author: ffang
Date: Thu Feb 13 09:43:25 2014
New Revision: 1567873
URL: http://svn.apache.org/r1567873
Log:
[CXF-5550]CXF JAX-WS frontend DispatchImpl ignores setting of MessageContext.WSDL_OPERATION
Added:
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchOpTest.java
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchTest.wsdl
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationRequest.xml
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationResponse.xml
Modified:
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
Modified: cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java?rev=1567873&r1=1567872&r2=1567873&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java Thu Feb 13 09:43:25 2014
@@ -308,9 +308,12 @@ public class DispatchImpl<T> implements
QName opName = (QName)getRequestContext().get(MessageContext.WSDL_OPERATION);
boolean findDispatchOp = Boolean.TRUE.equals(getRequestContext().get("find.dispatch.operation"));
+ boolean hasOpName;
if (opName == null) {
+ hasOpName = false;
opName = isOneWay ? INVOKE_ONEWAY_QNAME : INVOKE_QNAME;
} else {
+ hasOpName = true;
BindingOperationInfo bop = client.getEndpoint().getBinding()
.getBindingInfo().getOperation(opName);
if (bop == null) {
@@ -340,10 +343,10 @@ public class DispatchImpl<T> implements
}
}
}
- Map<String, QName> payloadOPMap =
- createPayloadEleOpNameMap(client.getEndpoint().getBinding().getBindingInfo());
+ Map<String, QName> payloadOPMap = createPayloadEleOpNameMap(
+ client.getEndpoint().getBinding().getBindingInfo(), hasOpName);
if (findDispatchOp && !payloadOPMap.isEmpty()) {
- String payloadElementName = null;
+ QName payloadElementName = null;
if (obj instanceof javax.xml.transform.Source) {
XMLStreamReader reader = null;
try {
@@ -367,7 +370,24 @@ public class DispatchImpl<T> implements
}
if (payloadElementName != null) {
- QName dispatchedOpName = payloadOPMap.get(payloadElementName);
+ if (hasOpName) {
+ // Verify the payload element against the given operation name.
+ // This allows graceful handling of non-standard WSDL definitions
+ // where different operations have the same payload element.
+ QName expectedElementName = payloadOPMap.get(opName.toString());
+ if (expectedElementName == null || !expectedElementName.toString().equals(
+ payloadElementName.toString())) {
+ // Verification of the provided operation name failed.
+ // Resolve the operation name from the payload element.
+ hasOpName = false;
+ payloadOPMap = createPayloadEleOpNameMap(
+ client.getEndpoint().getBinding().getBindingInfo(), hasOpName);
+ }
+ }
+ QName dispatchedOpName = null;
+ if (!hasOpName) {
+ dispatchedOpName = payloadOPMap.get(payloadElementName.toString());
+ }
if (null != dispatchedOpName) {
BindingOperationInfo dbop = client.getEndpoint().getBinding().getBindingInfo()
.getOperation(dispatchedOpName);
@@ -432,7 +452,7 @@ public class DispatchImpl<T> implements
return client;
}
- private String getPayloadElementName(Element ele) {
+ private QName getPayloadElementName(Element ele) {
XMLStreamReader xmlreader = StaxUtils.createXMLStreamReader(ele);
DepthXMLStreamReader reader = new DepthXMLStreamReader(xmlreader);
try {
@@ -440,14 +460,14 @@ public class DispatchImpl<T> implements
StaxUtils.skipToStartOfElement(reader);
- return reader.getName().toString();
+ return reader.getName();
}
if (this.mode == Service.Mode.MESSAGE) {
StaxUtils.skipToStartOfElement(reader);
StaxUtils.toNextTag(reader,
new QName(ele.getNamespaceURI(), "Body"));
reader.nextTag();
- return reader.getName().toString();
+ return reader.getName();
}
} catch (XMLStreamException e) {
// ignore
@@ -457,12 +477,12 @@ public class DispatchImpl<T> implements
}
- private String getPayloadElementName(SOAPMessage soapMessage) {
+ private QName getPayloadElementName(SOAPMessage soapMessage) {
try {
// we only care about the first element node, not text nodes
Element element = DOMUtils.getFirstElement(SAAJUtils.getBody(soapMessage));
if (element != null) {
- return DOMUtils.getElementQName(element).toString();
+ return DOMUtils.getElementQName(element);
}
} catch (Exception e) {
//ignore
@@ -470,7 +490,7 @@ public class DispatchImpl<T> implements
return null;
}
- private String getPayloadElementName(Object object) {
+ private QName getPayloadElementName(Object object) {
JAXBDataBinding dataBinding = new JAXBDataBinding();
dataBinding.setContext(context);
DataWriter<XMLStreamWriter> dbwriter = dataBinding.createWriter(XMLStreamWriter.class);
@@ -488,7 +508,7 @@ public class DispatchImpl<T> implements
StaxUtils.skipToStartOfElement(reader);
- return reader.getName().toString();
+ return reader.getName();
}
} catch (XMLStreamException e) {
@@ -497,14 +517,14 @@ public class DispatchImpl<T> implements
try {
StaxUtils.close(reader);
} catch (XMLStreamException e) {
- // ignore
+ // ignore
}
StaxUtils.close(resultWriter);
}
return null;
}
- private Map<String, QName> createPayloadEleOpNameMap(BindingInfo bindingInfo) {
+ private Map<String, QName> createPayloadEleOpNameMap(BindingInfo bindingInfo, boolean reverseMapping) {
Map<String, QName> payloadElementMap = new java.util.HashMap<String, QName>();
// assume a document binding style, which is default according to W3C spec on WSDL
String bindingStyle = "document";
@@ -526,12 +546,17 @@ public class DispatchImpl<T> implements
&& !bop.getOperationInfo().getInput().getMessageParts().isEmpty()) {
QName qn = bop.getOperationInfo().getInput().getMessagePartByIndex(0)
.getElementQName();
- payloadElementMap.put(qn.toString(), bop.getOperationInfo().getName());
+ QName op = bop.getOperationInfo().getName();
+ if (reverseMapping) {
+ payloadElementMap.put(op.toString(), qn);
+ } else {
+ payloadElementMap.put(qn.toString(), op);
+ }
}
} else if ("rpc".equals(operationStyle)) {
// if rpc
- payloadElementMap.put(bop.getOperationInfo().getName().toString(), bop.getOperationInfo()
- .getName());
+ QName op = bop.getOperationInfo().getName();
+ payloadElementMap.put(op.toString(), op);
}
}
}
@@ -541,5 +566,4 @@ public class DispatchImpl<T> implements
public void close() throws IOException {
client.destroy();
}
-
}
Added: cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchOpTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchOpTest.java?rev=1567873&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchOpTest.java (added)
+++ cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchOpTest.java Thu Feb 13 09:43:25 2014
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxws.dispatch;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Service;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.soap.AddressingFeature;
+
+import org.w3c.dom.Document;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.jaxws.AbstractJaxWsTest;
+import org.apache.cxf.jaxws.DispatchImpl;
+import org.apache.cxf.jaxws.MessageReplayObserver;
+import org.apache.cxf.jaxws.ServiceImpl;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.transport.Destination;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DispatchOpTest extends AbstractJaxWsTest {
+ private final QName serviceName = new QName("http://cxf.apache.org/test/dispatch", "DispatchTest");
+
+ private final QName portName = new QName("http://cxf.apache.org/test/dispatch", "DispatchPort");
+
+ private final String address = "http://localhost:9120/SoapContext/DispatchPort";
+
+ private final QName operationName = new QName("http://cxf.apache.org/test/dispatch", "RequestResponseOperation");
+
+ private final String wsdlResource = "/org/apache/cxf/jaxws/dispatch/DispatchTest.wsdl";
+
+ private final String requestResource = "/org/apache/cxf/jaxws/dispatch/OperationRequest.xml";
+
+ private final String responseResource = "/org/apache/cxf/jaxws/dispatch/OperationResponse.xml";
+
+ private Destination d;
+
+ @Before
+ public void setUp() throws Exception {
+ EndpointInfo ei = new EndpointInfo(null, "http://schemas.xmlsoap.org/soap/http");
+ ei.setAddress(address);
+
+ d = localTransport.getDestination(ei, bus);
+ }
+
+ @Test
+ public void testResolveOperationWithSource() throws Exception {
+ ServiceImpl service =
+ new ServiceImpl(getBus(), getClass().getResource(wsdlResource), serviceName, null);
+
+ Dispatch<Source> disp = service.createDispatch(
+ portName, Source.class, Service.Mode.PAYLOAD);
+ disp.getRequestContext().put(MessageContext.WSDL_OPERATION, operationName);
+ disp.getRequestContext().put(Dispatch.ENDPOINT_ADDRESS_PROPERTY, address);
+
+ d.setMessageObserver(new MessageReplayObserver(responseResource));
+
+ BindingOperationVerifier bov = new BindingOperationVerifier();
+ ((DispatchImpl<?>)disp).getClient().getOutInterceptors().add(bov);
+
+ Document doc = StaxUtils.read(getResourceAsStream(requestResource));
+ DOMSource source = new DOMSource(doc);
+ Source res = disp.invoke(source);
+ assertNotNull(res);
+
+ BindingOperationInfo boi = bov.getBindingOperationInfo();
+ assertNotNull(boi);
+
+ assertEquals(operationName, boi.getName());
+ }
+
+ @Test
+ public void testResolveOperationWithSourceAndWSA() throws Exception {
+ ServiceImpl service =
+ new ServiceImpl(getBus(), getClass().getResource(wsdlResource),
+ serviceName, null, new AddressingFeature());
+
+ Dispatch<Source> disp = service.createDispatch(
+ portName, Source.class, Service.Mode.PAYLOAD);
+ disp.getRequestContext().put(MessageContext.WSDL_OPERATION, operationName);
+ disp.getRequestContext().put(Dispatch.ENDPOINT_ADDRESS_PROPERTY, address);
+
+ d.setMessageObserver(new MessageReplayObserver(responseResource));
+
+ BindingOperationVerifier bov = new BindingOperationVerifier();
+ ((DispatchImpl<?>)disp).getClient().getOutInterceptors().add(bov);
+
+ Document doc = StaxUtils.read(getResourceAsStream(requestResource));
+ DOMSource source = new DOMSource(doc);
+ Source res = disp.invoke(source);
+ assertNotNull(res);
+
+ BindingOperationInfo boi = bov.getBindingOperationInfo();
+ assertNotNull(boi);
+
+ assertEquals(operationName, boi.getName());
+ }
+
+ private static class BindingOperationVerifier extends AbstractSoapInterceptor {
+ BindingOperationInfo boi;
+ public BindingOperationVerifier() {
+ super(Phase.POST_LOGICAL);
+ }
+
+ public void handleMessage(SoapMessage message) throws Fault {
+ boi = message.getExchange().getBindingOperationInfo();
+ }
+
+ public BindingOperationInfo getBindingOperationInfo() {
+ return boi;
+ }
+ }
+}
Added: cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchTest.wsdl
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchTest.wsdl?rev=1567873&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchTest.wsdl (added)
+++ cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchTest.wsdl Thu Feb 13 09:43:25 2014
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<definitions targetNamespace="http://cxf.apache.org/test/dispatch"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:tns="http://cxf.apache.org/test/dispatch"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <types>
+ <xsd:schema targetNamespace="http://cxf.apache.org/test/dispatch" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="OperationRequest">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="in" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="OperationResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="out" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ </types>
+ <message name="opRequestMsg">
+ <part element="tns:OperationRequest" name="body"/>
+ </message>
+ <message name="opResponseMsg">
+ <part element="tns:OperationResponse" name="body"/>
+ </message>
+ <portType name="DispatchTestInterface">
+ <operation name="RequestResponseOperation">
+ <input message="tns:opRequestMsg"/>
+ <output message="tns:opResponseMsg"/>
+ </operation>
+ <operation name="OneWayOperation">
+ <input message="tns:opRequestMsg"/>
+ </operation>
+ </portType>
+ <wsdl:service name="DispatchTest">
+ <wsdl:port binding="tns:localhostBinding" name="DispatchPort">
+ <soap:address location="http://localhost:9120/SoapContext/DispatchPort"/>
+ </wsdl:port>
+ </wsdl:service>
+ <wsdl:binding name="localhostBinding" type="tns:DispatchTestInterface">
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="RequestResponseOperation">
+ <soap:operation soapAction="RequestResponseOperation"/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="OneWayOperation">
+ <soap:operation soapAction="OneWayOperation"/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ </wsdl:operation>
+ </wsdl:binding>
+</definitions>
Added: cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationRequest.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationRequest.xml?rev=1567873&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationRequest.xml (added)
+++ cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationRequest.xml Thu Feb 13 09:43:25 2014
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<OperationRequest xmlns="http://cxf.apache.org/test/dispatch">
+ <in>Dispatch Test Operation Request</in>
+</OperationRequest>
Added: cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationResponse.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationResponse.xml?rev=1567873&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationResponse.xml (added)
+++ cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/OperationResponse.xml Thu Feb 13 09:43:25 2014
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+ <soap:Body>
+ <OperationResponse xmlns="http://cxf.apache.org/test/dispatch">
+ <out>Dispatch Test Operation Response</out>
+ </OperationResponse>
+ </soap:Body>
+</soap:Envelope>