Improve ONAP logging compliance 10/77910/5
authoremartin <ephraim.martin@est.tech>
Fri, 8 Feb 2019 18:22:27 +0000 (18:22 +0000)
committeremartin <ephraim.martin@est.tech>
Fri, 8 Feb 2019 18:22:27 +0000 (18:22 +0000)
Change-Id: I677977f592407d17c7cbd35b034785803c35d327
Issue-ID: DCAEGEN2-1166
Signed-off-by: emartin <ephraim.martin@est.tech>
12 files changed:
pom.xml
src/main/java/org/onap/dcaegen2/services/pmmapper/config/ConfigHandler.java
src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java
src/main/java/org/onap/dcaegen2/services/pmmapper/healthcheck/HealthCheckHandler.java
src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java
src/main/java/org/onap/dcaegen2/services/pmmapper/utils/HttpServerExchangeAdapter.java [new file with mode: 0644]
src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java
src/main/resources/logback.xml [new file with mode: 0644]
src/test/java/org/onap/dcaegen2/pmmapper/config/ConfigHandlerTests.java
src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java
src/test/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriberTest.java
src/test/java/utils/LoggingUtils.java [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index 50d4cdb..3b95207 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,7 @@
         <compiler.source.version>1.8</compiler.source.version>
         <shade.main>org.onap.dcaegen2.services.pmmapper.App</shade.main>
         <shade.transformer>org.apache.maven.plugins.shade.resource.ManifestResourceTransformer</shade.transformer>
+        <onap.logging.version>1.2.2</onap.logging.version>
     </properties>
 
     <dependencies>
             <artifactId>logback-classic</artifactId>
             <version>${logback.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.onap.logging-analytics</groupId>
+            <artifactId>logging-slf4j</artifactId>
+            <version>${onap.logging.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
index 847fff2..0087826 100644 (file)
@@ -20,6 +20,8 @@
 package org.onap.dcaegen2.services.pmmapper.config;\r
 \r
 import java.util.Arrays;\r
+import java.util.UUID;\r
+\r
 import org.onap.dcaegen2.services.pmmapper.exceptions.CBSConfigException;\r
 import org.onap.dcaegen2.services.pmmapper.exceptions.CBSServerError;\r
 import org.onap.dcaegen2.services.pmmapper.exceptions.ConsulServerError;\r
@@ -30,15 +32,20 @@ import org.onap.dcaegen2.services.pmmapper.model.EnvironmentConfig;
 import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;\r
 import org.onap.dcaegen2.services.pmmapper.utils.RequestSender;\r
 import org.onap.dcaegen2.services.pmmapper.utils.RequiredFieldDeserializer;\r
+\r
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;\r
+import org.onap.logging.ref.slf4j.ONAPLogConstants;\r
+import org.slf4j.LoggerFactory;\r
 import com.google.gson.GsonBuilder;\r
-import lombok.extern.slf4j.Slf4j;\r
 \r
 /**\r
  * Handles the retrieval of the component spec-based PM-Mapper Configuration\r
  * from DCAE.\r
  */\r
-@Slf4j\r
+\r
 public class ConfigHandler {\r
+    private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(ConfigHandler.class));\r
+    private static final String EMPTY_MESSAGE = "";\r
     private RequestSender sender;\r
 \r
     /**\r
@@ -67,37 +74,41 @@ public class ConfigHandler {
      */
     public MapperConfig getMapperConfig() throws CBSConfigException, ConsulServerError, EnvironmentConfigException,\r
             CBSServerError, MapperConfigException {\r
+        String mapperConfigJson = "";\r
         CBSConfig cbsConfig = convertCBSConfigToObject(getCBSConfigFromConsul());\r
         String cbsSocketAddress = cbsConfig.getServiceAddress() + ":" + cbsConfig.getServicePort();\r
         String requestURL = "http://" + cbsSocketAddress + "/service_component/" + cbsConfig.getServiceName();\r
-        String mapperConfigJson = "";\r
-        log.debug("Fetching mapper configuration from CBS: " + requestURL);\r
         try {\r
+            logger.unwrap().info(ONAPLogConstants.Markers.ENTRY, "Fetching pm-mapper configuration from Configbinding Service");\r
             mapperConfigJson = sender.send(requestURL);\r
         } catch (Exception exception) {\r
             throw new CBSServerError("Error connecting to Configbinding Service: ", exception);\r
+        } finally {\r
+            logger.unwrap().info(ONAPLogConstants.Markers.EXIT, EMPTY_MESSAGE);\r
         }\r
 \r
+        logger.unwrap().info("Received pm-mapper configuration from ConfigBinding Service:\n{}", mapperConfigJson);\r
         return convertMapperConfigToObject(mapperConfigJson);\r
     }\r
 \r
     private String getCBSConfigFromConsul() throws ConsulServerError, EnvironmentConfigException {\r
-        String cbsParams;\r
+        String cbsParams="";\r
         String consulURL = "http://" + EnvironmentConfig.getConsulHost() + ":" + EnvironmentConfig.getConsultPort()\r
                 + "/v1/catalog/service/" + EnvironmentConfig.getCbsName();\r
-        log.debug(consulURL);\r
         try {\r
+            logger.unwrap().info(ONAPLogConstants.Markers.ENTRY,\r
+                    "Retrieving ConfigBinding Service parameters from this Consul URL: {}", consulURL);\r
             cbsParams = sender.send(consulURL);\r
         } catch (Exception exception) {\r
             throw new ConsulServerError("Error connecting to Consul: ", exception);\r
+        } finally {\r
+            logger.unwrap().info(ONAPLogConstants.Markers.EXIT, "Received ConfigBinding Service parameters:\n{}", cbsParams);\r
         }\r
 \r
-        log.debug("cbsConfig: " + cbsParams);\r
         return cbsParams;\r
     }\r
 \r
     private MapperConfig convertMapperConfigToObject(String mapperConfigJson) throws MapperConfigException {\r
-        log.debug("mapperConfigJson:" + mapperConfigJson);\r
         MapperConfig mapperConfig;\r
         try {\r
             mapperConfig = new GsonBuilder()\r
@@ -105,10 +116,10 @@ public class ConfigHandler {
                     .create()\r
                     .fromJson(mapperConfigJson, MapperConfig.class);\r
         } catch (Exception exception) {\r
-            throw new MapperConfigException("Error parsing mapper configuration: " + mapperConfigJson, exception);\r
+            throw new MapperConfigException("Error parsing mapper configuration:\n{}" + mapperConfigJson, exception);\r
         }\r
 \r
-        log.debug("\n" + mapperConfig.toString());\r
+        logger.unwrap().debug("Mapper configuration:\n{}", mapperConfig);\r
         return mapperConfig;\r
     }\r
 \r
@@ -121,7 +132,7 @@ public class ConfigHandler {
                             .create()\r
                             .fromJson(cbsParameters, CBSConfig[].class))\r
                     .get(0);\r
-            log.debug("\n\nReceived ConfigBinding Service Configurations: " + cbsConfig);\r
+            logger.unwrap().debug("ConfigBinding Service Configurations: " + cbsConfig);\r
         } catch (Exception exception) {\r
             throw new CBSConfigException(\r
                     "Error mapping the received ConfigBinding service configuration parameters: " + cbsParameters,\r
index f063a23..a8211e6 100644 (file)
@@ -31,14 +31,18 @@ import lombok.NonNull;
 import org.onap.dcaegen2.services.pmmapper.exceptions.NoMetadataException;
 import org.onap.dcaegen2.services.pmmapper.exceptions.TooManyTriesException;
 import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
+import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
 import org.onap.dcaegen2.services.pmmapper.model.BusControllerConfig;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
 import io.undertow.server.HttpHandler;
 import io.undertow.server.HttpServerExchange;
 import io.undertow.util.StatusCodes;
 
-import lombok.extern.slf4j.Slf4j;
+import org.onap.dcaegen2.services.pmmapper.utils.HttpServerExchangeAdapter;
 import org.onap.dcaegen2.services.pmmapper.utils.RequiredFieldDeserializer;
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.io.OutputStream;
@@ -47,15 +51,15 @@ import java.net.HttpURLConnection;
 import java.nio.charset.StandardCharsets;
 import java.util.Optional;
 import java.util.Random;
+import java.util.UUID;
 
 /**
  * Subscriber for events sent from data router
  * Provides an undertow HttpHandler to be used as an endpoint for data router to send events to.
  */
-@Slf4j
 @Data
 public class DataRouterSubscriber implements HttpHandler {
-
+    private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(DataRouterSubscriber.class));
     private static final int NUMBER_OF_ATTEMPTS = 5;
     private static final int DEFAULT_TIMEOUT = 2000;
     private static final int MAX_JITTER = 50;
@@ -88,7 +92,12 @@ public class DataRouterSubscriber implements HttpHandler {
      * @throws TooManyTriesException in the event that timeout has occurred several times.
      */
     public void start(BusControllerConfig config) throws TooManyTriesException, InterruptedException {
-        subscribe(NUMBER_OF_ATTEMPTS, DEFAULT_TIMEOUT, config);
+        try {
+            logger.unwrap().info(ONAPLogConstants.Markers.ENTRY, "Starting subscription to DataRouter");
+            subscribe(NUMBER_OF_ATTEMPTS, DEFAULT_TIMEOUT, config);
+        } finally {
+            logger.unwrap().info(ONAPLogConstants.Markers.EXIT, "");
+        }
     }
 
     private HttpURLConnection getBusControllerConnection(BusControllerConfig config, int timeout) throws IOException {
@@ -99,6 +108,13 @@ public class DataRouterSubscriber implements HttpHandler {
         connection.setReadTimeout(timeout);
         connection.setRequestProperty("Content-Type", "application/json");
         connection.setDoOutput(true);
+
+        final UUID invocationID = logger.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS);
+        final UUID requestID = UUID.randomUUID();
+        connection.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID, requestID.toString());
+        connection.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID, invocationID.toString());
+        connection.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME, MapperConfig.CLIENT_NAME);
+
         return connection;
     }
 
@@ -126,9 +142,9 @@ public class DataRouterSubscriber implements HttpHandler {
             subResponse = connection.getResponseCode();
             subMessage = connection.getResponseMessage();
         } catch (IOException e) {
-            log.info("Timeout Failure:", e);
+            logger.unwrap().error("Timeout Failure:", e);
         }
-        log.info("Request to bus controller executed with Response Code: '{}' and Response Event: '{}'.", subResponse, subMessage);
+        logger.unwrap().info("Request to bus controller executed with Response Code: '{}' and Response Event: '{}'.", subResponse, subMessage);
         if (subResponse >= 300 && attempts > 1) {
             Thread.sleep(timeout);
             subscribe(--attempts, (timeout * 2) + jitterGenerator.nextInt(MAX_JITTER), config);
@@ -146,33 +162,38 @@ public class DataRouterSubscriber implements HttpHandler {
      */
     @Override
     public void handleRequest(HttpServerExchange httpServerExchange) {
-        if (limited) {
-            httpServerExchange.setStatusCode(StatusCodes.SERVICE_UNAVAILABLE)
-                    .getResponseSender()
-                    .send(StatusCodes.SERVICE_UNAVAILABLE_STRING);
-        } else {
-            try {
-                String metadataAsString = Optional.of(httpServerExchange.getRequestHeaders()
-                        .get(METADATA_HEADER))
-                        .map((HeaderValues headerValues) -> headerValues.get(0))
-                        .orElseThrow(() -> new NoMetadataException("Metadata Not found"));
-
-                EventMetadata metadata = metadataBuilder.fromJson(metadataAsString, EventMetadata.class);
-                httpServerExchange.getRequestReceiver()
-                        .receiveFullString((callbackExchange, body) -> {
-                            httpServerExchange.dispatch(() -> eventReceiver.receive(new Event(callbackExchange, body, metadata)));
-                        });
-            } catch (NoMetadataException exception) {
-                log.info("Bad Request: no metadata found under '{}' header.", METADATA_HEADER, exception);
-                httpServerExchange.setStatusCode(StatusCodes.BAD_REQUEST)
-                        .getResponseSender()
-                        .send(NO_METADATA_MESSAGE);
-            } catch (JsonParseException exception) {
-                log.info("Bad Request: Failure to parse metadata", exception);
-                httpServerExchange.setStatusCode(StatusCodes.BAD_REQUEST)
+        try{
+            logger.entering(new HttpServerExchangeAdapter(httpServerExchange));
+            if (limited) {
+                httpServerExchange.setStatusCode(StatusCodes.SERVICE_UNAVAILABLE)
                         .getResponseSender()
-                        .send(BAD_METADATA_MESSAGE);
+                        .send(StatusCodes.SERVICE_UNAVAILABLE_STRING);
+            } else {
+                try {
+                    String metadataAsString = Optional.of(httpServerExchange.getRequestHeaders()
+                            .get(METADATA_HEADER))
+                            .map((HeaderValues headerValues) -> headerValues.get(0))
+                            .orElseThrow(() -> new NoMetadataException("Metadata Not found"));
+
+                    EventMetadata metadata = metadataBuilder.fromJson(metadataAsString, EventMetadata.class);
+                    httpServerExchange.getRequestReceiver()
+                            .receiveFullString((callbackExchange, body) -> {
+                                httpServerExchange.dispatch(() -> eventReceiver.receive(new Event(callbackExchange, body, metadata)));
+                            });
+                } catch (NoMetadataException exception) {
+                    logger.unwrap().info("Bad Request: no metadata found under '{}' header.", METADATA_HEADER, exception);
+                    httpServerExchange.setStatusCode(StatusCodes.BAD_REQUEST)
+                            .getResponseSender()
+                            .send(NO_METADATA_MESSAGE);
+                } catch (JsonParseException exception) {
+                    logger.unwrap().info("Bad Request: Failure to parse metadata", exception);
+                    httpServerExchange.setStatusCode(StatusCodes.BAD_REQUEST)
+                            .getResponseSender()
+                            .send(BAD_METADATA_MESSAGE);
+                }
             }
+        } finally {
+            logger.exiting();
         }
     }
 }
index 2c788b0..756ee7b 100644 (file)
 
 package org.onap.dcaegen2.services.pmmapper.healthcheck;
 
+import org.onap.dcaegen2.services.pmmapper.utils.HttpServerExchangeAdapter;
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;
+import org.slf4j.LoggerFactory;
+
 import io.undertow.server.HttpHandler;
 import io.undertow.server.HttpServerExchange;
 import io.undertow.util.StatusCodes;
 
 public class HealthCheckHandler implements HttpHandler {
-
+    private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(HealthCheckHandler.class));
     @Override
     public void handleRequest(HttpServerExchange exchange) {
+        try {
+            logger.entering(new HttpServerExchangeAdapter(exchange));
+            exchange.setStatusCode(StatusCodes.OK)
+                    .getResponseSender()
+                    .send(StatusCodes.OK_STRING);
 
-        exchange.setStatusCode(StatusCodes.OK)
-                .getResponseSender()
-                .send(StatusCodes.OK_STRING);
+        } finally {
+            logger.exiting();
+        }
     }
 
 }
index f8e428f..b4a9f01 100644 (file)
@@ -27,11 +27,12 @@ import lombok.NoArgsConstructor;
 @Data\r
 @NoArgsConstructor\r
 public class MapperConfig {\r
+    public static final String CLIENT_NAME = "pm-mapper";\r
 \r
     @GSONRequired\r
     @SerializedName("streams_subscribes.pm_mapper_handle_out.message_router_topic")\r
-    private String messageRouterTopicName;\r
-
+    private String messageRouterTopicName;
+\r
     BusControllerConfig busControllerConfig;\r
 \r
 }
\ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/HttpServerExchangeAdapter.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/HttpServerExchangeAdapter.java
new file mode 100644 (file)
index 0000000..ef5512f
--- /dev/null
@@ -0,0 +1,62 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ *  Copyright (C) 2019 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.dcaegen2.services.pmmapper.utils;\r
+\r
+import io.undertow.server.HttpServerExchange;\r
+import org.onap.logging.ref.slf4j.ONAPLogAdapter.RequestAdapter;\r
+\r
+/**\r
+ * Logging Adapter for Undertow's {@link HttpServerExchange}\r
+ */\r
+\r
+public class HttpServerExchangeAdapter implements RequestAdapter<HttpServerExchangeAdapter>{\r
+\r
+    private final HttpServerExchange myRequest;\r
+\r
+    /**\r
+     * Construct adapter for the request part of {@link HttpServerExchange}.\r
+     * @param request to be wrapped;\r
+     */\r
+    public HttpServerExchangeAdapter(final HttpServerExchange request) {\r
+        this.myRequest = request;\r
+    }\r
+\r
+    @Override\r
+    public String getClientAddress() {\r
+        return myRequest.getSourceAddress().getAddress().toString();\r
+    }\r
+\r
+    @Override\r
+    public String getHeader(String headerName) {\r
+        return myRequest.getRequestHeaders().getFirst(headerName);\r
+    }\r
+\r
+    @Override\r
+    public String getRequestURI() {\r
+        return myRequest.getRequestURI();\r
+    }\r
+\r
+    @Override\r
+    public String getServerAddress() {\r
+       return myRequest.getHostName();\r
+    }\r
+\r
+}
\ No newline at end of file
index 1b9cdc6..04f3431 100644 (file)
@@ -24,15 +24,22 @@ import java.io.InputStream;
 import java.io.InputStreamReader;\r
 import java.net.HttpURLConnection;\r
 import java.net.URL;\r
+import java.util.UUID;\r
 import java.util.stream.Collectors;\r
+\r
+import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;\r
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;\r
+import org.onap.logging.ref.slf4j.ONAPLogConstants;\r
+import org.slf4j.LoggerFactory;\r
+\r
 import lombok.extern.slf4j.Slf4j;\r
 \r
-@Slf4j\r
 public class RequestSender {\r
     private static final int MAX_RETRIES = 5;\r
     private static final int RETRY_INTERVAL = 1000;\r
-    public static final String SERVER_ERROR_MESSAGE = "Error on Server";\r
-    public static final int ERROR_START_RANGE = 300;\r
+    private static final String SERVER_ERROR_MESSAGE = "Error on Server";\r
+    private static final int ERROR_START_RANGE = 300;\r
+    private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(RequestSender.class));\r
 \r
     /**\r
      * Sends an Http GET request to a given endpoint.\r
@@ -41,22 +48,33 @@ public class RequestSender {
      * @throws Exception\r
      * @throws InterruptedException\r
      */\r
-    public String send(final String url) throws Exception {\r
-        log.debug("RequestSender::send: " + url);\r
+\r
+    public String send(final String urlString) throws Exception {\r
+        final UUID invocationID = logger.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS);\r
+        final UUID requestID = UUID.randomUUID();\r
         String result = "";\r
+\r
         for (int i = 1; i <= MAX_RETRIES; i++) {\r
-            URL obj = new URL(url);\r
-            HttpURLConnection connection = (HttpURLConnection) obj.openConnection();\r
+            URL url = new URL(urlString);\r
+            HttpURLConnection connection = (HttpURLConnection) url.openConnection();\r
+            connection.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID, requestID.toString());\r
+            connection.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID, invocationID.toString());\r
+            connection.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME, MapperConfig.CLIENT_NAME);\r
+            logger.unwrap()\r
+                    .info("Sending:\n{}", connection.getRequestProperties());\r
+\r
             try (InputStream is = connection.getInputStream();\r
                     BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {\r
                 result = reader.lines()\r
                         .collect(Collectors.joining("\n"));\r
                 int responseCode = connection.getResponseCode();\r
                 if (!(isWithinErrorRange(responseCode))) {\r
+                    logger.unwrap()\r
+                            .info("Received:\n{}", result);\r
                     break;\r
                 }\r
 \r
-            } catch (Exception e) {
+            } catch (Exception e) {\r
                 if (retryLimitReached(i)) {\r
                     throw new Exception(SERVER_ERROR_MESSAGE + ": " + connection.getResponseMessage(), e);\r
                 }\r
@@ -74,4 +92,4 @@ public class RequestSender {
     private boolean isWithinErrorRange(final int responseCode) {\r
         return responseCode >= ERROR_START_RANGE;\r
     }\r
-}\r
+}
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..0d5d83c
--- /dev/null
@@ -0,0 +1,46 @@
+<configuration>\r
+    <property name="outputFilename" value="pm-mapper_output"/>\r
+    <property name="logPath" value="/var/log/ONAP/dcaegen2/services/pm-mapper"/>\r
+    <property name="archivePath" value="${logPath}/archive"/>\r
+    <property name="maxFileSize" value="50MB"/>\r
+    <property name="maxHistory" value="30"/>\r
+    <property name="totalSizeCap" value="10GB"/>\r
+    <property name="p_tim" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}"/>\r
+    <property name="p_lvl" value="%level"/>\r
+    <property name="p_log" value="%logger"/>\r
+    <property name="p_mdc" value="%replace(%replace(%mdc){'\t','\\\\t'}){'\n', '\\\\n'}"/>\r
+    <property name="p_msg" value="%replace(%replace(%msg){'\t', '\\\\t'}){'\n','\\\\n'}"/>\r
+    <property name="p_exc" value="%replace(%replace(%rootException){'\t', '\\\\t'}){'\n','\\\\n'}"/>\r
+    <property name="p_mak" value="%replace(%replace(%marker){'\t', '\\\\t'}){'\n','\\\\n'}"/>\r
+    <property name="p_thr" value="%thread"/>\r
+    <property name="pattern" value="%nopexception${p_tim}\t${p_thr}\t${p_lvl}\t${p_log}\t${p_mdc}\t${p_msg}\t${p_exc}\t${p_mak}\t%n"/>\r
+\r
+    <variable name="logLevel" value="${LOG_LEVEL:-INFO}"/>\r
+\r
+    <logger name="org.mockserver" level="${mockserver.logLevel:-OFF}"/>\r
+\r
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">\r
+        <encoder>\r
+            <pattern>${pattern}</pattern>\r
+        </encoder>\r
+    </appender>\r
+\r
+    <appender name="ROLLING-FILE" class="ch.qos.logback.core.FileAppender">\r
+        <file>${logPath}/${outputFilename}.log</file>\r
+        <encoder>\r
+            <pattern>${pattern}</pattern>\r
+        </encoder>\r
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">\r
+        <FileNamePattern>${archivePath}/${outputFilename}.%d{yyyy-MM-dd}.%i.log.zip</FileNamePattern>\r
+        <MaxFileSize>${maxFileSize}</MaxFileSize>\r
+        <MaxHistory>${maxHistory}</MaxHistory>\r
+        <TotalSizeCap>${totalSizeCap}</TotalSizeCap>\r
+      </rollingPolicy>\r
+    </appender>\r
+\r
+    <root level="${logLevel}" additivity="false">\r
+        <appender-ref ref="CONSOLE" />\r
+        <appender-ref ref="ROLLING-FILE" />\r
+    </root>\r
+\r
+</configuration>
\ No newline at end of file
index 0c3fb84..b4a2870 100644 (file)
@@ -19,7 +19,6 @@
  */\r
 package org.onap.dcaegen2.pmmapper.config;\r
 \r
-import static org.junit.jupiter.api.Assertions.assertThrows;\r
 import static org.junit.jupiter.api.Assertions.*;\r
 import static org.mockito.Mockito.when;\r
 \r
@@ -46,6 +45,10 @@ import org.onap.dcaegen2.services.pmmapper.utils.RequestSender;
 \r
 import com.google.gson.Gson;\r
 \r
+import ch.qos.logback.classic.spi.ILoggingEvent;\r
+import ch.qos.logback.core.read.ListAppender;\r
+import utils.LoggingUtils;\r
+\r
 @ExtendWith(MockitoExtension.class)\r
 public class ConfigHandlerTests {\r
     private static String cbsConfig;\r
@@ -86,6 +89,7 @@ public class ConfigHandlerTests {
 \r
     @Test\r
     public void getMapperConfig_success() throws Exception {\r
+        ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(ConfigHandler.class);\r
         when(sender.send(anyString())).then(invocation -> {\r
             String url = (String) invocation.getArguments()[0];\r
             return url.equals(consulURL) ? cbsConfig : validMapperConfig;\r
@@ -95,6 +99,11 @@ public class ConfigHandlerTests {
         MapperConfig expectedConfig = gson.fromJson(validMapperConfig, MapperConfig.class);\r
 \r
         assertEquals(expectedConfig, actualConfig);\r
+        assertEquals(logAppender.list.get(0).getMarker().getName(), "ENTRY");\r
+        assertTrue(logAppender.list.get(1).getMessage().contains("Received ConfigBinding Service parameters"));\r
+        assertEquals(logAppender.list.get(1).getMarker().getName(), "EXIT");\r
+        assertTrue(logAppender.list.get(4).getMessage().contains("Received pm-mapper configuration from ConfigBinding Service"));\r
+        logAppender.stop();\r
     }\r
 \r
     @Test\r
index 470f146..770ae43 100644 (file)
  */\r
 package org.onap.dcaegen2.pmmapper.config.util;\r
 \r
+import static org.junit.jupiter.api.Assertions.assertEquals;\r
 import static org.junit.jupiter.api.Assertions.assertThrows;\r
+import static org.junit.jupiter.api.Assertions.assertTrue;\r
 import static org.mockserver.integration.ClientAndServer.startClientAndServer;\r
 import static org.mockserver.model.HttpRequest.request;\r
 import static org.mockserver.model.HttpResponse.response;\r
 \r
 import java.io.IOException;\r
-import java.net.HttpURLConnection;\r
 import java.net.URL;\r
 import java.net.UnknownHostException;\r
 \r
@@ -33,15 +34,19 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;\r
 import org.junit.Test;\r
 import org.junit.runner.RunWith;\r
-import org.mockito.Matchers;\r
 import org.mockserver.client.server.MockServerClient;\r
 import org.mockserver.integration.ClientAndServer;\r
+import org.mockserver.model.HttpRequest;\r
 import org.mockserver.model.HttpStatusCode;\r
 import org.mockserver.verify.VerificationTimes;\r
 import org.onap.dcaegen2.services.pmmapper.utils.RequestSender;\r
+import org.onap.logging.ref.slf4j.ONAPLogConstants;\r
 import org.powermock.api.mockito.PowerMockito;\r
 import org.powermock.core.classloader.annotations.PrepareForTest;\r
 import org.powermock.modules.junit4.PowerMockRunner;\r
+import ch.qos.logback.classic.spi.ILoggingEvent;\r
+import ch.qos.logback.core.read.ListAppender;\r
+import utils.LoggingUtils;\r
 \r
 @RunWith(PowerMockRunner.class)\r
 @PrepareForTest(RequestSender.class)\r
@@ -60,23 +65,27 @@ public class RequestSenderTests {
         mockServer.stop();\r
     }\r
 \r
-    @BeforeClass\r
-    public static void setEnvironmentVariable() {\r
-        System.setProperty("CONSUL_HOST", "my_consult_host");\r
-        System.setProperty("CONFIG_BINDING_SERVICE", "config-binding-service");\r
-        System.setProperty("HOSTNAME", "hostname");\r
-    }\r
-\r
     @Test\r
     public void send_success() throws Exception {\r
-\r
-        client.when(request())\r
-                .respond(response().withStatusCode(HttpStatusCode.OK_200.code()));\r
-\r
-        new RequestSender().send("http://127.0.0.1:1080/once");\r
-\r
-        client.verify(request(), VerificationTimes.exactly(1));\r
-        client.clear(request());\r
+        String url = "http://127.0.0.1:1080/once";\r
+        String uuidRegex = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$";\r
+        ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(RequestSender.class);\r
+        HttpRequest req = HttpRequest.request();\r
+\r
+        client.when(req\r
+                .withHeader(ONAPLogConstants.Headers.REQUEST_ID, uuidRegex)\r
+                .withHeader(ONAPLogConstants.Headers.INVOCATION_ID, uuidRegex))\r
+                .respond(response()\r
+                        .withStatusCode(HttpStatusCode.OK_200.code())\r
+                        .withBody("ResponseBody"));\r
+        String result = new RequestSender().send(url);\r
+\r
+        client.verify(req, VerificationTimes.atLeast(1));\r
+        assertEquals(result, "ResponseBody");\r
+        assertTrue(logAppender.list.get(1).getMessage().contains("Sending"));\r
+        assertTrue(logAppender.list.get(2).getMessage().contains("Received"));\r
+        logAppender.stop();\r
+        client.clear(req);\r
     }\r
 \r
     @Test\r
@@ -95,17 +104,17 @@ public class RequestSenderTests {
     }\r
 \r
     @Test\r
-    public void host_unknown() throws IOException {\r
+    public void host_unknown() throws Exception {\r
         PowerMockito.mockStatic(Thread.class);\r
-        URL url = PowerMockito.mock(URL.class);\r
-        PowerMockito.when(url.openConnection())\r
-                .thenThrow(UnknownHostException.class);\r
+        String unknownHostUrl = "http://unknown-host:1080/host-is-unknown";\r
+        PowerMockito.whenNew(URL.class).withArguments(unknownHostUrl)\r
+            .thenThrow(UnknownHostException.class);\r
 \r
         assertThrows(Exception.class, () -> {\r
-            new RequestSender().send("http://127.0.0.1:1080/host-is-unknown");\r
+            new RequestSender().send(unknownHostUrl);\r
         });\r
 \r
-        client.verify(request(), VerificationTimes.exactly(5));\r
+        client.verify(request(), VerificationTimes.exactly(0));\r
         client.clear(request());\r
     }\r
 \r
@@ -113,4 +122,4 @@ public class RequestSenderTests {
         return new MockServerClient("127.0.0.1", 1080);\r
     }\r
 \r
-}\r
+}
\ No newline at end of file
index 645d1be..3239e93 100644 (file)
@@ -29,14 +29,21 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.read.ListAppender;
 import io.undertow.io.Receiver;
 import io.undertow.io.Sender;
 import io.undertow.server.HttpServerExchange;
 import io.undertow.util.StatusCodes;
+import utils.LoggingUtils;
+
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -53,10 +60,11 @@ import org.onap.dcaegen2.services.pmmapper.exceptions.TooManyTriesException;
 import org.onap.dcaegen2.services.pmmapper.model.BusControllerConfig;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
 import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
+import org.onap.dcaegen2.services.pmmapper.utils.HttpServerExchangeAdapter;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
-
+import org.slf4j.LoggerFactory;
 
 @RunWith(PowerMockRunner.class)
 @PrepareForTest(DataRouterSubscriber.class)
@@ -139,6 +147,9 @@ public class DataRouterSubscriberTest {
     @Test
     public void testRequestInboundLimitedStateServiceUnavailable() throws Exception {
         HttpServerExchange httpServerExchange = mock(HttpServerExchange.class);
+        HttpServerExchangeAdapter adapterMock = PowerMockito.mock(HttpServerExchangeAdapter.class);
+        PowerMockito.whenNew(HttpServerExchangeAdapter.class).withAnyArguments().thenReturn(adapterMock);
+
         Sender responseSender = mock(Sender.class);
         when(httpServerExchange.setStatusCode(anyInt())).thenReturn(httpServerExchange);
         when(httpServerExchange.getResponseSender()).thenReturn(responseSender);
@@ -150,6 +161,9 @@ public class DataRouterSubscriberTest {
     @Test
     public void testRequestInboundLimitedStateServiceNoEmission() throws Exception {
         HttpServerExchange httpServerExchange = mock(HttpServerExchange.class);
+        HttpServerExchangeAdapter adapterMock = PowerMockito.mock(HttpServerExchangeAdapter.class);
+        PowerMockito.whenNew(HttpServerExchangeAdapter.class).withAnyArguments().thenReturn(adapterMock);
+
         Sender responseSender = mock(Sender.class);
         when(httpServerExchange.setStatusCode(anyInt())).thenReturn(httpServerExchange);
         when(httpServerExchange.getResponseSender()).thenReturn(responseSender);
@@ -197,6 +211,7 @@ public class DataRouterSubscriberTest {
 
     @Test
     public void testRequestInboundSuccess() throws Exception {
+        ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(DataRouterSubscriber.class);
         HttpServerExchange httpServerExchange = mock(HttpServerExchange.class, RETURNS_DEEP_STUBS);
         Receiver receiver = mock(Receiver.class);
         when(httpServerExchange.getRequestReceiver()).thenReturn(receiver);
@@ -222,5 +237,12 @@ public class DataRouterSubscriberTest {
                 .receive(new Event(httpServerExchange, testString,
                         new GsonBuilder().create()
                                 .fromJson(metadata, EventMetadata.class)));
+
+        assertEquals(logAppender.list.get(0).getMarker().getName(), "ENTRY");
+        assertNotNull(logAppender.list.get(0).getMDCPropertyMap().get("InvocationID"));
+        assertNotNull(logAppender.list.get(0).getMDCPropertyMap().get("RequestID"));
+        assertEquals(logAppender.list.get(1).getMarker().getName(), "EXIT");
+        logAppender.stop();
     }
+
 }
diff --git a/src/test/java/utils/LoggingUtils.java b/src/test/java/utils/LoggingUtils.java
new file mode 100644 (file)
index 0000000..053bd0c
--- /dev/null
@@ -0,0 +1,41 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ *  Copyright (C) 2019 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package utils;\r
+\r
+import org.slf4j.LoggerFactory;\r
+import ch.qos.logback.classic.Logger;\r
+import ch.qos.logback.classic.spi.ILoggingEvent;\r
+import ch.qos.logback.core.read.ListAppender;\r
+\r
+public class LoggingUtils {\r
+\r
+    /**\r
+     * Returns a ListAppender that contains all logging events. Call this method at the very beginning of the test\r
+     * */\r
+    public static ListAppender<ILoggingEvent> getLogListAppender(Class<?> c) {\r
+        Logger logger = (Logger) LoggerFactory.getLogger(c);\r
+        ListAppender<ILoggingEvent> listAppender = new ListAppender<>();\r
+        listAppender.start();\r
+        logger.addAppender(listAppender);\r
+\r
+        return listAppender;\r
+    }\r
+}\r