You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2026/10/16 11:22:17 UTC
(cxf) branch main updated: CXF-6301: Deliver faults marked as partial responses to async callbacks (#3591)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new df01f78e0ba CXF-6301: Deliver faults marked as partial responses to async callbacks (#3591)
df01f78e0ba is described below
commit df01f78e0bae55026647835c1d8ceaf6bcbcd296
Author: Colm O hEigeartaigh <co...@users.noreply.github.com>
AuthorDate: Fri Oct 16 12:22:11 2026 +0100
CXF-6301: Deliver faults marked as partial responses to async callbacks (#3591)
---
.../java/org/apache/cxf/endpoint/ClientImpl.java | 3 +-
.../cxf/jaxws/dispatch/DispatchAsyncFaultTest.java | 129 +++++++++++++++++++++
.../cxf/jaxws/dispatch/Soap12FaultNoRelatesTo.xml | 40 +++++++
3 files changed, 171 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java b/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java
index 35803e1c4f2..aaeb3c1e384 100644
--- a/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java
+++ b/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java
@@ -933,7 +933,8 @@ public class ClientImpl
}
callback = message.getExchange().get(ClientCallback.class);
- if (callback == null || isPartialResponse(message)) {
+ if (callback == null
+ || (isPartialResponse(message) && message.getContent(Exception.class) == null)) {
return;
}
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchAsyncFaultTest.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchAsyncFaultTest.java
new file mode 100644
index 00000000000..3ff9db53875
--- /dev/null
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/DispatchAsyncFaultTest.java
@@ -0,0 +1,129 @@
+/**
+ * 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 java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+
+import jakarta.xml.ws.Dispatch;
+import jakarta.xml.ws.Response;
+import jakarta.xml.ws.Service;
+import jakarta.xml.ws.soap.AddressingFeature;
+import jakarta.xml.ws.soap.SOAPBinding;
+import jakarta.xml.ws.soap.SOAPFaultException;
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.jaxws.AbstractJaxWsTest;
+import org.apache.cxf.jaxws.MessageReplayObserver;
+import org.apache.cxf.jaxws.ServiceImpl;
+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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * CXF-6301: a SOAP 1.2 fault carrying WS-Addressing headers but no wsa:RelatesTo must be
+ * delivered to an AsyncHandler, as it already is for a synchronous invocation.
+ */
+public class DispatchAsyncFaultTest extends AbstractJaxWsTest {
+ private static final QName SERVICE_NAME = new QName("http://cxf.apache.org/test/dispatch", "DispatchTest");
+
+ private static final QName PORT_NAME = new QName("http://cxf.apache.org/test/dispatch", "DispatchPort");
+
+ private static final String ADDRESS = "http://localhost:9121/SoapContext/DispatchPort";
+
+ private static final String REQ_RESOURCE = "/org/apache/cxf/jaxws/dispatch/OperationRequest.xml";
+
+ private static final String FAULT_RESOURCE = "/org/apache/cxf/jaxws/dispatch/Soap12FaultNoRelatesTo.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);
+ d.setMessageObserver(new MessageReplayObserver(FAULT_RESOURCE));
+ }
+
+ @Test
+ public void testSyncFaultWithoutRelatesTo() throws Exception {
+ Dispatch<Source> disp = createDispatch();
+ try {
+ disp.invoke(createRequest());
+ fail("Expected SOAPFaultException");
+ } catch (SOAPFaultException ex) {
+ assertEquals("NotSupported", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testAsyncHandlerFaultWithoutRelatesTo() throws Exception {
+ Dispatch<Source> disp = createDispatch();
+ CompletableFuture<Response<Source>> handled = new CompletableFuture<>();
+ disp.invokeAsync(createRequest(), handled::complete);
+
+ Response<Source> response = handled.get(30, TimeUnit.SECONDS);
+ try {
+ response.get();
+ fail("Expected ExecutionException");
+ } catch (ExecutionException ex) {
+ assertTrue(ex.getCause() instanceof SoapFault);
+ assertEquals("NotSupported", ex.getCause().getMessage());
+ }
+ }
+
+ @Test
+ public void testAsyncResponseFaultWithoutRelatesTo() throws Exception {
+ Dispatch<Source> disp = createDispatch();
+ Response<Source> response = disp.invokeAsync(createRequest());
+ try {
+ response.get(30, TimeUnit.SECONDS);
+ fail("Expected ExecutionException");
+ } catch (ExecutionException ex) {
+ assertTrue(ex.getCause() instanceof SOAPFaultException);
+ assertEquals("NotSupported", ex.getCause().getMessage());
+ }
+ }
+
+ private Dispatch<Source> createDispatch() {
+ ServiceImpl service = new ServiceImpl(getBus(), null, SERVICE_NAME, null, new AddressingFeature());
+ service.addPort(PORT_NAME, SOAPBinding.SOAP12HTTP_BINDING, ADDRESS);
+ return service.createDispatch(PORT_NAME, Source.class, Service.Mode.PAYLOAD);
+ }
+
+ private Source createRequest() throws Exception {
+ Document doc = StaxUtils.read(getResourceAsStream(REQ_RESOURCE));
+ return new DOMSource(doc);
+ }
+}
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/Soap12FaultNoRelatesTo.xml b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/Soap12FaultNoRelatesTo.xml
new file mode 100644
index 00000000000..fc4078e6339
--- /dev/null
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/dispatch/Soap12FaultNoRelatesTo.xml
@@ -0,0 +1,40 @@
+<?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 1.2 fault with WS-Addressing headers but no wsa:RelatesTo (CXF-6301) -->
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope">
+ <SOAP-ENV:Header>
+ <Action xmlns="http://www.w3.org/2005/08/addressing">urn://Ocpp/cp/2012/06/:ChargePointService::Fault</Action>
+ <MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:a2eea7dd-1d3c-437c-870e-2dff0a63d44d</MessageID>
+ </SOAP-ENV:Header>
+ <SOAP-ENV:Body>
+ <SOAP-ENV:Fault>
+ <SOAP-ENV:Code>
+ <SOAP-ENV:Value>SOAP-ENV:Receiver</SOAP-ENV:Value>
+ </SOAP-ENV:Code>
+ <SOAP-ENV:Reason>
+ <SOAP-ENV:Text>NotSupported</SOAP-ENV:Text>
+ </SOAP-ENV:Reason>
+ <detail>SOAP-ENV:NotSupported</detail>
+ </SOAP-ENV:Fault>
+ </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>