Skip to content
This repository has been archived by the owner on May 28, 2018. It is now read-only.

Defer print of headers until all WriterInterceptors are done #3794

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

import java.io.IOException;
import java.io.OutputStream;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -99,18 +100,22 @@ public void filter(final ClientRequestContext context) throws IOException {
final long id = _id.incrementAndGet();
context.setProperty(LOGGING_ID_PROPERTY, id);

final StringBuilder b = new StringBuilder();
Supplier<StringBuilder> sbs = () -> {
final StringBuilder b = new StringBuilder();

printRequestLine(b, "Sending client request", id, context.getMethod(), context.getUri());
printPrefixedHeaders(b, id, REQUEST_PREFIX, context::getStringHeaders);

printRequestLine(b, "Sending client request", id, context.getMethod(), context.getUri());
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getStringHeaders());
return b;
};

if (context.hasEntity() && printEntity(verbosity, context.getMediaType())) {
final OutputStream stream = new LoggingStream(b, context.getEntityStream());
final OutputStream stream = new LoggingStream(sbs, context.getEntityStream());
context.setEntityStream(stream);
context.setProperty(ENTITY_LOGGER_PROPERTY, stream);
// not calling log(b) here - it will be called by the interceptor
} else {
log(b);
log(sbs.get());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -197,6 +198,14 @@ void printPrefixedHeaders(final StringBuilder b,
}
}

void printPrefixedHeaders(final StringBuilder b,
final long id,
final String prefix,
final Supplier<MultivaluedMap<String, String>> lazyHeaders) {
MultivaluedMap<String, String> headers = lazyHeaders.get();
printPrefixedHeaders(b, id, prefix, headers);
}

Set<Map.Entry<String, List<String>>> getSortedHeaders(final Set<Map.Entry<String, List<String>>> headers) {
final TreeSet<Map.Entry<String, List<String>>> sortedHeaders = new TreeSet<Map.Entry<String, List<String>>>(COMPARATOR);
sortedHeaders.addAll(headers);
Expand Down Expand Up @@ -266,7 +275,7 @@ static boolean printEntity(Verbosity verbosity, MediaType mediaType) {
*/
class LoggingStream extends FilterOutputStream {

private final StringBuilder b;
private final Supplier<StringBuilder> sbs;
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();

/**
Expand All @@ -276,15 +285,26 @@ class LoggingStream extends FilterOutputStream {
* @param inner the underlying output stream.
*/
LoggingStream(final StringBuilder b, final OutputStream inner) {
this(() -> b, inner);
}

/**
* Creates {@code LoggingStream} with the entity supplier and the underlying output stream as parameters.
*
* @param sbs contains the entity supplier to log.
* @param inner the underlying output stream.
*/
LoggingStream(final Supplier<StringBuilder> sbs, final OutputStream inner) {
super(inner);

this.b = b;
this.sbs = sbs;
}

StringBuilder getStringBuilder(final Charset charset) {
// write entity to the builder
final byte[] entity = baos.toByteArray();

StringBuilder b = sbs.get();
b.append(new String(entity, 0, Math.min(entity.length, maxEntitySize), charset));
if (entity.length > maxEntitySize) {
b.append("...more...");
Expand Down