You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by jl...@apache.org on 2006/11/01 11:36:28 UTC
svn commit: r469850 - in /incubator/cxf/trunk/rt/frontend/jaxws/src:
main/java/org/apache/cxf/jaxws/handler/soap/
test/java/org/apache/cxf/jaxws/handler/soap/
test/java/org/apache/cxf/jaxws/handler/soap/resources/
Author: jliu
Date: Wed Nov 1 02:36:27 2006
New Revision: 469850
URL: http://svn.apache.org/viewvc?view=rev&rev=469850
Log:
SAAJ handler support: Stream SOAPMessage back to output stream if necessary for outbound invocation.
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml (with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml (with props)
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptorTest.java
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java?view=diff&rev=469850&r1=469849&r2=469850
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java Wed Nov 1 02:36:27 2006
@@ -51,10 +51,12 @@
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
-public class SOAPHandlerInterceptor extends AbstractProtocolHandlerInterceptor<SoapMessage> implements
- SoapInterceptor {
+public class SOAPHandlerInterceptor extends
+ AbstractProtocolHandlerInterceptor<SoapMessage> implements
+ SoapInterceptor {
- private static final ResourceBundle BUNDLE = BundleUtils.getBundle(SOAPHandlerInterceptor.class);
+ private static final ResourceBundle BUNDLE = BundleUtils
+ .getBundle(SOAPHandlerInterceptor.class);
public SOAPHandlerInterceptor(Binding binding) {
super(binding);
@@ -73,7 +75,7 @@
Set<QName> understood = new HashSet<QName>();
for (Handler h : getBinding().getHandlerChain()) {
if (h instanceof SOAPHandler) {
- Set<QName> headers = ((SOAPHandler)h).getHeaders();
+ Set<QName> headers = ((SOAPHandler) h).getHeaders();
if (headers != null) {
understood.addAll(headers);
}
@@ -89,7 +91,7 @@
message.setContent(OutputStream.class, cs);
if (message.getInterceptorChain().doInterceptInSubChain(message)
- && message.getContent(Exception.class) != null) {
+ && message.getContent(Exception.class) != null) {
if (message.getContent(Exception.class) instanceof Fault) {
throw (Fault)message.getContent(Exception.class);
} else {
@@ -99,25 +101,35 @@
super.handleMessage(message);
- // TODO: Stream SOAPMessage back to output stream if SOAPMessage has
- // been changed
-
try {
- cs.flush();
- AbstractCachedOutputStream.copyStream(cs.getInputStream(), os, 64 * 1024);
- cs.close();
+ // Stream SOAPMessage back to output stream if necessary
+ SOAPMessage soapMessage = message.getContent(SOAPMessage.class);
+ if (soapMessage != null) {
+ soapMessage.writeTo(os);
+ } else {
+ cs.flush();
+ AbstractCachedOutputStream csnew = (AbstractCachedOutputStream) message
+ .getContent(OutputStream.class);
+ AbstractCachedOutputStream.copyStream(csnew
+ .getInputStream(), os, 64 * 1024);
+ cs.close();
+ }
+
os.flush();
message.setContent(OutputStream.class, os);
} catch (IOException ioe) {
- throw new SoapFault(
- new org.apache.cxf.common.i18n.Message(
- "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), ioe,
- message.getVersion().getSender());
+ throw new SoapFault(new org.apache.cxf.common.i18n.Message(
+ "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), ioe,
+ message.getVersion().getSender());
+ } catch (SOAPException soape) {
+ throw new SoapFault(new org.apache.cxf.common.i18n.Message(
+ "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), soape,
+ message.getVersion().getSender());
}
} else {
super.handleMessage(message);
- //SOAPMessageContextImpl ctx = (SOAPMessageContextImpl)createProtocolMessageContext(message);
+ //SOAPMessageContextImpl ctx = (SOAPMessageContextImpl) createProtocolMessageContext(message);
//ctx.getMessage();
try {
@@ -128,17 +140,16 @@
}
// soapMessage is not null means stax reader has been consumed
- // by SAAJ,
- // we need to replace stax reader with a new stax reader built
- // from the content
- // streamed from SAAJ SOAPBody.
+ // by SAAJ, we need to replace stax reader with a new stax reader built
+ // built from the content streamed from SAAJ SOAPBody.
SOAPBody body = soapMessage.getSOAPBody();
CachedStream outStream = new CachedStream();
XMLUtils.writeTo(body, outStream);
XMLStreamReader reader = null;
- reader = XMLInputFactory.newInstance().createXMLStreamReader(outStream.getInputStream());
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(
+ outStream.getInputStream());
// skip the start element of soap body.
if (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
reader.getName();
@@ -146,20 +157,17 @@
reader.next();
message.setContent(XMLStreamReader.class, reader);
} catch (IOException ioe) {
- throw new SoapFault(
- new org.apache.cxf.common.i18n.Message(
- "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), ioe,
- message.getVersion().getSender());
+ throw new SoapFault(new org.apache.cxf.common.i18n.Message(
+ "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), ioe,
+ message.getVersion().getSender());
} catch (SOAPException soape) {
- throw new SoapFault(
- new org.apache.cxf.common.i18n.Message(
- "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), soape,
- message.getVersion().getSender());
+ throw new SoapFault(new org.apache.cxf.common.i18n.Message(
+ "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), soape,
+ message.getVersion().getSender());
} catch (XMLStreamException e) {
- throw new SoapFault(
- new org.apache.cxf.common.i18n.Message(
- "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), e,
- message.getVersion().getSender());
+ throw new SoapFault(new org.apache.cxf.common.i18n.Message(
+ "SOAPHANDLERINTERCEPTOR_EXCEPTION", BUNDLE), e, message
+ .getVersion().getSender());
}
}
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptorTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptorTest.java?view=diff&rev=469850&r1=469849&r2=469850
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptorTest.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptorTest.java Wed Nov 1 02:36:27 2006
@@ -40,6 +40,7 @@
import junit.framework.TestCase;
import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.InterceptorChain;
import org.apache.cxf.io.AbstractCachedOutputStream;
import org.apache.cxf.jaxws.handler.HandlerChainInvoker;
@@ -50,6 +51,7 @@
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.notNull;
import static org.easymock.classextension.EasyMock.createNiceControl;
public class SOAPHandlerInterceptorTest extends TestCase {
@@ -60,7 +62,9 @@
public void tearDown() {
}
- public void xtestInterceptSuccessOutBound() {
+ // SAAJ tree is created on demand. SAAJ wont be created without
+ // the calling of SOAPMessageContext.getMessage().
+ public void testNoCallToGetMessageOutBound() throws Exception {
List<Handler> list = new ArrayList<Handler>();
list.add(new SOAPHandler<SOAPMessageContext>() {
public boolean handleMessage(SOAPMessageContext smc) {
@@ -79,29 +83,111 @@
}
});
HandlerChainInvoker invoker = new HandlerChainInvoker(list);
-
+
IMocksControl control = createNiceControl();
Binding binding = control.createMock(Binding.class);
SoapMessage message = control.createMock(SoapMessage.class);
Exchange exchange = control.createMock(Exchange.class);
InterceptorChain chain = control.createMock(InterceptorChain.class);
+
expect(chain.doInterceptInSubChain(isA(Message.class))).andReturn(true);
-
expect(message.getExchange()).andReturn(exchange).anyTimes();
-
expect(message.getInterceptorChain()).andReturn(chain);
-
expect(exchange.get(HandlerChainInvoker.class)).andReturn(invoker);
+ // This is to set direction to outbound
+ expect(exchange.getOutMessage()).andReturn(message);
+
+ CachedStream originalEmptyOs = new CachedStream();
+ SOAPMessage soapMessage = preparemSOAPMessage("resources/greetMeRpcLitResp.xml");
+ CachedStream os = prepareOutputStreamFromSOAPMessage(soapMessage);
+ expect(message.getContent(OutputStream.class)).andReturn(
+ originalEmptyOs);
+ expect(message.getContent(OutputStream.class)).andReturn(os);
+ control.replay();
+
+ SOAPHandlerInterceptor li = new SOAPHandlerInterceptor(binding);
+ li.handleMessage(message);
+ control.verify();
+
+ // the content of outputStream should remain unchanged.
+ CachedStream expectedOs = prepareOutputStreamFromResource("resources/greetMeRpcLitResp.xml");
+ assertTrue("the content of os should remain unchanged",
+ compareInputStream(expectedOs.getInputStream(), originalEmptyOs
+ .getInputStream()));
+ }
+
+ // SAAJ tree is created on if SOAPMessageContext.getMessage() is
+ // called. Any changes to SOAPMessage should be streamed back to
+ // outputStream
+ public void testSOAPBodyChangedOutBound() throws Exception {
+ List<Handler> list = new ArrayList<Handler>();
+ list.add(new SOAPHandler<SOAPMessageContext>() {
+ public boolean handleMessage(SOAPMessageContext smc) {
+ Boolean outboundProperty = (Boolean) smc
+ .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outboundProperty.booleanValue()) {
+ try {
+ SOAPMessage message = smc.getMessage();
+ message = preparemSOAPMessage("resources/greetMeRpcLitRespChanged.xml");
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ }
+ return true;
+ }
+
+ public boolean handleFault(SOAPMessageContext smc) {
+ return true;
+ }
+
+ public Set<QName> getHeaders() {
+ return null;
+ }
+
+ public void close(MessageContext messageContext) {
+ }
+ });
+ HandlerChainInvoker invoker = new HandlerChainInvoker(list);
+
+ IMocksControl control = createNiceControl();
+ Binding binding = control.createMock(Binding.class);
+ SoapMessage message = control.createMock(SoapMessage.class);
+ Exchange exchange = control.createMock(Exchange.class);
+ InterceptorChain chain = control.createMock(InterceptorChain.class);
+
+ expect(chain.doInterceptInSubChain(isA(Message.class))).andReturn(true);
+ expect(message.get(notNull())).andReturn(true).anyTimes();
+ expect(message.keySet()).andReturn(new HashSet()).anyTimes();
+ expect(message.getExchange()).andReturn(exchange).anyTimes();
+ expect(message.getInterceptorChain()).andReturn(chain);
+ expect(exchange.get(HandlerChainInvoker.class)).andReturn(invoker)
+ .anyTimes();
+ // message.getExchange().get(HandlerChainInvoker.class);
+
+ // This is to set direction to outbound
expect(exchange.getOutMessage()).andReturn(message);
- expect(message.getContent(OutputStream.class)).andReturn(new CachedStream());
+
+ CachedStream originalEmptyOs = new CachedStream();
+ SOAPMessage soapMessage = preparemSOAPMessage("resources/greetMeRpcLitResp.xml");
+ expect(message.getContent(SOAPMessage.class)).andReturn(soapMessage);
+ SOAPMessage soapMessageChanged = preparemSOAPMessage("resources/greetMeRpcLitRespChanged.xml");
+ expect(message.getContent(SOAPMessage.class)).andReturn(
+ soapMessageChanged);
+ expect(message.getContent(OutputStream.class)).andReturn(
+ originalEmptyOs);
control.replay();
SOAPHandlerInterceptor li = new SOAPHandlerInterceptor(binding);
li.handleMessage(message);
control.verify();
+
+ // the content of outputStream should remain unchanged.
+ CachedStream expectedOs = prepareOutputStreamFromResource("resources/greetMeRpcLitRespChanged.xml");
+ assertTrue("the content of os should have changed", compareInputStream(
+ expectedOs.getInputStream(), originalEmptyOs.getInputStream()));
}
- public void testInterceptSuccessInBound() throws Exception {
+ public void xtestInterceptSuccessInBound() throws Exception {
List<Handler> list = new ArrayList<Handler>();
list.add(new SOAPHandler<SOAPMessageContext>() {
public boolean handleMessage(SOAPMessageContext smc) {
@@ -120,13 +206,14 @@
}
});
HandlerChainInvoker invoker = new HandlerChainInvoker(list);
-
+
IMocksControl control = createNiceControl();
Binding binding = control.createMock(Binding.class);
SoapMessage message = control.createMock(SoapMessage.class);
Exchange exchange = control.createMock(Exchange.class);
InterceptorChain chain = control.createMock(InterceptorChain.class);
- InputStream is = this.getClass().getResourceAsStream("resources/greetMeRpcLitReq.xml");
+ InputStream is = this.getClass().getResourceAsStream(
+ "resources/greetMeRpcLitReq.xml");
SOAPMessage soapMessage = null;
try {
MessageFactory factory = MessageFactory.newInstance();
@@ -136,10 +223,9 @@
throw e;
}
- //expect(chain.doInterceptInSubChain(isA(Message.class))).andReturn(true);
- expect(message.getExchange()).andReturn(exchange).anyTimes();
- //expect(message.getInterceptorChain()).andReturn(chain);
+ expect(message.getExchange()).andReturn(exchange).anyTimes();
expect(exchange.get(HandlerChainInvoker.class)).andReturn(invoker);
+ // This is to set direction to inbound
expect(exchange.getOutMessage()).andReturn(null);
expect(message.getContent(SOAPMessage.class)).andReturn(soapMessage);
control.replay();
@@ -148,7 +234,7 @@
li.handleMessage(message);
control.verify();
}
-
+
public void testgetUnderstoodHeadersReturnsNull() {
List<Handler> list = new ArrayList<Handler>();
list.add(new SOAPHandler<SOAPMessageContext>() {
@@ -184,7 +270,42 @@
assertNotNull(understood);
assertTrue(understood.isEmpty());
}
-
+
+ private boolean compareInputStream(InputStream os1, InputStream os2) throws Exception {
+ if (os1.available() != os2.available()) {
+ return false;
+ }
+ for (int i = 0; i < os1.available(); i++) {
+ if (os1.read() != os2.read()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private SOAPMessage preparemSOAPMessage(String resouceName) throws Exception {
+ InputStream is = this.getClass().getResourceAsStream(resouceName);
+ SOAPMessage soapMessage = null;
+ MessageFactory factory = MessageFactory.newInstance();
+ MimeHeaders mhs = null;
+ soapMessage = factory.createMessage(mhs, is);
+ return soapMessage;
+ }
+
+ private CachedStream prepareOutputStreamFromResource(String resouceName) throws Exception {
+ SOAPMessage soapMessage = preparemSOAPMessage(resouceName);
+ CachedStream os = new CachedStream();
+ soapMessage.writeTo(os);
+ return os;
+ }
+
+ private CachedStream prepareOutputStreamFromSOAPMessage(
+ SOAPMessage soapMessage) throws Exception {
+ CachedStream os = new CachedStream();
+ soapMessage.writeTo(os);
+ return os;
+ }
+
private class CachedStream extends AbstractCachedOutputStream {
protected void doFlush() throws IOException {
currentStream.flush();
Added: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml?view=auto&rev=469850
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml Wed Nov 1 02:36:27 2006
@@ -0,0 +1,33 @@
+<?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-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <SOAP-ENV:Body>
+ <ns1:sendReceiveDataResponse xmlns:ns1="http://apache.org/hello_world_rpclit">
+ <out xmlns:ns5="http://apache.org/hello_world_rpclit/types">
+ <ns5:elem1>return is element 1</ns5:elem1>
+ <ns5:elem2>return is element 2</ns5:elem2>
+ <ns5:elem3>42</ns5:elem3>
+ </out>
+ </ns1:sendReceiveDataResponse>
+ </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>
+
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitResp.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Added: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml?view=auto&rev=469850
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml Wed Nov 1 02:36:27 2006
@@ -0,0 +1,33 @@
+<?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-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <SOAP-ENV:Body>
+ <ns1:sendReceiveDataResponse xmlns:ns1="http://apache.org/hello_world_rpclit">
+ <out xmlns:ns5="http://apache.org/hello_world_rpclit/types">
+ <ns5:elem1>return is element 2</ns5:elem1>
+ <ns5:elem2>return is element 1</ns5:elem2>
+ <ns5:elem3>100</ns5:elem3>
+ </out>
+ </ns1:sendReceiveDataResponse>
+ </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>
+
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/handler/soap/resources/greetMeRpcLitRespChanged.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml