This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 1df67041e9d3abeef86960a8b786d8c1c09ce7de Author: Andriy Redko <[email protected]> AuthorDate: Mon Aug 24 18:34:15 2026 -0400 CXF-9233: AbstractLoggingInterceptor.LIVE_LOGGING_PROP already set in the message properties, so RESP_OUT is not logged (#3372) * CXF-9233: AbstractLoggingInterceptor.LIVE_LOGGING_PROP already set in the message properties, so RESP_OUT is not logged * Add test cases * Address code review comments * Address code review comments (cherry picked from commit 650bbf9ca93953d85c6f20c47958c3f2f4309760) --- .../ext/logging/AbstractLoggingInterceptor.java | 14 +++++++ .../cxf/ext/logging/LoggingInInterceptor.java | 2 +- .../cxf/ext/logging/LoggingOutInterceptor.java | 2 +- .../java/org/apache/cxf/jaxws/JaxWsClientTest.java | 43 ++++++++++++++++++++++ .../cxf/jaxrs/client/logging/RESTLoggingTest.java | 33 +++++++++++++++++ .../{TestServiceRest.java => TestService.java} | 15 +++----- .../cxf/jaxrs/client/logging/TestServiceRest.java | 14 ++----- 7 files changed, 102 insertions(+), 21 deletions(-) diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java index 67e27633d34..346aba857ee 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java @@ -32,6 +32,7 @@ import org.apache.cxf.ext.logging.event.PrettyLoggingFilter; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; import org.apache.cxf.phase.AbstractPhaseInterceptor; public abstract class AbstractLoggingInterceptor extends AbstractPhaseInterceptor<Message> { @@ -63,7 +64,16 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto } protected static boolean isLoggingDisabledNow(Message message) throws Fault { + // For backward compatibility, check the old LIVE_LOGGING_PROP property first Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP); + if (liveLoggingProp != null) { + return PropertyUtils.isFalse(liveLoggingProp); + } + // Some frameworks (like Camel) do copy the context (properties) from in- to out- + // messages as-is, so it is very possible that LIVE_LOGGING_PROP will end up in the + // in / out message by mistake. To track that, adding the requestor message property + // to distinguish between such messages. + liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP + "." + getRequestorSuffix(message)); return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); } @@ -226,4 +236,8 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto Matcher m = BOUNDARY_PATTERN.matcher(payload); return m.find() ? "--" + m.group(1) : null; } + + static String getRequestorSuffix(Message message) { + return MessageUtils.isRequestor(message) ? "in" : "out"; + } } diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java index 436bbf3d16d..393e996b564 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java @@ -87,7 +87,7 @@ public class LoggingInInterceptor extends AbstractLoggingInterceptor { //ensure only logging once for a certain message //this can prevent message logging again when fault //happen after PRE_INVOKE phase(rewind calls into LoggingInFaultInterceptor) - message.put(LIVE_LOGGING_PROP, Boolean.FALSE); + message.put(LIVE_LOGGING_PROP + "." + getRequestorSuffix(message), Boolean.FALSE); } createExchangeId(message); final LogEvent event = eventMapper.map(message, sensitiveProtocolHeaderNames); diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java index 7e68a7c5cca..11a39cd2cf8 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java @@ -65,7 +65,7 @@ public class LoggingOutInterceptor extends AbstractLoggingInterceptor { //ensure only logging once for a certain message //this can prevent message logging again when fault //happen after PRE_STREAM phase(LoggingOutInterceptor is called both in out chain and fault out chain) - message.put(LIVE_LOGGING_PROP, Boolean.FALSE); + message.put(LIVE_LOGGING_PROP + "." + getRequestorSuffix(message), Boolean.FALSE); } createExchangeId(message); final OutputStream os = message.getContent(OutputStream.class); diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java index 809e9fdfc95..eaf1d61f6f9 100644 --- a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java +++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java @@ -22,6 +22,7 @@ package org.apache.cxf.jaxws; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.net.URL; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -44,6 +45,9 @@ import javax.xml.ws.handler.soap.SOAPMessageContext; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.ClientImpl; +import org.apache.cxf.ext.logging.LoggingFeature; +import org.apache.cxf.ext.logging.event.LogEvent; +import org.apache.cxf.ext.logging.event.LogEventSender; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.interceptor.Fault; @@ -58,10 +62,12 @@ import org.apache.cxf.service.model.BindingOperationInfo; import org.apache.cxf.service.model.EndpointInfo; import org.apache.cxf.service.model.MessagePartInfo; import org.apache.cxf.transport.Destination; +import org.apache.cxf.transport.local.LocalTransportFactory; import org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean; import org.apache.hello_world_soap_http.BadRecordLitFault; import org.apache.hello_world_soap_http.Greeter; import org.apache.hello_world_soap_http.GreeterImpl; +import org.apache.hello_world_soap_http.types.SayHi; import org.junit.Before; import org.junit.Test; @@ -253,6 +259,7 @@ public class JaxWsClientTest extends AbstractJaxWsTest { EndpointInfo ei = service.getServiceInfos().get(0).getEndpoint(new QName(namespace, "SoapPort")); JaxWsEndpointImpl endpoint = new JaxWsEndpointImpl(getBus(), service, ei); + getBus().setFeatures(List.of(new LoggingFeature())); ClientImpl client = new ClientImpl(getBus(), endpoint); BindingOperationInfo bop = ei.getBinding().getOperation(new QName(namespace, "sayHi")); @@ -309,6 +316,42 @@ public class JaxWsClientTest extends AbstractJaxWsTest { } + @Test + public void testEndpointWithLogging() throws Exception { + GreeterImpl service = new GreeterImpl(); + String namespace = "http://apache.org/hello_world_soap_http"; + try (EndpointImpl ep = new EndpointImpl(getBus(), service, (String) null)) { + ep.publish("local://localhost:9092/hello"); + + EndpointInfo ei = ep.getService().getServiceInfos().get(0).getEndpoint(new QName(namespace, "SoapPort")); + JaxWsEndpointImpl endpoint = new JaxWsEndpointImpl(getBus(), ep.getService(), ei); + + final List<LogEvent> events = new ArrayList<>(); + final LoggingFeature loggingFeature = new LoggingFeature(); + loggingFeature.setSender(new LogEventSender() { + @Override + public void send(LogEvent event) { + events.add(event); + } + }); + getBus().setFeatures(List.of(loggingFeature)); + + ClientImpl client = new ClientImpl(getBus(), endpoint); + client.getRequestContext().put(LocalTransportFactory.MESSAGE_INCLUDE_PROPERTIES, + Set.of("org.apache.cxf.logging.enable.out", "org.apache.cxf.logging.enable.in")); + + BindingOperationInfo bop = ei.getBinding().getOperation(new QName(namespace, "sayHi")); + assertNotNull(bop); + + Object[] ret = client.invoke(bop, new Object[] {new SayHi()}, null); + assertNotNull(ret); + assertEquals("Wrong number of return objects", 1, ret.length); + + assertEquals(4, events.size()); + client.close(); + } + } + @Test public void testClientProxyFactory() { JaxWsProxyFactoryBean cf = new JaxWsProxyFactoryBean(); diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java index 01c188c96f8..b617bf0629a 100644 --- a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java +++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java @@ -192,6 +192,31 @@ public class RESTLoggingTest { checkResponseIn(events.get(3)); } + @Test + public void testEventsWithProxy() throws MalformedURLException { + LoggingFeature loggingFeature = new LoggingFeature(); + loggingFeature.setLogBinary(true); + TestEventSender sender = new TestEventSender(); + loggingFeature.setSender(sender); + Server server = createService(SERVICE_URI, new TestServiceRest(), loggingFeature); + server.start(); + TestService client = createClient(SERVICE_URI, TestService.class, loggingFeature); + String result = client.echo("test1"); + Assert.assertEquals("test1", result); + + List<LogEvent> events = sender.getEvents(); + await().until(() -> events.size(), is(4)); + server.stop(); + server.destroy(); + + Assert.assertEquals(4, events.size()); + checkRequestOut(events.get(0)); + checkRequestIn(events.get(1)); + checkResponseOut(events.get(2)); + checkResponseIn(events.get(3)); + } + + private void assertContentLogged(LogEvent event) { Assert.assertNotEquals(AbstractLoggingInterceptor.CONTENT_SUPPRESSED, event.getPayload()); } @@ -200,6 +225,14 @@ public class RESTLoggingTest { Assert.assertEquals(AbstractLoggingInterceptor.CONTENT_SUPPRESSED, event.getPayload()); } + private <T> T createClient(String serviceURI, Class<T> contract, LoggingFeature loggingFeature) { + JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); + bean.setAddress(serviceURI); + bean.setFeatures(Collections.singletonList(loggingFeature)); + bean.setResourceClass(contract); + return bean.create(contract); + } + private WebClient createClient(String serviceURI, LoggingFeature loggingFeature) { JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); bean.setAddress(serviceURI); diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestService.java similarity index 84% copy from rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java copy to rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestService.java index 0d94fc1f719..e00c773e5df 100644 --- a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java +++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestService.java @@ -22,17 +22,14 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; -public class TestServiceRest { +public interface TestService { @GET @Path("{msg}") - public String echo(@PathParam("msg") String msg) { - return msg; - } + @Produces("application/octet-stream") + String echo(@PathParam("msg") String msg); @POST - public String post(String msg) { - return msg; - } -} - + String post(String msg); +} \ No newline at end of file diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java index 0d94fc1f719..f9999655428 100644 --- a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java +++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java @@ -18,19 +18,13 @@ */ package org.apache.cxf.jaxrs.client.logging; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; - -public class TestServiceRest { - @GET - @Path("{msg}") - public String echo(@PathParam("msg") String msg) { +public class TestServiceRest implements TestService { + @Override + public String echo(String msg) { return msg; } - @POST + @Override public String post(String msg) { return msg; }
