Author: ay
Date: Wed Nov 23 20:04:12 2011
New Revision: 1205558
URL: http://svn.apache.org/viewvc?rev=1205558&view=rev
Log:
[CXF-3926] supporting jaxws provider's null response handling
Added:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/InterpretNullAsOnewayProviderTest.java
(with props)
Modified:
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JAXWSMethodInvokerTest.java
Modified:
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java?rev=1205558&r1=1205557&r2=1205558&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
(original)
+++
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
Wed Nov 23 20:04:12 2011
@@ -59,6 +59,14 @@ public class JAXWSMethodInvoker extends
params = Collections.singletonList(null);
}
res = CastUtils.cast((List)super.invoke(exchange, serviceObject,
m, params));
+ if ((serviceObject instanceof Provider)
+ && Boolean.TRUE.equals(exchange.getInMessage().
+
getContextualProperty("jaxws.provider.interpretNullAsOneway"))
+ && (res != null && !res.isEmpty() && res.get(0) == null)) {
+ // treat the non-oneway call as oneway when a provider returns
null
+ res = null;
+ changeToOneway(exchange);
+ }
//update the webservice response context
updateWebServiceContext(exchange, ctx);
} catch (Fault f) {
@@ -73,5 +81,15 @@ public class JAXWSMethodInvoker extends
}
return res;
}
+
+ private void changeToOneway(Exchange exchange) {
+ exchange.setOneWay(true);
+ javax.servlet.http.HttpServletResponse httpresp =
+ (javax.servlet.http.HttpServletResponse)exchange.getInMessage().
+ get("HTTP.RESPONSE");
+ if (httpresp != null) {
+ httpresp.setStatus(202);
+ }
+ }
}
Modified:
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JAXWSMethodInvokerTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JAXWSMethodInvokerTest.java?rev=1205558&r1=1205557&r2=1205558&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JAXWSMethodInvokerTest.java
(original)
+++
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JAXWSMethodInvokerTest.java
Wed Nov 23 20:04:12 2011
@@ -19,10 +19,17 @@
package org.apache.cxf.jaxws;
+import java.lang.reflect.Method;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Provider;
+
import org.apache.cxf.continuations.SuspendedInvocationException;
import org.apache.cxf.frontend.MethodDispatcher;
import org.apache.cxf.jaxws.service.Hello;
import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.message.MessageImpl;
@@ -53,55 +60,107 @@ public class JAXWSMethodInvokerTest exte
@Test
public void testSuspendedException() throws Throwable {
- Exchange ex = EasyMock.createNiceMock(Exchange.class);
-
Exception originalException = new RuntimeException();
ContinuationService serviceObject =
new ContinuationService(originalException);
+ Method serviceMethod = ContinuationService.class.getMethod("invoke",
new Class[]{});
+
+ Exchange ex = new ExchangeImpl();
+ Message inMessage = new MessageImpl();
+ ex.setInMessage(inMessage);
+ inMessage.setExchange(ex);
+ inMessage.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
+
+ JAXWSMethodInvoker jaxwsMethodInvoker = prepareJAXWSMethodInvoker(ex,
serviceObject, serviceMethod);
+ try {
+ jaxwsMethodInvoker.invoke(ex, new MessageContentsList(new
Object[]{}));
+ fail("Suspended invocation swallowed");
+ } catch (SuspendedInvocationException suspendedEx) {
+ assertSame(suspendedEx, serviceObject.getSuspendedException());
+ assertSame(originalException, suspendedEx.getRuntimeException());
+ }
+ }
+
+ @Test
+ public void testProviderInterpretNullAsOneway() throws Throwable {
+ NullableProviderService serviceObject = new NullableProviderService();
+ Method serviceMethod =
NullableProviderService.class.getMethod("invoke", new Class[]{Source.class});
+
+ Exchange ex = new ExchangeImpl();
+ Message inMessage = new MessageImpl();
+ ex.setInMessage(inMessage);
+ inMessage.setExchange(ex);
+ inMessage.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
+
+ JAXWSMethodInvoker jaxwsMethodInvoker = prepareJAXWSMethodInvoker(ex,
serviceObject, serviceMethod);
+
+ // request-response with non-null response
+ ex.setOneWay(false);
+ MessageContentsList obj =
(MessageContentsList)jaxwsMethodInvoker.invoke(
+ ex, new MessageContentsList(new Object[]{new StreamSource()}));
+ assertEquals(1, obj.size());
+ assertNotNull(obj.get(0));
+ assertFalse(ex.isOneWay());
+
+ // oneway with non-null response
+ ex.setOneWay(true);
+ obj = (MessageContentsList)jaxwsMethodInvoker.invoke(
+ ex, new MessageContentsList(new Object[]{new StreamSource()}));
+ assertNull(obj);
+ assertTrue(ex.isOneWay());
+
+ // request-response with null response, interpretNullAsOneway disabled
+ ex.setOneWay(false);
+ serviceObject.setNullable(true);
+ obj = (MessageContentsList)jaxwsMethodInvoker.invoke(
+ ex, new MessageContentsList(new Object[]{new StreamSource()}));
+ assertEquals(1, obj.size());
+ assertNull(obj.get(0));
+ assertFalse(ex.isOneWay());
+
+ // request-response with null response, interpretNullAsOneway enabled
+ ex.setOneWay(false);
+ serviceObject.setNullable(true);
+
inMessage.setContextualProperty("jaxws.provider.interpretNullAsOneway",
Boolean.TRUE);
+ obj = (MessageContentsList)jaxwsMethodInvoker.invoke(
+ ex, new MessageContentsList(new Object[]{new StreamSource()}));
+ assertNull(obj);
+ assertTrue(ex.isOneWay());
+ }
+
+ private JAXWSMethodInvoker prepareJAXWSMethodInvoker(Exchange ex, Object
serviceObject,
+ Method serviceMethod)
throws Throwable {
EasyMock.reset(factory);
factory.create(ex);
- EasyMock.expectLastCall().andReturn(serviceObject);
+ EasyMock.expectLastCall().andReturn(serviceObject).anyTimes();
factory.release(ex, serviceObject);
- EasyMock.expectLastCall();
+ EasyMock.expectLastCall().anyTimes();
EasyMock.replay(factory);
-
- Message inMessage = new MessageImpl();
- ex.getInMessage();
- EasyMock.expectLastCall().andReturn(inMessage);
- inMessage.setExchange(ex);
- inMessage.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
-
- BindingOperationInfo boi =
EasyMock.createMock(BindingOperationInfo.class);
- ex.get(BindingOperationInfo.class);
- EasyMock.expectLastCall().andReturn(boi);
+
+ BindingOperationInfo boi = new BindingOperationInfo();
+ ex.put(BindingOperationInfo.class, boi);
Service serviceClass = EasyMock.createMock(Service.class);
- ex.get(Service.class);
- EasyMock.expectLastCall().andReturn(serviceClass);
+ serviceClass.size();
+ EasyMock.expectLastCall().andReturn(0).anyTimes();
+ ex.put(Service.class, serviceClass);
MethodDispatcher md = EasyMock.createMock(MethodDispatcher.class);
serviceClass.get(MethodDispatcher.class.getName());
- EasyMock.expectLastCall().andReturn(md);
+ EasyMock.expectLastCall().andReturn(md).anyTimes();
md.getMethod(boi);
- EasyMock.expectLastCall().andReturn(
- ContinuationService.class.getMethod("invoke", new Class[]{}));
+ EasyMock.expectLastCall().andReturn(serviceMethod).anyTimes();
- EasyMock.replay(ex);
EasyMock.replay(md);
EasyMock.replay(serviceClass);
-
- JAXWSMethodInvoker jaxwsMethodInvoker = new
JAXWSMethodInvoker(factory);
- try {
- jaxwsMethodInvoker.invoke(ex, new MessageContentsList(new
Object[]{}));
- fail("Suspended invocation swallowed");
- } catch (SuspendedInvocationException suspendedEx) {
- assertSame(suspendedEx, serviceObject.getSuspendedException());
- assertSame(originalException, suspendedEx.getRuntimeException());
- }
-
+
+ // initialize the contextCache
+ ex.getInMessage().getContextualProperty("dummy");
+
+ return new JAXWSMethodInvoker(factory);
}
-
+
public static class ContinuationService {
private RuntimeException ex;
@@ -117,4 +176,16 @@ public class JAXWSMethodInvokerTest exte
return ex;
}
}
+
+ public static class NullableProviderService implements Provider<Source> {
+ private boolean nullable;
+
+ public void setNullable(boolean nullable) {
+ this.nullable = nullable;
+ }
+
+ public Source invoke(Source request) {
+ return nullable ? null : request;
+ }
+ }
}
Added:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/InterpretNullAsOnewayProviderTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/InterpretNullAsOnewayProviderTest.java?rev=1205558&view=auto
==============================================================================
---
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/InterpretNullAsOnewayProviderTest.java
(added)
+++
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/InterpretNullAsOnewayProviderTest.java
Wed Nov 23 20:04:12 2011
@@ -0,0 +1,117 @@
+/**
+ * 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.systest.provider;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import javax.xml.transform.Source;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Provider;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Testing the null response behavior of jaxws provider (jaxws 2.2 section
5.1.1)
+ */
+public class InterpretNullAsOnewayProviderTest extends
AbstractBusClientServerTestBase {
+ public static final String PORT = allocatePort(Server.class);
+
+ private static final String ADDRESS1 = "http://localhost:" + PORT +
"/test/nullable1";
+ private static final String ADDRESS2 = "http://localhost:" + PORT +
"/test/nullable2";
+
+ public static class Server extends AbstractBusTestServerBase {
+
+ protected void run() {
+ // endpoint not interpreting null as oneway
+ NullProviderService servant1 = new NullProviderService();
+ Endpoint ep1 = Endpoint.publish(ADDRESS1, servant1);
+ assertNotNull("endpoint published", ep1);
+
+ // endpoint interpreting null as oneway
+ NullProviderService servant2 = new NullProviderService();
+ Endpoint ep2 = Endpoint.publish(ADDRESS2, servant2);
+ assertNotNull("endpoint published", ep2);
+ ep2.getProperties().put("jaxws.provider.interpretNullAsOneway",
Boolean.TRUE);
+ }
+
+ public static void main(String[] args) throws Exception {
+ try {
+ Server s = new Server();
+ s.start();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ System.exit(-1);
+ } finally {
+ System.out.println("done!");
+ }
+ }
+ }
+
+ @javax.xml.ws.WebServiceProvider(serviceName = "NullService",
+ portName = "NullPort")
+ @javax.xml.ws.ServiceMode(value = javax.xml.ws.Service.Mode.PAYLOAD)
+ public static class NullProviderService implements Provider<Source> {
+ public Source invoke(Source request) {
+ return null;
+ }
+ }
+
+ @BeforeClass
+ public static void startServers() throws Exception {
+ assertTrue("server did not launch correctly",
launchServer(Server.class, true));
+ }
+
+ @Test
+ public void testNotInterpretNullAsOneway() throws Exception {
+ HttpURLConnection conn = postRequest(ADDRESS1);
+ assertTrue("Soap fault must be returned", 400 <=
conn.getResponseCode());
+ }
+
+ @Test
+ public void testInterpretNullAsOneway() throws Exception {
+ HttpURLConnection conn = postRequest(ADDRESS2);
+ assertEquals("http 202 must be returned", 202, conn.getResponseCode());
+ }
+
+ private static HttpURLConnection postRequest(String address) throws
Exception {
+ URL url = new URL(address);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setDoOutput(true);
+ InputStream in = InterpretNullAsOnewayProviderTest.class.
+ getResourceAsStream("resources/sayHiDocLiteralReq.xml");
+ assertNotNull("could not load test data", in);
+
+ conn.setRequestMethod("POST");
+ conn.addRequestProperty("Content-Type", "text/xml");
+ OutputStream out = conn.getOutputStream();
+ IOUtils.copy(in, out);
+ out.close();
+
+ return conn;
+ }
+}
Propchange:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/InterpretNullAsOnewayProviderTest.java
------------------------------------------------------------------------------
svn:executable = *