From a8e48cfb480f325f0d359428672cc7f5cc20d13e Mon Sep 17 00:00:00 2001 From: emartin Date: Fri, 8 Feb 2019 18:22:27 +0000 Subject: Improve ONAP logging compliance Change-Id: I677977f592407d17c7cbd35b034785803c35d327 Issue-ID: DCAEGEN2-1166 Signed-off-by: emartin --- .../services/pmmapper/config/ConfigHandler.java | 33 ++++++--- .../pmmapper/datarouter/DataRouterSubscriber.java | 83 ++++++++++++++-------- .../pmmapper/healthcheck/HealthCheckHandler.java | 17 +++-- .../services/pmmapper/model/MapperConfig.java | 5 +- .../pmmapper/utils/HttpServerExchangeAdapter.java | 62 ++++++++++++++++ .../services/pmmapper/utils/RequestSender.java | 36 +++++++--- src/main/resources/logback.xml | 46 ++++++++++++ .../pmmapper/config/ConfigHandlerTests.java | 11 ++- .../pmmapper/config/util/RequestSenderTests.java | 57 ++++++++------- .../datarouter/DataRouterSubscriberTest.java | 24 ++++++- src/test/java/utils/LoggingUtils.java | 41 +++++++++++ 11 files changed, 332 insertions(+), 83 deletions(-) create mode 100644 src/main/java/org/onap/dcaegen2/services/pmmapper/utils/HttpServerExchangeAdapter.java create mode 100644 src/main/resources/logback.xml create mode 100644 src/test/java/utils/LoggingUtils.java (limited to 'src') diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/config/ConfigHandler.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/config/ConfigHandler.java index 847fff2..0087826 100644 --- a/src/main/java/org/onap/dcaegen2/services/pmmapper/config/ConfigHandler.java +++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/config/ConfigHandler.java @@ -20,6 +20,8 @@ package org.onap.dcaegen2.services.pmmapper.config; import java.util.Arrays; +import java.util.UUID; + import org.onap.dcaegen2.services.pmmapper.exceptions.CBSConfigException; import org.onap.dcaegen2.services.pmmapper.exceptions.CBSServerError; import org.onap.dcaegen2.services.pmmapper.exceptions.ConsulServerError; @@ -30,15 +32,20 @@ import org.onap.dcaegen2.services.pmmapper.model.EnvironmentConfig; import org.onap.dcaegen2.services.pmmapper.model.MapperConfig; import org.onap.dcaegen2.services.pmmapper.utils.RequestSender; 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 com.google.gson.GsonBuilder; -import lombok.extern.slf4j.Slf4j; /** * Handles the retrieval of the component spec-based PM-Mapper Configuration * from DCAE. */ -@Slf4j + public class ConfigHandler { + private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(ConfigHandler.class)); + private static final String EMPTY_MESSAGE = ""; private RequestSender sender; /** @@ -67,37 +74,41 @@ public class ConfigHandler { */ public MapperConfig getMapperConfig() throws CBSConfigException, ConsulServerError, EnvironmentConfigException, CBSServerError, MapperConfigException { + String mapperConfigJson = ""; CBSConfig cbsConfig = convertCBSConfigToObject(getCBSConfigFromConsul()); String cbsSocketAddress = cbsConfig.getServiceAddress() + ":" + cbsConfig.getServicePort(); String requestURL = "http://" + cbsSocketAddress + "/service_component/" + cbsConfig.getServiceName(); - String mapperConfigJson = ""; - log.debug("Fetching mapper configuration from CBS: " + requestURL); try { + logger.unwrap().info(ONAPLogConstants.Markers.ENTRY, "Fetching pm-mapper configuration from Configbinding Service"); mapperConfigJson = sender.send(requestURL); } catch (Exception exception) { throw new CBSServerError("Error connecting to Configbinding Service: ", exception); + } finally { + logger.unwrap().info(ONAPLogConstants.Markers.EXIT, EMPTY_MESSAGE); } + logger.unwrap().info("Received pm-mapper configuration from ConfigBinding Service:\n{}", mapperConfigJson); return convertMapperConfigToObject(mapperConfigJson); } private String getCBSConfigFromConsul() throws ConsulServerError, EnvironmentConfigException { - String cbsParams; + String cbsParams=""; String consulURL = "http://" + EnvironmentConfig.getConsulHost() + ":" + EnvironmentConfig.getConsultPort() + "/v1/catalog/service/" + EnvironmentConfig.getCbsName(); - log.debug(consulURL); try { + logger.unwrap().info(ONAPLogConstants.Markers.ENTRY, + "Retrieving ConfigBinding Service parameters from this Consul URL: {}", consulURL); cbsParams = sender.send(consulURL); } catch (Exception exception) { throw new ConsulServerError("Error connecting to Consul: ", exception); + } finally { + logger.unwrap().info(ONAPLogConstants.Markers.EXIT, "Received ConfigBinding Service parameters:\n{}", cbsParams); } - log.debug("cbsConfig: " + cbsParams); return cbsParams; } private MapperConfig convertMapperConfigToObject(String mapperConfigJson) throws MapperConfigException { - log.debug("mapperConfigJson:" + mapperConfigJson); MapperConfig mapperConfig; try { mapperConfig = new GsonBuilder() @@ -105,10 +116,10 @@ public class ConfigHandler { .create() .fromJson(mapperConfigJson, MapperConfig.class); } catch (Exception exception) { - throw new MapperConfigException("Error parsing mapper configuration: " + mapperConfigJson, exception); + throw new MapperConfigException("Error parsing mapper configuration:\n{}" + mapperConfigJson, exception); } - log.debug("\n" + mapperConfig.toString()); + logger.unwrap().debug("Mapper configuration:\n{}", mapperConfig); return mapperConfig; } @@ -121,7 +132,7 @@ public class ConfigHandler { .create() .fromJson(cbsParameters, CBSConfig[].class)) .get(0); - log.debug("\n\nReceived ConfigBinding Service Configurations: " + cbsConfig); + logger.unwrap().debug("ConfigBinding Service Configurations: " + cbsConfig); } catch (Exception exception) { throw new CBSConfigException( "Error mapping the received ConfigBinding service configuration parameters: " + cbsParameters, diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java index f063a23..a8211e6 100644 --- a/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java +++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java @@ -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(); } } } diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/healthcheck/HealthCheckHandler.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/healthcheck/HealthCheckHandler.java index 2c788b0..756ee7b 100644 --- a/src/main/java/org/onap/dcaegen2/services/pmmapper/healthcheck/HealthCheckHandler.java +++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/healthcheck/HealthCheckHandler.java @@ -22,18 +22,27 @@ 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(); + } } } diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java index f8e428f..b4a9f01 100644 --- a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java +++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java @@ -27,11 +27,12 @@ import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class MapperConfig { + public static final String CLIENT_NAME = "pm-mapper"; @GSONRequired @SerializedName("streams_subscribes.pm_mapper_handle_out.message_router_topic") - private String messageRouterTopicName; - + private String messageRouterTopicName; + BusControllerConfig busControllerConfig; } \ 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 index 0000000..ef5512f --- /dev/null +++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/HttpServerExchangeAdapter.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.dcaegen2.services.pmmapper.utils; + +import io.undertow.server.HttpServerExchange; +import org.onap.logging.ref.slf4j.ONAPLogAdapter.RequestAdapter; + +/** + * Logging Adapter for Undertow's {@link HttpServerExchange} + */ + +public class HttpServerExchangeAdapter implements RequestAdapter{ + + private final HttpServerExchange myRequest; + + /** + * Construct adapter for the request part of {@link HttpServerExchange}. + * @param request to be wrapped; + */ + public HttpServerExchangeAdapter(final HttpServerExchange request) { + this.myRequest = request; + } + + @Override + public String getClientAddress() { + return myRequest.getSourceAddress().getAddress().toString(); + } + + @Override + public String getHeader(String headerName) { + return myRequest.getRequestHeaders().getFirst(headerName); + } + + @Override + public String getRequestURI() { + return myRequest.getRequestURI(); + } + + @Override + public String getServerAddress() { + return myRequest.getHostName(); + } + +} \ No newline at end of file diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java index 1b9cdc6..04f3431 100644 --- a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java +++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java @@ -24,15 +24,22 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.util.UUID; import java.util.stream.Collectors; + +import org.onap.dcaegen2.services.pmmapper.model.MapperConfig; +import org.onap.logging.ref.slf4j.ONAPLogAdapter; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.LoggerFactory; + import lombok.extern.slf4j.Slf4j; -@Slf4j public class RequestSender { private static final int MAX_RETRIES = 5; private static final int RETRY_INTERVAL = 1000; - public static final String SERVER_ERROR_MESSAGE = "Error on Server"; - public static final int ERROR_START_RANGE = 300; + private static final String SERVER_ERROR_MESSAGE = "Error on Server"; + private static final int ERROR_START_RANGE = 300; + private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(RequestSender.class)); /** * Sends an Http GET request to a given endpoint. @@ -41,22 +48,33 @@ public class RequestSender { * @throws Exception * @throws InterruptedException */ - public String send(final String url) throws Exception { - log.debug("RequestSender::send: " + url); + + public String send(final String urlString) throws Exception { + final UUID invocationID = logger.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS); + final UUID requestID = UUID.randomUUID(); String result = ""; + for (int i = 1; i <= MAX_RETRIES; i++) { - URL obj = new URL(url); - HttpURLConnection connection = (HttpURLConnection) obj.openConnection(); + URL url = new URL(urlString); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + 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); + logger.unwrap() + .info("Sending:\n{}", connection.getRequestProperties()); + try (InputStream is = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { result = reader.lines() .collect(Collectors.joining("\n")); int responseCode = connection.getResponseCode(); if (!(isWithinErrorRange(responseCode))) { + logger.unwrap() + .info("Received:\n{}", result); break; } - } catch (Exception e) { + } catch (Exception e) { if (retryLimitReached(i)) { throw new Exception(SERVER_ERROR_MESSAGE + ": " + connection.getResponseMessage(), e); } @@ -74,4 +92,4 @@ public class RequestSender { private boolean isWithinErrorRange(final int responseCode) { return responseCode >= ERROR_START_RANGE; } -} +} \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..0d5d83c --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + ${pattern} + + + + + ${logPath}/${outputFilename}.log + + ${pattern} + + + ${archivePath}/${outputFilename}.%d{yyyy-MM-dd}.%i.log.zip + ${maxFileSize} + ${maxHistory} + ${totalSizeCap} + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/org/onap/dcaegen2/pmmapper/config/ConfigHandlerTests.java b/src/test/java/org/onap/dcaegen2/pmmapper/config/ConfigHandlerTests.java index 0c3fb84..b4a2870 100644 --- a/src/test/java/org/onap/dcaegen2/pmmapper/config/ConfigHandlerTests.java +++ b/src/test/java/org/onap/dcaegen2/pmmapper/config/ConfigHandlerTests.java @@ -19,7 +19,6 @@ */ package org.onap.dcaegen2.pmmapper.config; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; @@ -46,6 +45,10 @@ import org.onap.dcaegen2.services.pmmapper.utils.RequestSender; import com.google.gson.Gson; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import utils.LoggingUtils; + @ExtendWith(MockitoExtension.class) public class ConfigHandlerTests { private static String cbsConfig; @@ -86,6 +89,7 @@ public class ConfigHandlerTests { @Test public void getMapperConfig_success() throws Exception { + ListAppender logAppender = LoggingUtils.getLogListAppender(ConfigHandler.class); when(sender.send(anyString())).then(invocation -> { String url = (String) invocation.getArguments()[0]; return url.equals(consulURL) ? cbsConfig : validMapperConfig; @@ -95,6 +99,11 @@ public class ConfigHandlerTests { MapperConfig expectedConfig = gson.fromJson(validMapperConfig, MapperConfig.class); assertEquals(expectedConfig, actualConfig); + assertEquals(logAppender.list.get(0).getMarker().getName(), "ENTRY"); + assertTrue(logAppender.list.get(1).getMessage().contains("Received ConfigBinding Service parameters")); + assertEquals(logAppender.list.get(1).getMarker().getName(), "EXIT"); + assertTrue(logAppender.list.get(4).getMessage().contains("Received pm-mapper configuration from ConfigBinding Service")); + logAppender.stop(); } @Test diff --git a/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java b/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java index 470f146..770ae43 100644 --- a/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java +++ b/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java @@ -19,13 +19,14 @@ */ package org.onap.dcaegen2.pmmapper.config.util; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockserver.integration.ClientAndServer.startClientAndServer; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; import java.io.IOException; -import java.net.HttpURLConnection; import java.net.URL; import java.net.UnknownHostException; @@ -33,15 +34,19 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Matchers; import org.mockserver.client.server.MockServerClient; import org.mockserver.integration.ClientAndServer; +import org.mockserver.model.HttpRequest; import org.mockserver.model.HttpStatusCode; import org.mockserver.verify.VerificationTimes; import org.onap.dcaegen2.services.pmmapper.utils.RequestSender; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import utils.LoggingUtils; @RunWith(PowerMockRunner.class) @PrepareForTest(RequestSender.class) @@ -60,23 +65,27 @@ public class RequestSenderTests { mockServer.stop(); } - @BeforeClass - public static void setEnvironmentVariable() { - System.setProperty("CONSUL_HOST", "my_consult_host"); - System.setProperty("CONFIG_BINDING_SERVICE", "config-binding-service"); - System.setProperty("HOSTNAME", "hostname"); - } - @Test public void send_success() throws Exception { - - client.when(request()) - .respond(response().withStatusCode(HttpStatusCode.OK_200.code())); - - new RequestSender().send("http://127.0.0.1:1080/once"); - - client.verify(request(), VerificationTimes.exactly(1)); - client.clear(request()); + String url = "http://127.0.0.1:1080/once"; + 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}$"; + ListAppender logAppender = LoggingUtils.getLogListAppender(RequestSender.class); + HttpRequest req = HttpRequest.request(); + + client.when(req + .withHeader(ONAPLogConstants.Headers.REQUEST_ID, uuidRegex) + .withHeader(ONAPLogConstants.Headers.INVOCATION_ID, uuidRegex)) + .respond(response() + .withStatusCode(HttpStatusCode.OK_200.code()) + .withBody("ResponseBody")); + String result = new RequestSender().send(url); + + client.verify(req, VerificationTimes.atLeast(1)); + assertEquals(result, "ResponseBody"); + assertTrue(logAppender.list.get(1).getMessage().contains("Sending")); + assertTrue(logAppender.list.get(2).getMessage().contains("Received")); + logAppender.stop(); + client.clear(req); } @Test @@ -95,17 +104,17 @@ public class RequestSenderTests { } @Test - public void host_unknown() throws IOException { + public void host_unknown() throws Exception { PowerMockito.mockStatic(Thread.class); - URL url = PowerMockito.mock(URL.class); - PowerMockito.when(url.openConnection()) - .thenThrow(UnknownHostException.class); + String unknownHostUrl = "http://unknown-host:1080/host-is-unknown"; + PowerMockito.whenNew(URL.class).withArguments(unknownHostUrl) + .thenThrow(UnknownHostException.class); assertThrows(Exception.class, () -> { - new RequestSender().send("http://127.0.0.1:1080/host-is-unknown"); + new RequestSender().send(unknownHostUrl); }); - client.verify(request(), VerificationTimes.exactly(5)); + client.verify(request(), VerificationTimes.exactly(0)); client.clear(request()); } @@ -113,4 +122,4 @@ public class RequestSenderTests { return new MockServerClient("127.0.0.1", 1080); } -} +} \ No newline at end of file diff --git a/src/test/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriberTest.java b/src/test/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriberTest.java index 645d1be..3239e93 100644 --- a/src/test/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriberTest.java +++ b/src/test/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriberTest.java @@ -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 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 index 0000000..053bd0c --- /dev/null +++ b/src/test/java/utils/LoggingUtils.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package utils; + +import org.slf4j.LoggerFactory; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; + +public class LoggingUtils { + + /** + * Returns a ListAppender that contains all logging events. Call this method at the very beginning of the test + * */ + public static ListAppender getLogListAppender(Class c) { + Logger logger = (Logger) LoggerFactory.getLogger(c); + ListAppender listAppender = new ListAppender<>(); + listAppender.start(); + logger.addAppender(listAppender); + + return listAppender; + } +} -- cgit 1.2.3-korg