logging of HttpResponse use raw body 83/95583/1
authorEylon Malin <eylon.malin@intl.att.com>
Thu, 12 Sep 2019 14:02:46 +0000 (17:02 +0300)
committerEylon Malin <eylon.malin@intl.att.com>
Thu, 12 Sep 2019 14:02:46 +0000 (17:02 +0300)
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 <eylon.malin@intl.att.com>
Change-Id: If138531f515fb2927a13417040b68e81babebc4e

vid-app-common/src/main/java/org/onap/vid/utils/Logging.java
vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java
vid-app-common/src/test/java/org/onap/vid/utils/LoggingUtilsTest.java

index 77b7ee8..0d8e588 100644 (file)
@@ -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 <T> void logResponse(final EELFLogger logger, final HttpMethod method, final String url, final HttpResponse<T> 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());
index 66052ad..6cdb1bd 100644 (file)
@@ -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 <T> HttpResponse<T> createTestHttpResponse(int statusCode, T entity, final Class<T> 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;
index c22b59c..6cbb14a 100644 (file)
@@ -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<TestModel> response = TestUtils.createTestHttpResponse(200, testObject, TestModel.class);
+        logginService.logResponse(loggerMock, HttpMethod.POST, url, response);
+
+        ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
+        ArgumentCaptor<String> 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<TestModel> 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<TestModel> 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");