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 ++++++++++++ 7 files changed, 225 insertions(+), 57 deletions(-) create mode 100644 src/main/java/org/onap/dcaegen2/services/pmmapper/utils/HttpServerExchangeAdapter.java create mode 100644 src/main/resources/logback.xml (limited to 'src/main') 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 -- cgit 1.2.3-korg