From c729cb1356a3bacead0d9d63920c889966f64bdd Mon Sep 17 00:00:00 2001 From: Eylon Malin Date: Thu, 12 Sep 2019 17:02:46 +0300 Subject: logging of HttpResponse use raw body print raw body for cases like errors make sure the response can be read logging it Issue-ID: VID-611 Signed-off-by: Eylon Malin Change-Id: If138531f515fb2927a13417040b68e81babebc4e --- .../src/main/java/org/onap/vid/utils/Logging.java | 6 ++- .../java/org/onap/vid/testUtils/TestUtils.java | 13 +++++ .../java/org/onap/vid/utils/LoggingUtilsTest.java | 56 +++++++++++++++++++++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java index 77b7ee869..0d8e58878 100644 --- a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java +++ b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java @@ -31,11 +31,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.google.common.collect.ImmutableList; import io.joshworks.restclient.http.HttpResponse; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Optional; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.util.SystemProperties; @@ -123,7 +125,9 @@ public class Logging { public void logResponse(final EELFLogger logger, final HttpMethod method, final String url, final HttpResponse response) { try { - logger.debug("Received {} {} Status: {} . Body: {}", method.name(), url, response.getStatus(), response.getBody()); + logger.debug("Received {} {} Status: {} . Body: {}", method.name(), + url, response.getStatus(), IOUtils.toString(response.getRawBody(), StandardCharsets.UTF_8)); + response.getRawBody().reset(); } catch (Exception e) { logger.debug("Received {} {} Status: {} . Failed to read response", method.name(), url, response.getStatus()); diff --git a/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java b/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java index 66052adeb..6cdb1bdb3 100644 --- a/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java +++ b/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java @@ -34,6 +34,8 @@ import static org.mockito.Mockito.RETURNS_DEFAULTS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.Mockito.withSettings; +import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; +import static org.onap.vid.utils.KotlinUtilsKt.JOSHWORKS_JACKSON_OBJECT_MAPPER; import static org.testng.Assert.fail; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -66,6 +68,7 @@ import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.reflect.MethodUtils; import org.apache.commons.text.RandomStringGenerator; import org.apache.http.HttpResponseFactory; +import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.message.BasicStatusLine; @@ -253,6 +256,16 @@ public class TestUtils { return new HttpResponse<>(response, String.class, null); } + public static HttpResponse createTestHttpResponse(int statusCode, T entity, final Class entityClass) throws Exception { + HttpResponseFactory factory = new DefaultHttpResponseFactory(); + org.apache.http.HttpResponse response = factory.newHttpResponse(new BasicStatusLine(HTTP_1_1, statusCode, null), null); + if (entity != null) { + InputStream inputStream = IOUtils.toInputStream(JACKSON_OBJECT_MAPPER.writeValueAsString(entity), StandardCharsets.UTF_8.name()); + response.setEntity(new InputStreamEntity(inputStream)); + } + return new HttpResponse(response, entityClass, JOSHWORKS_JACKSON_OBJECT_MAPPER); + } + public static class JavaxRsClientMocks { private final javax.ws.rs.client.Client fakeClient; diff --git a/vid-app-common/src/test/java/org/onap/vid/utils/LoggingUtilsTest.java b/vid-app-common/src/test/java/org/onap/vid/utils/LoggingUtilsTest.java index c22b59c69..6cbb14ac2 100644 --- a/vid-app-common/src/test/java/org/onap/vid/utils/LoggingUtilsTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/utils/LoggingUtilsTest.java @@ -20,7 +20,9 @@ package org.onap.vid.utils; +import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; import static org.mockito.ArgumentMatchers.contains; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -31,15 +33,19 @@ import com.att.eelf.configuration.EELFLogger; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; +import io.joshworks.restclient.http.HttpResponse; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import javax.crypto.BadPaddingException; import javax.net.ssl.SSLHandshakeException; import javax.ws.rs.ProcessingException; +import org.apache.commons.io.IOUtils; import org.mockito.ArgumentCaptor; import org.onap.vid.exceptions.GenericUncheckedException; +import org.onap.vid.testUtils.TestUtils; import org.springframework.http.HttpMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; @@ -49,9 +55,26 @@ import sun.security.validator.ValidatorException; public class LoggingUtilsTest { + private static final String TEST_OBJECT_JSON = "{\"key\":\"myNumber\",\"value\":42}"; + + public static class TestModel { + public String key; + public int value; + + public TestModel(String key, int value) { + this.key = key; + this.value = value; + } + + public TestModel() {} + } + private EELFLogger loggerMock; private Logging logginService = new Logging(); + private String url = "someUrl"; + private final TestModel testObject = new TestModel("myNumber", 42); + @BeforeMethod public void setUp() { @@ -61,7 +84,6 @@ public class LoggingUtilsTest { @Test public void whenLogRequest_thenLoggedInDebug() { //when - String url = "someUrl"; logginService.logRequest(loggerMock, HttpMethod.GET, url); //then @@ -71,6 +93,38 @@ public class LoggingUtilsTest { assertEquals(url, argumentCaptor.getAllValues().get(1)); } + + + @Test + public void whenLogResponseOfHttpResponse_thenLoggedInDebug() throws Exception { + HttpResponse response = TestUtils.createTestHttpResponse(200, testObject, TestModel.class); + logginService.logResponse(loggerMock, HttpMethod.POST, url, response); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Object.class); + ArgumentCaptor messageCaptur = ArgumentCaptor.forClass(String.class); + verify(loggerMock).debug(messageCaptur.capture(), argumentCaptor.capture()); + + assertThat(messageCaptur.getValue(), matchesPattern("Received.*Status.*Body.*")); + assertEquals("POST", argumentCaptor.getAllValues().get(0)); + assertEquals(url, argumentCaptor.getAllValues().get(1)); + assertEquals(200, argumentCaptor.getAllValues().get(2)); + assertEquals(TEST_OBJECT_JSON, argumentCaptor.getAllValues().get(3)); + } + + @Test + public void whenLogResponseOfHttpResponse_thenCanReadEntityAfterwards() throws Exception { + HttpResponse response = TestUtils.createTestHttpResponse(200, testObject, TestModel.class); + logginService.logResponse(loggerMock, HttpMethod.POST, url, response); + assertThat(response.getBody(), jsonEquals(TEST_OBJECT_JSON)); + } + + @Test + public void whenLogResponseOfHttpResponse_thenCanReadRawEntityAfterwards() throws Exception { + HttpResponse response = TestUtils.createTestHttpResponse(200, testObject, TestModel.class); + logginService.logResponse(loggerMock, HttpMethod.POST, url, response); + assertThat(IOUtils.toString(response.getRawBody(), StandardCharsets.UTF_8), jsonEquals(TEST_OBJECT_JSON)); + } + @DataProvider public static Object[][] exceptions() { Exception e0 = new CertificateException("No X509TrustManager implementation available"); -- cgit 1.2.3-korg