153 lines
5.6 KiB
Java
153 lines
5.6 KiB
Java
package com.baeldung.reactive.logging;
|
|
|
|
import ch.qos.logback.classic.spi.LoggingEvent;
|
|
import ch.qos.logback.core.Appender;
|
|
import com.baeldung.reactive.logging.filters.LogFilters;
|
|
import com.baeldung.reactive.logging.jetty.RequestLogEnhancer;
|
|
import com.baeldung.reactive.logging.netty.CustomLogger;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import java.net.URI;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.Data;
|
|
import org.eclipse.jetty.client.api.Request;
|
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.http.client.reactive.JettyClientHttpConnector;
|
|
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
|
import org.springframework.web.reactive.function.BodyInserters;
|
|
import org.springframework.web.reactive.function.client.WebClient;
|
|
import reactor.netty.channel.BootstrapHandlers;
|
|
import reactor.netty.http.client.HttpClient;
|
|
|
|
import static org.mockito.ArgumentMatchers.argThat;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
|
public class WebClientLoggingIntegrationTest {
|
|
|
|
@AllArgsConstructor
|
|
@Data
|
|
class Post {
|
|
private String title;
|
|
private String body;
|
|
private int userId;
|
|
}
|
|
|
|
private Appender jettyAppender;
|
|
private Appender nettyAppender;
|
|
private Appender mockAppender;
|
|
private String sampleUrl = "https://jsonplaceholder.typicode.com/posts";
|
|
|
|
private Post post;
|
|
private String sampleResponseBody;
|
|
|
|
@BeforeEach
|
|
private void setup() throws Exception {
|
|
|
|
post = new Post("Learn WebClient logging with Baeldung!", "", 1);
|
|
sampleResponseBody = new ObjectMapper().writeValueAsString(post);
|
|
|
|
ch.qos.logback.classic.Logger jetty = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.baeldung.reactive.logging.jetty");
|
|
jettyAppender = mock(Appender.class);
|
|
when(jettyAppender.getName()).thenReturn("com.baeldung.reactive.logging.jetty");
|
|
jetty.addAppender(jettyAppender);
|
|
|
|
ch.qos.logback.classic.Logger netty = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("reactor.netty.http.client");
|
|
nettyAppender = mock(Appender.class);
|
|
when(nettyAppender.getName()).thenReturn("reactor.netty.http.client");
|
|
netty.addAppender(nettyAppender);
|
|
|
|
ch.qos.logback.classic.Logger test = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.baeldung.reactive");
|
|
mockAppender = mock(Appender.class);
|
|
when(mockAppender.getName()).thenReturn("com.baeldung.reactive");
|
|
test.addAppender(mockAppender);
|
|
|
|
}
|
|
|
|
@Test
|
|
public void givenJettyHttpClient_whenEndpointIsConsumed_thenRequestAndResponseBodyShouldBeLogged() {
|
|
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
|
org.eclipse.jetty.client.HttpClient httpClient = new org.eclipse.jetty.client.HttpClient(sslContextFactory) {
|
|
@Override
|
|
public Request newRequest(URI uri) {
|
|
Request request = super.newRequest(uri);
|
|
return new RequestLogEnhancer().enhance(request);
|
|
}
|
|
};
|
|
|
|
WebClient
|
|
.builder()
|
|
.clientConnector(new JettyClientHttpConnector(httpClient))
|
|
.build()
|
|
.post()
|
|
.uri(sampleUrl)
|
|
.body(BodyInserters.fromObject(post))
|
|
.retrieve()
|
|
.bodyToMono(String.class)
|
|
.block();
|
|
|
|
verify(jettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody)));
|
|
}
|
|
|
|
@Test
|
|
public void givenNettyHttpClientWithWiretap_whenEndpointIsConsumed_thenRequestAndResponseBodyShouldBeLogged() {
|
|
|
|
reactor.netty.http.client.HttpClient httpClient = HttpClient
|
|
.create()
|
|
.wiretap(true);
|
|
WebClient
|
|
.builder()
|
|
.clientConnector(new ReactorClientHttpConnector(httpClient))
|
|
.build()
|
|
.post()
|
|
.uri(sampleUrl)
|
|
.body(BodyInserters.fromObject(post))
|
|
.exchange()
|
|
.block();
|
|
verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains("00000300")));
|
|
}
|
|
|
|
@Test
|
|
public void givenNettyHttpClientWithCustomLogger_whenEndpointIsConsumed_thenRequestAndResponseBodyShouldBeLogged() {
|
|
|
|
reactor.netty.http.client.HttpClient httpClient = HttpClient
|
|
.create()
|
|
.tcpConfiguration(
|
|
tc -> tc.bootstrap(
|
|
b -> BootstrapHandlers.updateLogSupport(b, new CustomLogger(HttpClient.class))));
|
|
WebClient
|
|
.builder()
|
|
.clientConnector(new ReactorClientHttpConnector(httpClient))
|
|
.build()
|
|
.post()
|
|
.uri(sampleUrl)
|
|
.body(BodyInserters.fromObject(post))
|
|
.exchange()
|
|
.block();
|
|
verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody)));
|
|
}
|
|
|
|
@Test
|
|
public void givenDefaultHttpClientWithString_whenEndpointIsConsumed_thenRequestAndResponseLogged() {
|
|
WebClient
|
|
.builder()
|
|
.filters(exchangeFilterFunctions -> {
|
|
exchangeFilterFunctions.addAll(LogFilters.prepareFilters());
|
|
})
|
|
.build()
|
|
.post()
|
|
.uri(sampleUrl)
|
|
.body(BodyInserters.fromObject(post))
|
|
.exchange()
|
|
.block();
|
|
|
|
verify(mockAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains("domain=.typicode.com;")));
|
|
}
|
|
|
|
|
|
}
|