From 12f1beb9309ef42e4b7b920a68cca68467de8ee9 Mon Sep 17 00:00:00 2001 From: vp340 Date: Fri, 14 Aug 2026 00:59:28 +0200 Subject: [PATCH 1/8] move LIVE_LOGGING_PROP from AbstractLoggingInterceptor to Message --- core/src/main/java/org/apache/cxf/message/Message.java | 6 ++++++ .../apache/cxf/ext/logging/AbstractLoggingInterceptor.java | 3 +-- .../org/apache/cxf/ext/logging/LoggingInInterceptor.java | 2 +- .../org/apache/cxf/ext/logging/LoggingOutInterceptor.java | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/message/Message.java b/core/src/main/java/org/apache/cxf/message/Message.java index 339fade7658..71c155d51a9 100644 --- a/core/src/main/java/org/apache/cxf/message/Message.java +++ b/core/src/main/java/org/apache/cxf/message/Message.java @@ -211,6 +211,12 @@ public interface Message extends StringMap { */ String THREAD_SAFE_STAX_FACTORIES = Message.class.getName() + ".THREAD_SAFE_STAX_FACTORIES"; + + /** + * Property to disable the interceptor log of the Message + */ + String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable"; + String getId(); void setId(String id); 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 4f7c7c015a6..d3541b14dc9 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 @@ -38,7 +38,6 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto public static final int DEFAULT_LIMIT = 48 * 1024; public static final int DEFAULT_THRESHOLD = -1; public static final String CONTENT_SUPPRESSED = "--- Content suppressed ---"; - protected static final String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable"; private static final Pattern BOUNDARY_PATTERN = Pattern.compile("^--(\\S*)$", Pattern.MULTILINE); private static final Pattern CONTENT_TYPE_PATTERN = @@ -63,7 +62,7 @@ public AbstractLoggingInterceptor(String phase, LogEventSender sender) { } protected static boolean isLoggingDisabledNow(Message message) throws Fault { - Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP); + Object liveLoggingProp = message.getContextualProperty(Message.LIVE_LOGGING_PROP); return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); } 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..4c84ab768b1 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 void handleMessage(Message message) throws Fault { //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(Message.LIVE_LOGGING_PROP, 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..0fbdb724d21 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 void handleMessage(Message message) throws Fault { //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(Message.LIVE_LOGGING_PROP, Boolean.FALSE); } createExchangeId(message); final OutputStream os = message.getContent(OutputStream.class); From 622e2408289177c3f3bb4dcfc45f9d614c1dcde4 Mon Sep 17 00:00:00 2001 From: vp340 Date: Fri, 14 Aug 2026 01:00:00 +0200 Subject: [PATCH 2/8] remove the LIVE_LOGGING_PROPERTY from the ResponseContext --- core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java | 2 ++ 1 file changed, 2 insertions(+) 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 30ac1ba0b3a..6cbdbbe6007 100644 --- a/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java +++ b/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java @@ -650,6 +650,8 @@ protected Object[] processResult(Message message, resContext.putAll(inMsg); // remove the recursive reference if present resContext.remove(Message.INVOCATION_CONTEXT); + // remove the logging disable property + resContext.remove(Message.LIVE_LOGGING_PROP); setResponseContext(resContext); } resList = CastUtils.cast(inMsg.getContent(List.class)); From 66886ed954bcb83337170f026aae415609b5d3bc Mon Sep 17 00:00:00 2001 From: vp340 Date: Wed, 19 Aug 2026 00:25:04 +0200 Subject: [PATCH 3/8] restore previous situation --- core/src/main/java/org/apache/cxf/message/Message.java | 6 ------ .../org/apache/cxf/ext/logging/LoggingInInterceptor.java | 2 +- .../org/apache/cxf/ext/logging/LoggingOutInterceptor.java | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/message/Message.java b/core/src/main/java/org/apache/cxf/message/Message.java index 71c155d51a9..339fade7658 100644 --- a/core/src/main/java/org/apache/cxf/message/Message.java +++ b/core/src/main/java/org/apache/cxf/message/Message.java @@ -211,12 +211,6 @@ public interface Message extends StringMap { */ String THREAD_SAFE_STAX_FACTORIES = Message.class.getName() + ".THREAD_SAFE_STAX_FACTORIES"; - - /** - * Property to disable the interceptor log of the Message - */ - String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable"; - String getId(); void setId(String id); 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 4c84ab768b1..436bbf3d16d 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 void handleMessage(Message message) throws Fault { //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(Message.LIVE_LOGGING_PROP, Boolean.FALSE); + message.put(LIVE_LOGGING_PROP, 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 0fbdb724d21..7e68a7c5cca 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 void handleMessage(Message message) throws Fault { //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(Message.LIVE_LOGGING_PROP, Boolean.FALSE); + message.put(LIVE_LOGGING_PROP, Boolean.FALSE); } createExchangeId(message); final OutputStream os = message.getContent(OutputStream.class); From 08c8e80869a30dbc82f6e3dda3071c57b69d4afe Mon Sep 17 00:00:00 2001 From: vp340 Date: Wed, 19 Aug 2026 00:31:43 +0200 Subject: [PATCH 4/8] restore previous situation --- .../org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 d3541b14dc9..4f7c7c015a6 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 @@ -38,6 +38,7 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto public static final int DEFAULT_LIMIT = 48 * 1024; public static final int DEFAULT_THRESHOLD = -1; public static final String CONTENT_SUPPRESSED = "--- Content suppressed ---"; + protected static final String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable"; private static final Pattern BOUNDARY_PATTERN = Pattern.compile("^--(\\S*)$", Pattern.MULTILINE); private static final Pattern CONTENT_TYPE_PATTERN = @@ -62,7 +63,7 @@ public AbstractLoggingInterceptor(String phase, LogEventSender sender) { } protected static boolean isLoggingDisabledNow(Message message) throws Fault { - Object liveLoggingProp = message.getContextualProperty(Message.LIVE_LOGGING_PROP); + Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP); return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); } From 6dc70e42d649c970765b288cacd49cf595e629eb Mon Sep 17 00:00:00 2001 From: vp340 Date: Wed, 19 Aug 2026 00:34:23 +0200 Subject: [PATCH 5/8] add in the constructor the directive not to propagate the LIVE_LOGGING_PROP from InMessage into the ResponseContext --- .../org/apache/cxf/ext/logging/LoggingInInterceptor.java | 5 +++++ 1 file changed, 5 insertions(+) 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..149e0c170ff 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 @@ -38,6 +38,8 @@ import org.apache.cxf.phase.Phase; import org.apache.cxf.phase.PhaseInterceptor; +import static org.apache.cxf.endpoint.ClientImpl.addResponseContextExcludedInProperty; + /** * */ @@ -71,6 +73,9 @@ public LoggingInInterceptor(PrintWriter writer) { public LoggingInInterceptor(LogEventSender sender) { super(Phase.PRE_INVOKE, sender); + + //Make sure that the LIVE_LOGGING_PROP won't be propagated into the ResponseContext from IN Messages + addResponseContextExcludedInProperty(LIVE_LOGGING_PROP); } public Collection> getAdditionalInterceptors() { From 00e09abd3ee12651e15a63b64c02b3d6964840dc Mon Sep 17 00:00:00 2001 From: vp340 Date: Wed, 19 Aug 2026 00:35:10 +0200 Subject: [PATCH 6/8] add test --- .../ext/logging/LoggingInInterceptorTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java index d7b75781504..c73416c7b39 100644 --- a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java +++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; @@ -29,6 +30,7 @@ import java.util.Map; import java.util.Set; +import org.apache.cxf.endpoint.ClientImpl; import org.apache.cxf.ext.logging.event.LogEvent; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.message.ExchangeImpl; @@ -38,11 +40,13 @@ import org.junit.Before; import org.junit.Test; +import static org.apache.cxf.ext.logging.AbstractLoggingInterceptor.LIVE_LOGGING_PROP; import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.MASKED_HEADER_VALUE; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class LoggingInInterceptorTest { private static final String TEST_HEADER_VALUE = "TestValue"; @@ -234,4 +238,17 @@ public void shouldLogMultipartPayloadNoHeaders() throws IOException { assertThat(event.getPayload(), equalToIgnoringCase(buf.toString())); } + + @Test + public void shouldAddResponseContextInExcludedProperty() throws NoSuchFieldException, IllegalAccessException { + Field field = ClientImpl.class + .getDeclaredField("RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES"); + + field.setAccessible(true); + + @SuppressWarnings("unchecked") + Set actual = (Set) field.get(null); + + assertTrue(actual.contains(LIVE_LOGGING_PROP)); + } } From 2a65368301cc2c81f1e6ee0222241ddad9fddc27 Mon Sep 17 00:00:00 2001 From: vp340 Date: Wed, 19 Aug 2026 01:15:31 +0200 Subject: [PATCH 7/8] add methods to manage the propagation of ResponseContext properties coming from the InMessage --- .../org/apache/cxf/endpoint/ClientImpl.java | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) 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 6cbdbbe6007..3a0c5e99fc8 100644 --- a/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java +++ b/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java @@ -24,14 +24,7 @@ import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.logging.Level; @@ -107,6 +100,35 @@ public class ClientImpl protected Map responseContext = Collections.synchronizedMap(new WeakHashMap()); + /** + * Set of properties that should not be propagated into the ResponseContext from IN Message + */ + private static final Set RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES = new HashSet<>( + List.of( + // remove the recursive reference if present + Message.INVOCATION_CONTEXT + ) + ); + + /** + * Method that a cxf submodule can call to add a property not to propagate from IN Message into the ResponseContext + * @param property to exclude + */ + public static void addResponseContextExcludedInProperty(String property) { + RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES.add(property); + } + public static void addAllResponseContextExcludedInProperties(Set properties) { + RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES.addAll(properties); + } + + /** + * Method to remove RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES from ResponseContext Map + * @param context ResponseContext Map + */ + protected void filterResponseContextProperties(Map context) { + RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES.forEach(context::remove); + } + protected Executor executor; public ClientImpl(Bus b, Endpoint e) { @@ -648,10 +670,7 @@ protected Object[] processResult(Message message, if (inMsg != null) { if (null != resContext) { resContext.putAll(inMsg); - // remove the recursive reference if present - resContext.remove(Message.INVOCATION_CONTEXT); - // remove the logging disable property - resContext.remove(Message.LIVE_LOGGING_PROP); + filterResponseContextProperties(resContext); setResponseContext(resContext); } resList = CastUtils.cast(inMsg.getContent(List.class)); From 6d619a7f0ce0aec9a73404390917d2517e7936f1 Mon Sep 17 00:00:00 2001 From: vp340 Date: Wed, 19 Aug 2026 01:15:41 +0200 Subject: [PATCH 8/8] add some test --- .../apache/cxf/endpoint/ClientImplTest.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 core/src/test/java/org/apache/cxf/endpoint/ClientImplTest.java diff --git a/core/src/test/java/org/apache/cxf/endpoint/ClientImplTest.java b/core/src/test/java/org/apache/cxf/endpoint/ClientImplTest.java new file mode 100644 index 00000000000..cce006b6f2b --- /dev/null +++ b/core/src/test/java/org/apache/cxf/endpoint/ClientImplTest.java @@ -0,0 +1,124 @@ +package org.apache.cxf.endpoint; + + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.cxf.BusFactory; +import org.apache.cxf.message.Message; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ClientImplTest { + + private static class TestClientImpl extends ClientImpl { + + public TestClientImpl() { + super(BusFactory.newInstance().createBus(), null); + } + + void filter(Map context) { + filterResponseContextProperties(context); + } + } + + private final TestClientImpl testClientImpl = new TestClientImpl(); + + private static Set getExcludedProperties() throws Exception { + Field field = ClientImpl.class + .getDeclaredField("RESPONSE_CONTEXT_EXCLUDED_IN_PROPERTIES"); + + field.setAccessible(true); + + @SuppressWarnings("unchecked") + Set properties = (Set) field.get(null); + + return properties; + } + + private static Set defaultExcludedProperties; + + @BeforeClass + public static void initDefaults() throws Exception { + defaultExcludedProperties = + new HashSet<>(getExcludedProperties()); + } + + @Before + public void setUp() throws Exception { + Set properties = getExcludedProperties(); + + properties.clear(); + properties.addAll(defaultExcludedProperties); + } + + @Test + public void shouldFilterDefaultExcludedProperty() { + + Map context = new HashMap<>(); + context.put(Message.INVOCATION_CONTEXT, "invocation-context"); + context.put("property.to.keep", "value"); + + testClientImpl.filter(context); + + assertFalse(context.containsKey(Message.INVOCATION_CONTEXT)); + assertEquals("value", context.get("property.to.keep")); + } + + @Test + public void shouldFilterPropertyAddedWithAdd() { + String property = "my.custom.property"; + + ClientImpl.addResponseContextExcludedInProperty(property); + + Map context = new HashMap<>(); + context.put(property, "custom-value"); + context.put("property.to.keep", "value"); + + testClientImpl.filter(context); + + assertFalse(context.containsKey(property)); + assertEquals("value", context.get("property.to.keep")); + } + + @Test + public void shouldFilterPropertiesAddedWithAddAll() { + Set properties = Set.of( + "custom.property.1", + "custom.property.2" + ); + + ClientImpl.addAllResponseContextExcludedInProperties(properties); + + Map context = new HashMap<>(); + context.put("custom.property.1", "value1"); + context.put("custom.property.2", "value2"); + context.put("property.to.keep", "keep"); + + testClientImpl.filter(context); + + assertFalse(context.containsKey("custom.property.1")); + assertFalse(context.containsKey("custom.property.2")); + assertEquals("keep", context.get("property.to.keep")); + } + + @Test + public void shouldKeepPropertiesNotExcluded() { + + Map context = new HashMap<>(); + context.put("property.1", "value1"); + context.put("property.2", "value2"); + + testClientImpl.filter(context); + + assertEquals(2, context.size()); + assertEquals("value1", context.get("property.1")); + assertEquals("value2", context.get("property.2")); + } +} \ No newline at end of file