You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by de...@apache.org on 2018/01/21 12:14:19 UTC
[cxf] branch master updated: [CXF-7562] ext.logging: truncated flag
not set closes #340
This is an automated email from the ASF dual-hosted git repository.
deki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/master by this push:
new 62ba50c [CXF-7562] ext.logging: truncated flag not set closes #340
62ba50c is described below
commit 62ba50cc2cf934865d4646785137167cd44c29ff
Author: Franz Forsthofer <fr...@sap.com>
AuthorDate: Sun Jan 21 13:13:02 2018 +0100
[CXF-7562] ext.logging: truncated flag not set closes #340
---
.../cxf/ext/logging/LoggingInInterceptor.java | 39 +++++-
.../cxf/ext/logging/LoggingOutInterceptor.java | 32 +++--
.../apache/cxf/ext/logging/LogEventSenderMock.java | 37 +++++
.../org/apache/cxf/ext/logging/TruncatedTest.java | 149 +++++++++++++++++++++
4 files changed, 242 insertions(+), 15 deletions(-)
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 8ba700e..8d06c7d 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
@@ -35,6 +35,7 @@ import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.io.CachedWriter;
import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptor;
@@ -43,11 +44,25 @@ import org.apache.cxf.phase.PhaseInterceptor;
*/
@NoJSR250Annotations
public class LoggingInInterceptor extends AbstractLoggingInterceptor {
-
+ class LoggingInFaultInterceptor extends AbstractPhaseInterceptor<Message> {
+ LoggingInFaultInterceptor() {
+ super(Phase.RECEIVE);
+ }
+
+ @Override
+ public void handleMessage(Message message) throws Fault {
+ }
+
+ @Override
+ public void handleFault(Message message) throws Fault {
+ LoggingInInterceptor.this.handleMessage(message);
+ }
+ }
+
public LoggingInInterceptor() {
this(new Slf4jVerboseEventSender());
}
-
+
public LoggingInInterceptor(PrintWriter writer) {
this(new PrintWriterEventSender(writer));
}
@@ -55,11 +70,11 @@ public class LoggingInInterceptor extends AbstractLoggingInterceptor {
public LoggingInInterceptor(LogEventSender sender) {
super(Phase.PRE_INVOKE, sender);
}
-
public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
Collection<PhaseInterceptor<? extends Message>> ret = new ArrayList<>();
- ret.add(new WireTapIn(limit, threshold));
+ ret.add(new WireTapIn(getWireTapLimit(), threshold));
+ ret.add(new LoggingInFaultInterceptor());
return ret;
}
@@ -94,7 +109,7 @@ public class LoggingInInterceptor extends AbstractLoggingInterceptor {
}
private void handleOutputStream(final LogEvent event, Message message, CachedOutputStream cos) throws IOException {
- String encoding = (String)message.get(Message.ENCODING);
+ String encoding = (String) message.get(Message.ENCODING);
if (StringUtils.isEmpty(encoding)) {
encoding = StandardCharsets.UTF_8.name();
}
@@ -116,5 +131,19 @@ public class LoggingInInterceptor extends AbstractLoggingInterceptor {
event.setFullContentFile(writer.getTempFile());
}
+ int getWireTapLimit() {
+ if (limit == -1) {
+ return -1;
+ } else if (limit == Integer.MAX_VALUE) {
+ return limit;
+ } else {
+ // add limit +1 as limit for the wiretab in order to read one byte more, so that truncated
+ // is correctly calculated in LogginInIntecepteor!
+ // See code line : boolean isTruncated = cos.size() > limit && limit != -1;
+ // cos is here the outputstream read by the wiretab which will return for cos.size() the
+ // limit in the truncated case!
+ return limit + 1;
+ }
+ }
}
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 93a7a0b..9a8d71f 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
@@ -49,7 +49,7 @@ public class LoggingOutInterceptor extends AbstractLoggingInterceptor {
public LoggingOutInterceptor() {
this(new Slf4jVerboseEventSender());
}
-
+
public LoggingOutInterceptor(PrintWriter writer) {
this(new PrintWriterEventSender(writer));
}
@@ -82,12 +82,22 @@ public class LoggingOutInterceptor extends AbstractLoggingInterceptor {
newOut.setThreshold(threshold);
}
if (limit > 0) {
- newOut.setCacheLimit(limit);
+ // make the limit for the cache greater than the limit for the truncated payload in the log event,
+ // this is necessary for finding out that the payload was truncated
+ //(see boolean isTruncated = cos.size() > limit && limit != -1;) in method copyPayload
+ newOut.setCacheLimit(getCacheLimit());
}
newOut.registerCallback(callback);
return newOut;
}
+ private int getCacheLimit() {
+ if (limit == Integer.MAX_VALUE) {
+ return limit;
+ }
+ return limit + 1;
+ }
+
private class LogEventSendingWriter extends FilterWriter {
StringWriter out2;
int count;
@@ -133,7 +143,7 @@ public class LoggingOutInterceptor extends AbstractLoggingInterceptor {
final LogEvent event = new DefaultLogEventMapper().map(message);
StringWriter w2 = out2;
if (w2 == null) {
- w2 = (StringWriter)out;
+ w2 = (StringWriter) out;
}
String payload = shouldLogContent(event) ? getPayload(event, w2) : CONTENT_SUPPRESSED;
@@ -144,23 +154,23 @@ public class LoggingOutInterceptor extends AbstractLoggingInterceptor {
}
private String getPayload(final LogEvent event, StringWriter w2) {
- String ct = (String)message.get(Message.CONTENT_TYPE);
StringBuilder payload = new StringBuilder();
try {
- writePayload(payload, w2, ct);
+ writePayload(payload, w2, event);
} catch (Exception ex) {
// ignore
}
return payload.toString();
}
- protected void writePayload(StringBuilder builder, StringWriter stringWriter, String contentType)
- throws Exception {
+ protected void writePayload(StringBuilder builder, StringWriter stringWriter, LogEvent event) throws Exception {
StringBuffer buffer = stringWriter.getBuffer();
if (buffer.length() > lim) {
builder.append(buffer.subSequence(0, lim));
+ event.setTruncated(true);
} else {
builder.append(buffer);
+ event.setTruncated(false);
}
}
}
@@ -204,17 +214,19 @@ public class LoggingOutInterceptor extends AbstractLoggingInterceptor {
private void copyPayload(CachedOutputStream cos, final LogEvent event) {
try {
- String encoding = (String)message.get(Message.ENCODING);
+ String encoding = (String) message.get(Message.ENCODING);
StringBuilder payload = new StringBuilder();
writePayload(payload, cos, encoding, event.getContentType());
event.setPayload(payload.toString());
+ boolean isTruncated = cos.size() > limit && limit != -1;
+ event.setTruncated(isTruncated);
} catch (Exception ex) {
// ignore
}
}
- protected void writePayload(StringBuilder builder, CachedOutputStream cos, String encoding,
- String contentType) throws Exception {
+ protected void writePayload(StringBuilder builder, CachedOutputStream cos, String encoding, String contentType)
+ throws Exception {
if (StringUtils.isEmpty(encoding)) {
cos.writeCacheTo(builder, lim);
} else {
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
new file mode 100644
index 0000000..8f723be
--- /dev/null
+++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LogEventSenderMock.java
@@ -0,0 +1,37 @@
+/**
+ * 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 org.apache.cxf.ext.logging.event.LogEvent;
+import org.apache.cxf.ext.logging.event.LogEventSender;
+
+public class LogEventSenderMock implements LogEventSender {
+
+ private LogEvent logEvent;
+
+ @Override
+ public void send(LogEvent event) {
+ logEvent = event;
+ }
+
+ public LogEvent getLogEvent() {
+ return logEvent;
+ }
+
+}
diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/TruncatedTest.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/TruncatedTest.java
new file mode 100644
index 0000000..a7567fc
--- /dev/null
+++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/TruncatedTest.java
@@ -0,0 +1,149 @@
+/**
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+
+import org.apache.cxf.ext.logging.event.LogEvent;
+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.apache.cxf.phase.PhaseInterceptor;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+
+
+public class TruncatedTest {
+
+ @Test
+ public void truncatedOutboundInterceptorOutputStream() 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.setLimit(1); // set limit to 1 byte in order to get a truncated message!
+ interceptor.handleMessage(message);
+ byte[] payload = "TestMessage".getBytes(StandardCharsets.UTF_8);
+
+ OutputStream out = message.getContent(OutputStream.class);
+ out.write(payload);
+ out.close();
+ LogEvent event = logEventSender.getLogEvent();
+ assertNotNull(event);
+ assertEquals("T", event.getPayload()); // only the first byte is read!
+ assertTrue(event.isTruncated());
+ }
+
+ @Test
+ public void truncatedOutboundInterceptorWriter() throws IOException {
+
+ Message message = new MessageImpl();
+ StringWriter stringWriter = new StringWriter();
+ message.setContent(Writer.class, stringWriter);
+ Exchange exchange = new ExchangeImpl();
+ message.setExchange(exchange);
+ LogEventSenderMock logEventSender = new LogEventSenderMock();
+ LoggingOutInterceptor interceptor = new LoggingOutInterceptor(logEventSender);
+ interceptor.setLimit(1); // set limit to 1 byte in order to get a truncated message!
+ interceptor.handleMessage(message);
+
+ Writer out = message.getContent(Writer.class);
+ out.write("TestMessage");
+ out.close();
+ LogEvent event = logEventSender.getLogEvent();
+ assertNotNull(event);
+ assertEquals("T", event.getPayload()); // only the first byte is read!
+ assertTrue(event.isTruncated());
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Test
+ public void truncatedInboundInterceptorInputStream() throws IOException {
+
+ Message message = new MessageImpl();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream("TestMessage".getBytes(StandardCharsets.UTF_8));
+ message.setContent(InputStream.class, inputStream);
+ Exchange exchange = new ExchangeImpl();
+ message.setExchange(exchange);
+ LogEventSenderMock logEventSender = new LogEventSenderMock();
+ LoggingInInterceptor interceptor = new LoggingInInterceptor(logEventSender);
+ interceptor.setLimit(1); // set limit to 1 byte in order to get a truncated message!
+
+ Collection<PhaseInterceptor<? extends Message>> interceptors = interceptor.getAdditionalInterceptors();
+ for (PhaseInterceptor intercept : interceptors) {
+ intercept.handleMessage(message);
+ }
+
+ interceptor.handleMessage(message);
+
+ LogEvent event = logEventSender.getLogEvent();
+ assertNotNull(event);
+ assertEquals("T", event.getPayload()); // only the first byte is read!
+ assertTrue(event.isTruncated());
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Test
+ public void truncatedInboundInterceptorReader() throws IOException {
+
+ Message message = new MessageImpl();
+ StringReader stringReader = new StringReader("TestMessage");
+ message.setContent(Reader.class, stringReader);
+ Exchange exchange = new ExchangeImpl();
+ message.setExchange(exchange);
+ LogEventSenderMock logEventSender = new LogEventSenderMock();
+ LoggingInInterceptor interceptor = new LoggingInInterceptor(logEventSender);
+ interceptor.setLimit(1); // set limit to 1 byte in order to get a truncated message!
+
+ Collection<PhaseInterceptor<? extends Message>> interceptors = interceptor.getAdditionalInterceptors();
+ for (PhaseInterceptor intercept : interceptors) {
+ intercept.handleMessage(message);
+ }
+
+ interceptor.handleMessage(message);
+
+ LogEvent event = logEventSender.getLogEvent();
+ assertNotNull(event);
+ assertEquals("T", event.getPayload()); // only the first byte is read!
+ assertTrue(event.isTruncated());
+ }
+
+
+
+}
--
To stop receiving notification emails like this one, please contact
['"commits@cxf.apache.org" <co...@cxf.apache.org>'].