-/*-\r
- * ============LICENSE_START=======================================================\r
- * ONAP CLAMP\r
- * ================================================================================\r
- * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights\r
- * reserved.\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
- * ============LICENSE_END============================================\r
- * ===================================================================\r
- *\r
- */\r
-\r
-package org.onap.clamp.clds.util;\r
-\r
-import com.att.eelf.configuration.EELFLogger;\r
-import com.att.eelf.configuration.EELFManager;\r
-\r
-import java.net.HttpURLConnection;\r
-import java.net.InetAddress;\r
-import java.net.UnknownHostException;\r
-import java.text.DateFormat;\r
-import java.text.SimpleDateFormat;\r
-import java.time.ZoneOffset;\r
-import java.time.ZonedDateTime;\r
-import java.time.format.DateTimeFormatter;\r
-import java.util.Date;\r
-import java.util.TimeZone;\r
-import java.util.UUID;\r
-\r
-import javax.net.ssl.HttpsURLConnection;\r
-import javax.servlet.http.HttpServletRequest;\r
-import javax.validation.constraints.NotNull;\r
-\r
-import org.onap.clamp.clds.service.DefaultUserNameHandler;\r
-import org.slf4j.MDC;\r
-import org.slf4j.event.Level;\r
-import org.springframework.security.core.context.SecurityContextHolder;\r
-\r
-/**\r
- * This class handles the special info that appear in the log, like RequestID,\r
- * time context, ...\r
- */\r
-public class LoggingUtils {\r
- protected static final EELFLogger logger = EELFManager.getInstance().getLogger(LoggingUtils.class);\r
-\r
- private static final DateFormat DATE_FORMAT = createDateFormat();\r
-\r
- /** String constant for messages <tt>ENTERING</tt>, <tt>EXITING</tt>, etc. */\r
- private static final String EMPTY_MESSAGE = "";\r
-\r
- /** Logger delegate. */\r
- private EELFLogger mlogger;\r
- /** Automatic UUID, overrideable per adapter or per invocation. */\r
- private static UUID sInstanceUUID = UUID.randomUUID();\r
-\r
- /**\r
- * Constructor.\r
- */\r
- public LoggingUtils(final EELFLogger loggerP) {\r
- this.mlogger = checkNotNull(loggerP);\r
- }\r
-\r
- /**\r
- * Set request related logging variables in thread local data via MDC\r
- *\r
- * @param service Service Name of API (ex. "PUT template")\r
- * @param partner Partner name (client or user invoking API)\r
- */\r
- public static void setRequestContext(String service, String partner) {\r
- MDC.put("RequestId", UUID.randomUUID().toString());\r
- MDC.put("ServiceName", service);\r
- MDC.put("PartnerName", partner);\r
- //Defaulting to HTTP/1.1 protocol\r
- MDC.put("Protocol", "HTTP/1.1");\r
- try {\r
- MDC.put("ServerFQDN", InetAddress.getLocalHost().getCanonicalHostName());\r
- MDC.put("ServerIPAddress", InetAddress.getLocalHost().getHostAddress());\r
- } catch (UnknownHostException e) {\r
- logger.error("Failed to initiate setRequestContext", e);\r
- }\r
- }\r
-\r
- /**\r
- * Set time related logging variables in thread local data via MDC.\r
- *\r
- * @param beginTimeStamp Start time\r
- * @param endTimeStamp End time\r
- */\r
- public static void setTimeContext(@NotNull Date beginTimeStamp, @NotNull Date endTimeStamp) {\r
- MDC.put("BeginTimestamp", generateTimestampStr(beginTimeStamp));\r
- MDC.put("EndTimestamp", generateTimestampStr(endTimeStamp));\r
- MDC.put("ElapsedTime", String.valueOf(endTimeStamp.getTime() - beginTimeStamp.getTime()));\r
- }\r
-\r
- /**\r
- * Set response related logging variables in thread local data via MDC.\r
- *\r
- * @param code Response code ("0" indicates success)\r
- * @param description Response description\r
- * @param className class name of invoking class\r
- */\r
- public static void setResponseContext(String code, String description, String className) {\r
- MDC.put("ResponseCode", code);\r
- MDC.put("StatusCode", code.equals("0") ? "COMPLETE" : "ERROR");\r
- MDC.put("ResponseDescription", description != null ? description : "");\r
- MDC.put("ClassName", className != null ? className : "");\r
- }\r
-\r
- /**\r
- * Set target related logging variables in thread local data via MDC\r
- *\r
- * @param targetEntity Target entity (an external/sub component, for ex. "sdc")\r
- * @param targetServiceName Target service name (name of API invoked on target)\r
- */\r
- public static void setTargetContext(String targetEntity, String targetServiceName) {\r
- MDC.put("TargetEntity", targetEntity != null ? targetEntity : "");\r
- MDC.put("TargetServiceName", targetServiceName != null ? targetServiceName : "");\r
- }\r
-\r
- /**\r
- * Set error related logging variables in thread local data via MDC.\r
- *\r
- * @param code Error code\r
- * @param description Error description\r
- */\r
- public static void setErrorContext(String code, String description) {\r
- MDC.put("ErrorCode", code);\r
- MDC.put("ErrorDescription", description != null ? description : "");\r
- }\r
-\r
- private static String generateTimestampStr(Date timeStamp) {\r
- return DATE_FORMAT.format(timeStamp);\r
- }\r
-\r
- /**\r
- * Get a previously stored RequestID for the thread local data via MDC. If\r
- * one was not previously stored, generate one, store it, and return that\r
- * one.\r
- *\r
- * @return A string with the request ID\r
- */\r
- public static String getRequestId() {\r
- String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);\r
- if (requestId == null || requestId.isEmpty()) {\r
- requestId = UUID.randomUUID().toString();\r
- MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);\r
- }\r
- return requestId;\r
- }\r
-\r
- private static DateFormat createDateFormat() {\r
- DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");\r
- dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));\r
- return dateFormat;\r
- }\r
-\r
-\r
-\r
- /*********************************************************************************************\r
- * Method for ONAP Application Logging Specification v1.2\r
- ********************************************************************************************/\r
-\r
- /**\r
- * Report <tt>ENTERING</tt> marker.\r
- *\r
- * @param request non-null incoming request (wrapper)\r
- * @param serviceName service name\r
- */\r
- public void entering(HttpServletRequest request, String serviceName) {\r
- MDC.clear();\r
- checkNotNull(request);\r
- // Extract MDC values from standard HTTP headers.\r
- final String requestId = defaultToUUID(request.getHeader(ONAPLogConstants.Headers.REQUEST_ID));\r
- final String invocationId = defaultToUUID(request.getHeader(ONAPLogConstants.Headers.INVOCATION_ID));\r
- final String partnerName = defaultToEmpty(request.getHeader(ONAPLogConstants.Headers.PARTNER_NAME));\r
-\r
- // Default the partner name to the user name used to login to clamp\r
- if (partnerName.equalsIgnoreCase(EMPTY_MESSAGE)) {\r
- MDC.put(ONAPLogConstants.MDCs.PARTNER_NAME, new DefaultUserNameHandler()\r
- .retrieveUserName(SecurityContextHolder.getContext()));\r
- }\r
-\r
- // Set standard MDCs. Override this entire method if you want to set\r
- // others, OR set them BEFORE or AFTER the invocation of #entering,\r
- // depending on where you need them to appear, OR extend the\r
- // ServiceDescriptor to add them.\r
- MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP,\r
- ZonedDateTime.now(ZoneOffset.UTC)\r
- .format(DateTimeFormatter.ISO_INSTANT));\r
- MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);\r
- MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, invocationId);\r
- MDC.put(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS, defaultToEmpty(request.getRemoteAddr()));\r
- MDC.put(ONAPLogConstants.MDCs.SERVER_FQDN, defaultToEmpty(request.getServerName()));\r
- MDC.put(ONAPLogConstants.MDCs.INSTANCE_UUID, defaultToEmpty(sInstanceUUID));\r
-\r
- // Default the service name to the requestURI, in the event that\r
- // no value has been provided.\r
- if (serviceName == null\r
- || serviceName.equalsIgnoreCase(EMPTY_MESSAGE)) {\r
- MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI());\r
- } else {\r
- MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, serviceName);\r
- }\r
-\r
- this.mlogger.info(ONAPLogConstants.Markers.ENTRY);\r
- }\r
-\r
- /**\r
- * Report <tt>EXITING</tt> marker.\r
- *\r
- * @param code response code\r
- * @param descrption response description\r
- * @param severity response severity\r
- * @param status response status code\r
- */\r
- public void exiting(String code, String descrption, Level severity, ONAPLogConstants.ResponseStatus status) {\r
- try {\r
- MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, defaultToEmpty(code));\r
- MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, defaultToEmpty(descrption));\r
- MDC.put(ONAPLogConstants.MDCs.RESPONSE_SEVERITY, defaultToEmpty(severity));\r
- MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, defaultToEmpty(status));\r
- this.mlogger.info(ONAPLogConstants.Markers.EXIT);\r
- }\r
- finally {\r
- MDC.clear();\r
- }\r
- }\r
-\r
- /**\r
- * Report pending invocation with <tt>INVOKE</tt> marker,\r
- * setting standard ONAP logging headers automatically.\r
- *\r
- * @param con http URL connection\r
- * @param targetEntity target entity\r
- * @param targetServiceName target service name\r
- * @return invocation ID to be passed with invocation\r
- */\r
- public HttpURLConnection invoke(final HttpURLConnection con, String targetEntity, String targetServiceName) {\r
- final String invocationId = UUID.randomUUID().toString();\r
-\r
- // Set standard HTTP headers on (southbound request) builder.\r
- con.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID,\r
- defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)));\r
- con.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID,\r
- invocationId);\r
- con.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME,\r
- defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)));\r
-\r
- invokeContext(targetEntity, targetServiceName, invocationId);\r
-\r
- // Log INVOKE*, with the invocationID as the message body.\r
- // (We didn't really want this kind of behavior in the standard,\r
- // but is it worse than new, single-message MDC?)\r
- this.mlogger.info(ONAPLogConstants.Markers.INVOKE);\r
- this.mlogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{" + invocationId + "}");\r
- return con;\r
- }\r
-\r
- /**\r
- * Report pending invocation with <tt>INVOKE</tt> marker,\r
- * setting standard ONAP logging headers automatically.\r
- *\r
- * @param con http URL connection\r
- * @param targetEntity target entity\r
- * @param targetServiceName target service name\r
- * @return invocation ID to be passed with invocation\r
- */\r
- public HttpsURLConnection invokeHttps(final HttpsURLConnection con, String targetEntity, String targetServiceName) {\r
- final String invocationId = UUID.randomUUID().toString();\r
-\r
- // Set standard HTTP headers on (southbound request) builder.\r
- con.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID,\r
- defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)));\r
- con.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID,\r
- invocationId);\r
- con.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME,\r
- defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)));\r
-\r
- invokeContext(targetEntity, targetServiceName, invocationId);\r
-\r
- // Log INVOKE*, with the invocationID as the message body.\r
- // (We didn't really want this kind of behavior in the standard,\r
- // but is it worse than new, single-message MDC?)\r
- this.mlogger.info(ONAPLogConstants.Markers.INVOKE);\r
- this.mlogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{" + invocationId + "}");\r
- return con;\r
- }\r
-\r
- /**\r
- * Invokes return context.\r
- */\r
- public void invokeReturn() {\r
- // Add the Invoke-return marker and clear the needed MDC\r
- this.mlogger.info(ONAPLogConstants.Markers.INVOKE_RETURN);\r
- invokeReturnContext();\r
- }\r
-\r
- /**\r
- * Dependency-free nullcheck.\r
- *\r
- * @param in to be checked\r
- * @param <T> argument (and return) type\r
- * @return input arg\r
- */\r
- private static <T> T checkNotNull(final T in) {\r
- if (in == null) {\r
- throw new NullPointerException();\r
- }\r
- return in;\r
- }\r
-\r
- /**\r
- * Dependency-free string default.\r
- *\r
- * @param in to be filtered\r
- * @return input string or null\r
- */\r
- private static String defaultToEmpty(final Object in) {\r
- if (in == null) {\r
- return "";\r
- }\r
- return in.toString();\r
- }\r
-\r
- /**\r
- * Dependency-free string default.\r
- *\r
- * @param in to be filtered\r
- * @return input string or null\r
- */\r
- private static String defaultToUUID(final String in) {\r
- if (in == null) {\r
- return UUID.randomUUID().toString();\r
- }\r
- return in;\r
- }\r
-\r
- /**\r
- * Set target related logging variables in thread local data via MDC.\r
- *\r
- * @param targetEntity Target entity (an external/sub component, for ex. "sdc")\r
- * @param targetServiceName Target service name (name of API invoked on target)\r
- * @param invocationID The invocation ID\r
- */\r
- private void invokeContext(String targetEntity, String targetServiceName, String invocationID) {\r
- MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, defaultToEmpty(targetEntity));\r
- MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, defaultToEmpty(targetServiceName));\r
- MDC.put(ONAPLogConstants.MDCs.INVOCATIONID_OUT, invocationID);\r
- MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP,\r
- ZonedDateTime.now(ZoneOffset.UTC)\r
- .format(DateTimeFormatter.ISO_INSTANT));\r
- }\r
-\r
- /**\r
- * Clear target related logging variables in thread local data via MDC.\r
- */\r
- private void invokeReturnContext() {\r
- MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY);\r
- MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME);\r
- MDC.remove(ONAPLogConstants.MDCs.INVOCATIONID_OUT);\r
- }\r
-}\r
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.util;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotNull;
+
+import org.onap.clamp.clds.service.DefaultUserNameHandler;
+import org.slf4j.MDC;
+import org.slf4j.event.Level;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/**
+ * This class handles the special info that appear in the log, like RequestID,
+ * time context, ...
+ */
+public class LoggingUtils {
+ protected static final EELFLogger logger = EELFManager.getInstance().getLogger(LoggingUtils.class);
+
+ private static final DateFormat DATE_FORMAT = createDateFormat();
+
+ /** String constant for messages <tt>ENTERING</tt>, <tt>EXITING</tt>, etc. */
+ private static final String EMPTY_MESSAGE = "";
+
+ /** Logger delegate. */
+ private EELFLogger mlogger;
+
+ /** Automatic UUID, overrideable per adapter or per invocation. */
+ private static UUID sInstanceUUID = UUID.randomUUID();
+
+ /**
+ * Constructor.
+ */
+ public LoggingUtils(final EELFLogger loggerP) {
+ this.mlogger = checkNotNull(loggerP);
+ }
+
+ /**
+ * Set request related logging variables in thread local data via MDC.
+ *
+ * @param service Service Name of API (ex. "PUT template")
+ * @param partner Partner name (client or user invoking API)
+ */
+ public static void setRequestContext(String service, String partner) {
+ MDC.put("RequestId", UUID.randomUUID().toString());
+ MDC.put("ServiceName", service);
+ MDC.put("PartnerName", partner);
+ //Defaulting to HTTP/1.1 protocol
+ MDC.put("Protocol", "HTTP/1.1");
+ try {
+ MDC.put("ServerFQDN", InetAddress.getLocalHost().getCanonicalHostName());
+ MDC.put("ServerIPAddress", InetAddress.getLocalHost().getHostAddress());
+ } catch (UnknownHostException e) {
+ logger.error("Failed to initiate setRequestContext", e);
+ }
+ }
+
+ /**
+ * Set time related logging variables in thread local data via MDC.
+ *
+ * @param beginTimeStamp Start time
+ * @param endTimeStamp End time
+ */
+ public static void setTimeContext(@NotNull Date beginTimeStamp, @NotNull Date endTimeStamp) {
+ MDC.put("EntryTimestamp", generateTimestampStr(beginTimeStamp));
+ MDC.put("EndTimestamp", generateTimestampStr(endTimeStamp));
+ MDC.put("ElapsedTime", String.valueOf(endTimeStamp.getTime() - beginTimeStamp.getTime()));
+ }
+
+ /**
+ * Set response related logging variables in thread local data via MDC.
+ *
+ * @param code Response code ("0" indicates success)
+ * @param description Response description
+ * @param className class name of invoking class
+ */
+ public static void setResponseContext(String code, String description, String className) {
+ MDC.put("ResponseCode", code);
+ MDC.put("StatusCode", code.equals("0") ? "COMPLETE" : "ERROR");
+ MDC.put("ResponseDescription", description != null ? description : "");
+ MDC.put("ClassName", className != null ? className : "");
+ }
+
+ /**
+ * Set target related logging variables in thread local data via MDC.
+ *
+ * @param targetEntity Target entity (an external/sub component, for ex. "sdc")
+ * @param targetServiceName Target service name (name of API invoked on target)
+ */
+ public static void setTargetContext(String targetEntity, String targetServiceName) {
+ MDC.put("TargetEntity", targetEntity != null ? targetEntity : "");
+ MDC.put("TargetServiceName", targetServiceName != null ? targetServiceName : "");
+ }
+
+ /**
+ * Set error related logging variables in thread local data via MDC.
+ *
+ * @param code Error code
+ * @param description Error description
+ */
+ public static void setErrorContext(String code, String description) {
+ MDC.put("ErrorCode", code);
+ MDC.put("ErrorDescription", description != null ? description : "");
+ }
+
+ private static String generateTimestampStr(Date timeStamp) {
+ return DATE_FORMAT.format(timeStamp);
+ }
+
+ /**
+ * Get a previously stored RequestID for the thread local data via MDC. If
+ * one was not previously stored, generate one, store it, and return that
+ * one.
+ *
+ * @return A string with the request ID
+ */
+ public static String getRequestId() {
+ String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
+ if (requestId == null || requestId.isEmpty()) {
+ requestId = UUID.randomUUID().toString();
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+ }
+ return requestId;
+ }
+
+ private static DateFormat createDateFormat() {
+ DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ return dateFormat;
+ }
+
+
+
+ /*********************************************************************************************
+ * Method for ONAP Application Logging Specification v1.2
+ ********************************************************************************************/
+
+ /**
+ * Report <tt>ENTERING</tt> marker.
+ *
+ * @param request non-null incoming request (wrapper)
+ * @param serviceName service name
+ */
+ public void entering(HttpServletRequest request, String serviceName) {
+ MDC.clear();
+ checkNotNull(request);
+ // Extract MDC values from standard HTTP headers.
+ final String requestId = defaultToUUID(request.getHeader(ONAPLogConstants.Headers.REQUEST_ID));
+ final String invocationId = defaultToUUID(request.getHeader(ONAPLogConstants.Headers.INVOCATION_ID));
+ final String partnerName = defaultToEmpty(request.getHeader(ONAPLogConstants.Headers.PARTNER_NAME));
+
+ // Default the partner name to the user name used to login to clamp
+ if (partnerName.equalsIgnoreCase(EMPTY_MESSAGE)) {
+ MDC.put(ONAPLogConstants.MDCs.PARTNER_NAME, new DefaultUserNameHandler()
+ .retrieveUserName(SecurityContextHolder.getContext()));
+ }
+
+ // Set standard MDCs. Override this entire method if you want to set
+ // others, OR set them BEFORE or AFTER the invocation of #entering,
+ // depending on where you need them to appear, OR extend the
+ // ServiceDescriptor to add them.
+ MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP,
+ ZonedDateTime.now(ZoneOffset.UTC)
+ .format(DateTimeFormatter.ISO_INSTANT));
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, invocationId);
+ MDC.put(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS, defaultToEmpty(request.getRemoteAddr()));
+ MDC.put(ONAPLogConstants.MDCs.SERVER_FQDN, defaultToEmpty(request.getServerName()));
+ MDC.put(ONAPLogConstants.MDCs.INSTANCE_UUID, defaultToEmpty(sInstanceUUID));
+
+ // Default the service name to the requestURI, in the event that
+ // no value has been provided.
+ if (serviceName == null
+ || serviceName.equalsIgnoreCase(EMPTY_MESSAGE)) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI());
+ } else {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, serviceName);
+ }
+
+ this.mlogger.info(ONAPLogConstants.Markers.ENTRY);
+ }
+
+ /**
+ * Report <tt>EXITING</tt> marker.
+ *
+
+ * @param code response code
+ * @param descrption response description
+ * @param severity response severity
+ * @param status response status code
+ */
+ public void exiting(String code, String descrption, Level severity, ONAPLogConstants.ResponseStatus status) {
+ try {
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, defaultToEmpty(code));
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, defaultToEmpty(descrption));
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_SEVERITY, defaultToEmpty(severity));
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, defaultToEmpty(status));
+
+ ZonedDateTime startTime = ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP),
+ DateTimeFormatter.ISO_INSTANT.withZone(ZoneOffset.UTC));
+ ZonedDateTime endTime = ZonedDateTime.now(ZoneOffset.UTC);
+ MDC.put(ONAPLogConstants.MDCs.END_TIMESTAMP, endTime.format(DateTimeFormatter.ISO_INSTANT));
+ long duration = ChronoUnit.MILLIS.between(startTime, endTime);
+ MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIMESTAMP, String.valueOf(duration));
+ this.mlogger.info(ONAPLogConstants.Markers.EXIT);
+ }
+ finally {
+ MDC.clear();
+ }
+ }
+
+ /**
+ * Get the property value.
+ *
+ * @param name The name of the property
+ * @return The value of the property
+ */
+ public String getProperties(String name) {
+ return MDC.get(name);
+ }
+
+ /**
+ * Report pending invocation with <tt>INVOKE</tt> marker,
+ * setting standard ONAP logging headers automatically.
+ *
+ * @param con The HTTP url connection
+ * @param targetEntity The target entity
+ * @param targetServiceName The target service name
+ * @return The HTTP url connection
+ */
+ public HttpURLConnection invoke(final HttpURLConnection con, String targetEntity, String targetServiceName) {
+ final String invocationId = UUID.randomUUID().toString();
+
+ // Set standard HTTP headers on (southbound request) builder.
+ con.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID,
+ defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)));
+ con.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID,
+ invocationId);
+ con.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME,
+ defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)));
+
+ invokeContext(targetEntity, targetServiceName, invocationId);
+
+ // Log INVOKE*, with the invocationID as the message body.
+ // (We didn't really want this kind of behavior in the standard,
+ // but is it worse than new, single-message MDC?)
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE);
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{" + invocationId + "}");
+ return con;
+ }
+
+ /**
+ * Report pending invocation with <tt>INVOKE</tt> marker,
+ * setting standard ONAP logging headers automatically.
+ *
+ * @param targetEntity The target entity
+ * @param targetServiceName The target service name
+ */
+ public void invoke(String targetEntity, String targetServiceName) {
+ final String invocationId = UUID.randomUUID().toString();
+
+ invokeContext(targetEntity, targetServiceName, invocationId);
+
+ // Log INVOKE*, with the invocationID as the message body.
+ // (We didn't really want this kind of behavior in the standard,
+ // but is it worse than new, single-message MDC?)
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE);
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{" + invocationId + "}");
+ }
+
+ /**
+ * Report pending invocation with <tt>INVOKE</tt> marker,
+ * setting standard ONAP logging headers automatically.
+ *
+ * @param con The HTTPS url connection
+ * @param targetEntity The target entity
+ * @param targetServiceName The target service name
+ * @return The HTTPS url connection
+ */
+ public HttpsURLConnection invokeHttps(final HttpsURLConnection con, String targetEntity, String targetServiceName) {
+ final String invocationId = UUID.randomUUID().toString();
+
+ // Set standard HTTP headers on (southbound request) builder.
+ con.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID,
+ defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)));
+ con.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID,
+ invocationId);
+ con.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME,
+ defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)));
+
+ invokeContext(targetEntity, targetServiceName, invocationId);
+
+ // Log INVOKE*, with the invocationID as the message body.
+ // (We didn't really want this kind of behavior in the standard,
+ // but is it worse than new, single-message MDC?)
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE);
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{" + invocationId + "}");
+ return con;
+ }
+
+ /**
+ * Report pending invocation with <tt>INVOKE-RETURN</tt> marker.
+ */
+ public void invokeReturn() {
+ // Add the Invoke-return marker and clear the needed MDC
+ this.mlogger.info(ONAPLogConstants.Markers.INVOKE_RETURN);
+ invokeReturnContext();
+ }
+
+ /**
+ * Dependency-free nullcheck.
+ *
+ * @param in to be checked
+ * @param <T> argument (and return) type
+ * @return input arg
+ */
+ private static <T> T checkNotNull(final T in) {
+ if (in == null) {
+ throw new NullPointerException();
+ }
+ return in;
+ }
+
+ /**
+ * Dependency-free string default.
+ *
+ * @param in to be filtered
+ * @return input string or null
+ */
+ private static String defaultToEmpty(final Object in) {
+ if (in == null) {
+ return "";
+ }
+ return in.toString();
+ }
+
+ /**
+ * Dependency-free string default.
+ *
+ * @param in to be filtered
+ * @return input string or null
+ */
+ private static String defaultToUUID(final String in) {
+ if (in == null) {
+ return UUID.randomUUID().toString();
+ }
+ return in;
+ }
+
+ /**
+ * Set target related logging variables in thread local data via MDC.
+ *
+ * @param targetEntity Target entity (an external/sub component, for ex. "sdc")
+ * @param targetServiceName Target service name (name of API invoked on target)
+ * @param invocationID The invocation ID
+ */
+ private void invokeContext(String targetEntity, String targetServiceName, String invocationID) {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, defaultToEmpty(targetEntity));
+ MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, defaultToEmpty(targetServiceName));
+ MDC.put(ONAPLogConstants.MDCs.INVOCATIONID_OUT, invocationID);
+ MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP,
+ ZonedDateTime.now(ZoneOffset.UTC)
+ .format(DateTimeFormatter.ISO_INSTANT));
+ }
+
+ /**
+ * Clear target related logging variables in thread local data via MDC.
+ */
+ private void invokeReturnContext() {
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY);
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME);
+ MDC.remove(ONAPLogConstants.MDCs.INVOCATIONID_OUT);
+ MDC.remove(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP);
+ }
+}