From 460b44e1cb7f88d70529d13a3e311a322ccb2995 Mon Sep 17 00:00:00 2001 From: vp340 Date: Sun, 26 Jul 2026 23:53:58 +0200 Subject: [PATCH 1/3] Disabling the log for the same Message object just for the same flow (REQ_IN/REQ_OUT/RESP_IN/RESP_OUT)... Replacing the general logging enable properties that could be present from other flow if the same Message object is reused from underlying framework --- .../logging/AbstractLoggingInterceptor.java | 21 ++++++++---- .../cxf/ext/logging/LoggingInInterceptor.java | 4 +-- .../ext/logging/LoggingOutInterceptor.java | 4 +-- .../logging/event/DefaultLogEventMapper.java | 18 +++++++++- .../logging/DefaultLogEventMapperTest.java | 10 +++++- .../ext/logging/LoggingInInterceptorTest.java | 34 ++++++++++++++++++- 6 files changed, 77 insertions(+), 14 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 4f7c7c015a6..a681f5aa9e5 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 @@ -25,20 +25,19 @@ import java.util.regex.Pattern; import org.apache.cxf.common.util.PropertyUtils; -import org.apache.cxf.ext.logging.event.DefaultLogEventMapper; -import org.apache.cxf.ext.logging.event.LogEvent; -import org.apache.cxf.ext.logging.event.LogEventSender; -import org.apache.cxf.ext.logging.event.PrettyLoggingFilter; +import org.apache.cxf.ext.logging.event.*; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; +import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.normalizeFlow; + public abstract class AbstractLoggingInterceptor extends AbstractPhaseInterceptor { 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"; + protected static final String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable."; // the EventType (flow) will be concatenated private static final Pattern BOUNDARY_PATTERN = Pattern.compile("^--(\\S*)$", Pattern.MULTILINE); private static final Pattern CONTENT_TYPE_PATTERN = @@ -62,10 +61,18 @@ public AbstractLoggingInterceptor(String phase, LogEventSender sender) { this.eventMapper = new DefaultLogEventMapper(maskSensitiveHelper); } - protected static boolean isLoggingDisabledNow(Message message) throws Fault { - Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP); + // The concatenated flow is added in order to enhance resilience against misuse and underlying framework + // (Reuse of the same Message object with properties still there) + // The message will be logged once per flow + // If previous properties (ex. LIVE_LOGGING_PROP + REQ_IN) are still there... this will search + // only for the right properties (ex. LIVE_LOGGING_PROP + RESP_OUT) + protected boolean isLoggingDisabledForThisFlow(Message message) throws Fault { + Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message))); //idempotency per Flow return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); } + protected void disableFutureLoggingForThisFlow(Message message) throws Fault { + message.put(LIVE_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message)), Boolean.FALSE); + } public void addBinaryContentMediaTypes(String mediaTypes) { eventMapper.addBinaryContentMediaTypes(mediaTypes); 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..ba13dbe102f 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 @@ -81,13 +81,13 @@ public Collection> getAdditionalInterceptors } public void handleMessage(Message message) throws Fault { - if (isLoggingDisabledNow(message)) { + if (isLoggingDisabledForThisFlow(message)) { return; } else { //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); + disableFutureLoggingForThisFlow(message); } 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..04d50e9660a 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 @@ -59,13 +59,13 @@ public LoggingOutInterceptor(LogEventSender sender) { } public void handleMessage(Message message) throws Fault { - if (isLoggingDisabledNow(message)) { + if (isLoggingDisabledForThisFlow(message)) { return; } else { //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); + disableFutureLoggingForThisFlow(message); } createExchangeId(message); final OutputStream os = message.getContent(OutputStream.class); diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java index ee3a386bec5..1dc4b4894d9 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java @@ -47,6 +47,8 @@ import org.apache.cxf.ws.addressing.AddressingProperties; import org.apache.cxf.ws.addressing.ContextUtils; +import static org.apache.cxf.ext.logging.event.EventType.*; + public class DefaultLogEventMapper { public static final String MASKED_HEADER_VALUE = "XXX"; private static final Set DEFAULT_BINARY_CONTENT_MEDIA_TYPES; @@ -352,11 +354,25 @@ public EventType getEventType(Message message) { return isRequestor ? EventType.REQ_OUT : EventType.RESP_OUT; } if (isFault) { - return EventType.FAULT_IN; + return FAULT_IN; } return isRequestor ? EventType.RESP_IN : EventType.REQ_IN; } + /** + * Get the normalize 'flow' from the eventType + * + * @param eventType + * @return normalized eventType + */ + public static EventType normalizeFlow(EventType eventType){ + return switch (eventType) { + case FAULT_IN -> RESP_IN; + case FAULT_OUT -> RESP_OUT; + default -> eventType; + }; + } + /** * For REST we also consider a response to be a fault if the operation is not found or the response code * is an error diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java index f502d8e8de0..0154610bea9 100644 --- a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java +++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java @@ -43,6 +43,8 @@ import org.junit.Test; import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.MASKED_HEADER_VALUE; +import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.normalizeFlow; +import static org.apache.cxf.ext.logging.event.EventType.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -81,7 +83,7 @@ public void testPreflightRequestEventType() { message.setExchange(exchange); exchange.setOutMessage(message); LogEvent event = mapper.map(message, Collections.emptySet()); - assertEquals(EventType.RESP_OUT, event.getType()); + assertEquals(RESP_OUT, event.getType()); } /** @@ -206,4 +208,10 @@ public void testNoSubjectReturned() { LogEvent event = Subject.doAs(subject, (PrivilegedAction) () -> mapper.map(message)); assertThat(event.getPrincipal(), is(nullValue())); } + + @Test + public void testNormalizeFlow(){ + assertEquals(RESP_IN, normalizeFlow(FAULT_IN)); + assertEquals(RESP_OUT, normalizeFlow(FAULT_OUT)); + } } 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..fea866e82ac 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 @@ -29,8 +29,10 @@ import java.util.Map; import java.util.Set; +import org.apache.cxf.ext.logging.event.DefaultLogEventMapper; import org.apache.cxf.ext.logging.event.LogEvent; import org.apache.cxf.io.CachedOutputStream; +import org.apache.cxf.message.Exchange; import org.apache.cxf.message.ExchangeImpl; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageImpl; @@ -38,11 +40,15 @@ import org.junit.Before; import org.junit.Test; +import static org.apache.cxf.common.util.PropertyUtils.isFalse; +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.apache.cxf.ext.logging.event.DefaultLogEventMapper.normalizeFlow; +import static org.apache.cxf.ext.logging.event.EventType.*; 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.*; public class LoggingInInterceptorTest { private static final String TEST_HEADER_VALUE = "TestValue"; @@ -234,4 +240,30 @@ public void shouldLogMultipartPayloadNoHeaders() throws IOException { assertThat(event.getPayload(), equalToIgnoringCase(buf.toString())); } + + @Test + public void testLoggingEnable(){ + Message message = new MessageImpl(); + Exchange exchange = new ExchangeImpl(); + exchange.setOutMessage(message); + message.setExchange(exchange); + message.put(Message.REQUESTOR_ROLE, Boolean.TRUE); + + DefaultLogEventMapper mapper = new DefaultLogEventMapper(); + assertEquals(FAULT_OUT, mapper.getEventType(message)); + + assertFalse(interceptor.isLoggingDisabledForThisFlow(message)); + interceptor.disableFutureLoggingForThisFlow(message); + assertTrue(interceptor.isLoggingDisabledForThisFlow(message)); + + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_IN)); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_OUT)); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_IN)); + assertNotNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT)); //The only present // FAULT_OUT normalized + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_IN)); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_OUT)); + + assertTrue(isFalse(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT))); + + } } From 6fc77e530080dcdcd626d04500b089ccf78bbf60 Mon Sep 17 00:00:00 2001 From: vp340 Date: Mon, 27 Jul 2026 14:31:39 +0200 Subject: [PATCH 2/3] Add also the ExchangeId to avoid previous REQ_OUT / RESP_IN properties set from previous backend-client call! :) --- .../logging/AbstractLoggingInterceptor.java | 18 ++++++++++++------ .../cxf/ext/logging/LoggingInInterceptor.java | 13 +++++++------ .../cxf/ext/logging/LoggingOutInterceptor.java | 13 +++++++------ .../ext/logging/LoggingInInterceptorTest.java | 16 +++++++++------- 4 files changed, 35 insertions(+), 25 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 a681f5aa9e5..33c83a3b240 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 @@ -37,7 +37,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."; // the EventType (flow) will be concatenated + protected static final String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable."; // the EventType (flow) and ExchangeId will be concatenated private static final Pattern BOUNDARY_PATTERN = Pattern.compile("^--(\\S*)$", Pattern.MULTILINE); private static final Pattern CONTENT_TYPE_PATTERN = @@ -63,15 +63,21 @@ public AbstractLoggingInterceptor(String phase, LogEventSender sender) { // The concatenated flow is added in order to enhance resilience against misuse and underlying framework // (Reuse of the same Message object with properties still there) - // The message will be logged once per flow - // If previous properties (ex. LIVE_LOGGING_PROP + REQ_IN) are still there... this will search - // only for the right properties (ex. LIVE_LOGGING_PROP + RESP_OUT) + // The message will be logged once per flow per ExchangeId + // If previous properties (ex. LIVE_LOGGING_PROP + REQ_IN + ExchangeId) are still there... this will search + // only for the right properties (ex. LIVE_LOGGING_PROP + RESP_OUT + ExchangeId) protected boolean isLoggingDisabledForThisFlow(Message message) throws Fault { - Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message))); //idempotency per Flow + Object liveLoggingProp = message.getContextualProperty(getDisableLogKey(message)); //idempotency per Flow per ExchangeId return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); } protected void disableFutureLoggingForThisFlow(Message message) throws Fault { - message.put(LIVE_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message)), Boolean.FALSE); + message.put(getDisableLogKey(message), Boolean.FALSE); + } + + // LIVE_LOGGING_PROP + FLOW + ExchangeId + protected String getDisableLogKey(Message message){ + createExchangeId(message); //Redundant + return LIVE_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message)) + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID); } public void addBinaryContentMediaTypes(String mediaTypes) { 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 ba13dbe102f..687c6f958fa 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 @@ -81,15 +81,16 @@ public Collection> getAdditionalInterceptors } public void handleMessage(Message message) throws Fault { + + createExchangeId(message); if (isLoggingDisabledForThisFlow(message)) { return; - } else { - //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) - disableFutureLoggingForThisFlow(message); } - createExchangeId(message); + //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) + disableFutureLoggingForThisFlow(message); + final LogEvent event = eventMapper.map(message, sensitiveProtocolHeaderNames); if (shouldLogContent(event)) { addContent(message, event); 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 04d50e9660a..81a8b9d1833 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 @@ -59,15 +59,16 @@ public LoggingOutInterceptor(LogEventSender sender) { } public void handleMessage(Message message) throws Fault { + createExchangeId(message); if (isLoggingDisabledForThisFlow(message)) { return; - } else { - //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) - disableFutureLoggingForThisFlow(message); } - createExchangeId(message); + + //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) + disableFutureLoggingForThisFlow(message); + final OutputStream os = message.getContent(OutputStream.class); if (os != null) { LoggingCallback callback = new LoggingCallback(sender, message, os, limit); 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 fea866e82ac..b685ffecd0c 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 @@ -252,18 +252,20 @@ public void testLoggingEnable(){ DefaultLogEventMapper mapper = new DefaultLogEventMapper(); assertEquals(FAULT_OUT, mapper.getEventType(message)); + assertNull(message.getExchange().get(LogEvent.KEY_EXCHANGE_ID)); assertFalse(interceptor.isLoggingDisabledForThisFlow(message)); + assertNotNull(message.getExchange().get(LogEvent.KEY_EXCHANGE_ID)); interceptor.disableFutureLoggingForThisFlow(message); assertTrue(interceptor.isLoggingDisabledForThisFlow(message)); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_IN)); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_OUT)); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_IN)); - assertNotNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT)); //The only present // FAULT_OUT normalized - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_IN)); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_OUT)); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNotNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); //The only present // FAULT_OUT normalized + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); - assertTrue(isFalse(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT))); + assertTrue(isFalse(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID)))); } } From 756c6bdbf42a2965586d430d25f48bb58da556a8 Mon Sep 17 00:00:00 2001 From: vp340 Date: Mon, 27 Jul 2026 15:22:43 +0200 Subject: [PATCH 3/3] Reintroduce LIVE_LOGGING_PROP if is set and use for other feature. Introduce another properties for idempotent logging --- .../logging/AbstractLoggingInterceptor.java | 20 +++++++++++----- .../cxf/ext/logging/LoggingInInterceptor.java | 2 +- .../ext/logging/LoggingOutInterceptor.java | 2 +- .../ext/logging/LoggingInInterceptorTest.java | 24 +++++++------------ 4 files changed, 25 insertions(+), 23 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 33c83a3b240..3bdc2adc2d7 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 @@ -37,7 +37,9 @@ 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."; // the EventType (flow) and ExchangeId will be concatenated + protected static final String LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable"; + protected static final String IDEMPOTENT_LOGGING_PROP = "org.apache.cxf.idempotent.logging."; // the EventType (flow) and ExchangeId will be concatenated + private static final Pattern BOUNDARY_PATTERN = Pattern.compile("^--(\\S*)$", Pattern.MULTILINE); private static final Pattern CONTENT_TYPE_PATTERN = @@ -61,23 +63,29 @@ public AbstractLoggingInterceptor(String phase, LogEventSender sender) { this.eventMapper = new DefaultLogEventMapper(maskSensitiveHelper); } + // If the properties is set somewhere else (Bus...etc...) + protected static boolean isLoggingDisabledNow(Message message) throws Fault { + Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP); + return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); + } + // The concatenated flow is added in order to enhance resilience against misuse and underlying framework // (Reuse of the same Message object with properties still there) // The message will be logged once per flow per ExchangeId // If previous properties (ex. LIVE_LOGGING_PROP + REQ_IN + ExchangeId) are still there... this will search // only for the right properties (ex. LIVE_LOGGING_PROP + RESP_OUT + ExchangeId) protected boolean isLoggingDisabledForThisFlow(Message message) throws Fault { - Object liveLoggingProp = message.getContextualProperty(getDisableLogKey(message)); //idempotency per Flow per ExchangeId - return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); + Object idempotentLoggingProp = message.getContextualProperty(getidempotentDisableLogKey(message)); //idempotency per Flow per ExchangeId + return idempotentLoggingProp != null && PropertyUtils.isFalse(idempotentLoggingProp); } protected void disableFutureLoggingForThisFlow(Message message) throws Fault { - message.put(getDisableLogKey(message), Boolean.FALSE); + message.put(getidempotentDisableLogKey(message), Boolean.FALSE); } // LIVE_LOGGING_PROP + FLOW + ExchangeId - protected String getDisableLogKey(Message message){ + protected String getidempotentDisableLogKey(Message message){ createExchangeId(message); //Redundant - return LIVE_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message)) + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID); + return IDEMPOTENT_LOGGING_PROP + normalizeFlow(eventMapper.getEventType(message)) + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID); } public void addBinaryContentMediaTypes(String mediaTypes) { 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 687c6f958fa..50251117310 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 @@ -83,7 +83,7 @@ public Collection> getAdditionalInterceptors public void handleMessage(Message message) throws Fault { createExchangeId(message); - if (isLoggingDisabledForThisFlow(message)) { + if (isLoggingDisabledNow(message) || isLoggingDisabledForThisFlow(message)) { return; } //ensure only logging once for a certain message 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 81a8b9d1833..dd19d1df015 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 @@ -60,7 +60,7 @@ public LoggingOutInterceptor(LogEventSender sender) { public void handleMessage(Message message) throws Fault { createExchangeId(message); - if (isLoggingDisabledForThisFlow(message)) { + if (isLoggingDisabledNow(message) || isLoggingDisabledForThisFlow(message)) { return; } 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 b685ffecd0c..290fe3eaf39 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 @@ -22,12 +22,7 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.apache.cxf.ext.logging.event.DefaultLogEventMapper; import org.apache.cxf.ext.logging.event.LogEvent; @@ -41,9 +36,8 @@ import org.junit.Test; import static org.apache.cxf.common.util.PropertyUtils.isFalse; -import static org.apache.cxf.ext.logging.AbstractLoggingInterceptor.LIVE_LOGGING_PROP; +import static org.apache.cxf.ext.logging.AbstractLoggingInterceptor.IDEMPOTENT_LOGGING_PROP; import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.MASKED_HEADER_VALUE; -import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.normalizeFlow; import static org.apache.cxf.ext.logging.event.EventType.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalToIgnoringCase; @@ -258,14 +252,14 @@ public void testLoggingEnable(){ interceptor.disableFutureLoggingForThisFlow(message); assertTrue(interceptor.isLoggingDisabledForThisFlow(message)); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + REQ_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); - assertNotNull(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); //The only present // FAULT_OUT normalized - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); - assertNull(message.getContextualProperty(LIVE_LOGGING_PROP + FAULT_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + REQ_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + REQ_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + RESP_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNotNull(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + RESP_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); //The only present // FAULT_OUT normalized + assertNull(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + FAULT_IN + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); + assertNull(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + FAULT_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID))); - assertTrue(isFalse(message.getContextualProperty(LIVE_LOGGING_PROP + RESP_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID)))); + assertTrue(isFalse(message.getContextualProperty(IDEMPOTENT_LOGGING_PROP + RESP_OUT + '.' + message.getExchange().get(LogEvent.KEY_EXCHANGE_ID)))); } }