This is an automated email from the ASF dual-hosted git repository.
reta 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 d6842c9aa6 [CXF-8925] Prevent double logging on fault in out chain
(#1426)
d6842c9aa6 is described below
commit d6842c9aa6fd15d5a9a64286dceed303e9829e1c
Author: Rand Hillerøe <[email protected]>
AuthorDate: Thu Sep 7 22:53:24 2023 +0200
[CXF-8925] Prevent double logging on fault in out chain (#1426)
Signed-off-by: Randi H <[email protected]>
---
.../cxf/ext/logging/LoggingOutInterceptor.java | 5 ++
.../java/org/apache/cxf/ext/logging/FaultTest.java | 69 ++++++++++++++++++++++
.../apache/cxf/ext/logging/LogEventSenderMock.java | 13 +++-
3 files changed, 84 insertions(+), 3 deletions(-)
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 c6673c06dc..7e68a7c5cc 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
@@ -61,6 +61,11 @@ public class LoggingOutInterceptor extends
AbstractLoggingInterceptor {
public void handleMessage(Message message) throws Fault {
if (isLoggingDisabledNow(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);
}
createExchangeId(message);
final OutputStream os = message.getContent(OutputStream.class);
diff --git
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/FaultTest.java
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/FaultTest.java
new file mode 100644
index 0000000000..dd99dcebfa
--- /dev/null
+++
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/FaultTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.ext.logging;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class FaultTest {
+ @Test
+ public void logOnceForFaultsOccurringAfterLoggingOutPhase() throws
IOException {
+
+ Message message = new MessageImpl();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ message.setContent(OutputStream.class, outputStream);
+ Exchange exchange = new ExchangeImpl();
+ message.setExchange(exchange);
+ LogEventSenderMock logEventSender = new LogEventSenderMock();
+ LoggingOutInterceptor interceptor = new
LoggingOutInterceptor(logEventSender);
+
+ interceptor.handleMessage(message);
+ OutputStream preFaultOut = message.getContent(OutputStream.class);
+
+ // simulate fault happening after message is already handled in out
chain
+ interceptor.handleFault(message); // first we unwind
+ interceptor.handleMessage(message); // then we handle in the fault
chain
+
+ byte[] payload = "TestMessage".getBytes(StandardCharsets.UTF_8);
+ // simulate writing that is setup based on the pre-fault output stream
on message
+ // this is what happens when StaxOutInterceptor is in use
+ // StaxOutInterceptor sets XmlStreamWriter content wrapping the
OutputStream in the message at that time
+ // it does not recreate XmlStreamWriter during out fault chain, as it
is already set during out chain
+ preFaultOut.write(payload);
+
+ // Then close is called through close on Conduit,
+ // which means close is called on the OutputStream in message at the
time of close
+ OutputStream postFaultOut = message.getContent(OutputStream.class);
+ postFaultOut.close();
+
+ assertEquals(1, logEventSender.getLogEvents().size());
+ assertEquals("TestMessage",
logEventSender.getLogEvents().get(0).getPayload());
+ }
+}
diff --git
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LogEventSenderMock.java
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LogEventSenderMock.java
index 8f723be169..645faefb74 100644
---
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LogEventSenderMock.java
+++
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LogEventSenderMock.java
@@ -18,20 +18,27 @@
*/
package org.apache.cxf.ext.logging;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.cxf.ext.logging.event.LogEvent;
import org.apache.cxf.ext.logging.event.LogEventSender;
public class LogEventSenderMock implements LogEventSender {
- private LogEvent logEvent;
+ private List<LogEvent> logEvents = new ArrayList<>();
@Override
public void send(LogEvent event) {
- logEvent = event;
+ logEvents.add(event);
}
public LogEvent getLogEvent() {
- return logEvent;
+ return logEvents.isEmpty() ? null : logEvents.get(0);
+ }
+
+ public List<LogEvent> getLogEvents() {
+ return logEvents;
}
}