Jakarta migration 64/138264/1 newdelhi
authorDan Timoney <dtimoney@att.com>
Wed, 3 Jul 2024 15:10:09 +0000 (11:10 -0400)
committerDan Timoney <dtimoney@att.com>
Wed, 3 Jul 2024 15:10:09 +0000 (11:10 -0400)
Update filters to migrate from javax.* to jakarta

Issue-ID: SDNC-1843
Change-Id: Ieb217a9f346e8f3529c55f2eb55b4d14151b6bcc
Signed-off-by: Dan Timoney <dtimoney@att.com>
services/pom.xml
services/src/main/java/org/onap/ccsdk/apps/filters/AbstractAuditLogFilter.java [new file with mode: 0644]
services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogFilter.java
services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogServletFilter.java [new file with mode: 0644]
services/src/main/java/org/onap/ccsdk/apps/filters/CustomResponseStatus.java [new file with mode: 0644]
services/src/main/java/org/onap/ccsdk/apps/filters/MDCSetup.java [new file with mode: 0644]
services/src/main/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMap.java [new file with mode: 0644]

index af1377f..d89385d 100644 (file)
             <artifactId>logging-filter-spring</artifactId>
             <version>${logging.analytics.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>javax.ws.rs</groupId>
             <artifactId>javax.ws.rs-api</artifactId>
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractAuditLogFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractAuditLogFilter.java
new file mode 100644 (file)
index 0000000..a332fcb
--- /dev/null
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 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.ccsdk.apps.filters;
+
+ import jakarta.servlet.http.HttpServletRequest;
+ import org.onap.logging.ref.slf4j.ONAPLogConstants;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.slf4j.MDC;
+ import org.onap.logging.filter.base.SimpleMap;
+ public abstract class AbstractAuditLogFilter<GenericRequest, GenericResponse> extends MDCSetup {
+     protected static final Logger logger = LoggerFactory.getLogger(AbstractAuditLogFilter.class);
+     protected void pre(SimpleMap headers, GenericRequest request, HttpServletRequest httpServletRequest) {
+         try {
+             String requestId = getRequestId(headers);
+             MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
+             setInvocationId(headers);
+             setServiceName(request);
+             setMDCPartnerName(headers);
+             setServerFQDN();
+             setClientIPAddress(httpServletRequest);
+             setInstanceID();
+             setEntryTimeStamp();
+             MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+             additionalPreHandling(request);
+             setLogTimestamp();
+             setElapsedTime();
+             logEntering();
+         } catch (Exception e) {
+             logger.warn("Error in AbstractInboundFilter pre", e);
+         }
+     }
+     protected void post(GenericResponse response) {
+         try {
+             MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, MDC.get(ONAPLogConstants.MDCs.SERVER_INVOCATION_ID));
+             int responseCode = getResponseCode(response);
+             setResponseStatusCode(responseCode);
+             MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, String.valueOf(responseCode));
+             setResponseDescription(responseCode);
+             setLogTimestamp();
+             setElapsedTime();
+             additionalPostHandling(response);
+             logExiting();
+         } catch (Exception e) {
+             logger.warn("Error in AbstractInboundFilter post", e);
+         } finally {
+             MDC.clear();
+         }
+     }
+     protected abstract int getResponseCode(GenericResponse response);
+     protected abstract void setServiceName(GenericRequest request);
+     protected void additionalPreHandling(GenericRequest request) {
+         // override to add additional pre handling
+     }
+     protected void additionalPostHandling(GenericResponse response) {
+         // override to add additional post handling
+     }
+     protected void logEntering() {
+         logger.info(ONAPLogConstants.Markers.ENTRY, "Entering");
+     }
+     protected void logExiting() {
+         logger.info(ONAPLogConstants.Markers.EXIT, "Exiting.");
+     }
+ }
\ No newline at end of file
index 45ce55f..0c29238 100644 (file)
@@ -1,8 +1,7 @@
 package org.onap.ccsdk.apps.filters
 ;
 
-import javax.servlet.http.HttpServletRequest;
-import org.onap.logging.filter.base.AuditLogServletFilter;
+import jakarta.servlet.http.HttpServletRequest;
 import org.onap.logging.ref.slf4j.ONAPLogConstants;
 import org.slf4j.MDC;
 import org.springframework.stereotype.Component;
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogServletFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/AuditLogServletFilter.java
new file mode 100644 (file)
index 0000000..cd9f855
--- /dev/null
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * 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.ccsdk.apps.filters;
+
+ import java.io.IOException;
+ import jakarta.servlet.Filter;
+ import jakarta.servlet.FilterChain;
+ import jakarta.servlet.FilterConfig;
+ import jakarta.servlet.ServletException;
+ import jakarta.servlet.ServletRequest;
+ import jakarta.servlet.ServletResponse;
+ import jakarta.servlet.http.HttpServletRequest;
+ import jakarta.servlet.http.HttpServletResponse;
+ import org.onap.logging.ref.slf4j.ONAPLogConstants;
+ import org.onap.logging.filter.base.SimpleMap;
+ import org.slf4j.MDC;
+ public class AuditLogServletFilter extends AbstractAuditLogFilter<HttpServletRequest, HttpServletResponse>
+         implements Filter {
+     @Override
+     public void destroy() {
+         // this method does nothing
+     }
+     @Override
+     public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
+             throws IOException, ServletException {
+         try {
+             if (request != null && request instanceof HttpServletRequest) {
+                 pre((HttpServletRequest) request);
+             }
+             filterChain.doFilter(request, response);
+         } finally {
+             if (request != null && request instanceof HttpServletRequest) {
+                 post((HttpServletRequest) request, (HttpServletResponse) response);
+             }
+             MDC.clear();
+         }
+     }
+     @Override
+     public void init(FilterConfig filterConfig) throws ServletException {
+         // this method does nothing
+     }
+     protected void pre(HttpServletRequest request) {
+         SimpleMap headers = new SimpleServletHeadersMap(request);
+         pre(headers, request, request);
+     }
+     @Override
+     protected void setServiceName(HttpServletRequest request) {
+         MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI());
+     }
+     private void post(HttpServletRequest request, HttpServletResponse response) {
+         post(response);
+     }
+     @Override
+     protected int getResponseCode(HttpServletResponse response) {
+         return response.getStatus();
+     }
+ }
\ No newline at end of file
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/CustomResponseStatus.java b/services/src/main/java/org/onap/ccsdk/apps/filters/CustomResponseStatus.java
new file mode 100644 (file)
index 0000000..c44466d
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2021 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.ccsdk.apps.filters;
+
+ public enum CustomResponseStatus {
+     PROCESSING(102, "Processing"),
+     MULTI_STATUS(207, "Multi-Status"),
+     ALREADY_REPORTED(208, "Already Reported"),
+     UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"),
+     LOCKED(423, "Locked"),
+     FAILED_DEPENDENCY(424, "Failed Dependency"),
+     INSUFFICIENT_STORAGE(508, "Insufficient Storage"),
+     LOOP_DETECTED(508, "Loop Detected");
+     private final int code;
+     private final String reason;
+     CustomResponseStatus(int statusCode, String reasonPhrase) {
+         this.code = statusCode;
+         this.reason = reasonPhrase;
+     }
+     public static CustomResponseStatus fromStatusCode(int statusCode) {
+         for (CustomResponseStatus s : values()) {
+             if (s.code == statusCode) {
+                 return s;
+             }
+         }
+         return null;
+     }
+     public int getStatusCode() {
+         return this.code;
+     }
+     public String getReasonPhrase() {
+         return this.toString();
+     }
+     public String toString() {
+         return this.reason;
+     }
+ }
\ No newline at end of file
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/MDCSetup.java b/services/src/main/java/org/onap/ccsdk/apps/filters/MDCSetup.java
new file mode 100644 (file)
index 0000000..6b7f38d
--- /dev/null
@@ -0,0 +1,291 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 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.ccsdk.apps.filters;
+
+ import java.net.InetAddress;
+ import java.net.UnknownHostException;
+ import java.time.ZoneOffset;
+ import java.time.ZonedDateTime;
+ import java.time.format.DateTimeFormatter;
+ import java.time.format.DateTimeFormatterBuilder;
+ import java.time.temporal.ChronoUnit;
+ import java.util.Base64;
+ import java.util.UUID;
+ import jakarta.servlet.http.HttpServletRequest;
+ import javax.ws.rs.core.HttpHeaders;
+ import javax.ws.rs.core.Response;
+
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.ONAPComponentsList;
+import org.onap.logging.filter.base.SimpleMap;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+ public class MDCSetup {
+     protected static Logger logger = LoggerFactory.getLogger(MDCSetup.class);
+     private static final String INSTANCE_UUID = UUID.randomUUID().toString();
+     protected static final String serverIpAddressOverride = "SERVER_IP_ADDRESS_OVERRIDE";
+     protected static final String serverFqdnOverride = "SERVER_FQDN_OVERRIDE";
+     protected static final String INSTANT_PRECISION_OVERRIDE = "INSTANT_PRECISION_OVERRIDE";
+     protected static final String checkHeaderLogPattern = "Checking {} header to determine the value of {}";
+     protected String serverFqdn;
+     protected String serverIpAddress;
+     protected String[] prioritizedIdHeadersNames;
+     protected String[] prioritizedPartnerHeadersNames;
+     protected DateTimeFormatter iso8601Formatter;
+     public MDCSetup() {
+         this.prioritizedIdHeadersNames =
+                 new String[] {ONAPLogConstants.Headers.REQUEST_ID, Constants.HttpHeaders.HEADER_REQUEST_ID,
+                         Constants.HttpHeaders.TRANSACTION_ID, Constants.HttpHeaders.ECOMP_REQUEST_ID};
+         this.prioritizedPartnerHeadersNames =
+                 new String[] {HttpHeaders.AUTHORIZATION, ONAPLogConstants.Headers.PARTNER_NAME, HttpHeaders.USER_AGENT};
+         initServerFqdnandIp();
+         this.iso8601Formatter = createFormatter();
+     }
+     protected String getCurrentTimeStamp() {
+         return ZonedDateTime.now(ZoneOffset.UTC).format(iso8601Formatter);
+     }
+     protected DateTimeFormatter createFormatter() {
+         DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
+         try {
+             Integer instantPrecision = Integer.valueOf(System.getProperty(INSTANT_PRECISION_OVERRIDE, "3"));
+             builder.appendInstant(instantPrecision);
+         } catch (NumberFormatException nfe) {
+             logger.warn("instant precision could not be read and thus won't be set, the default will be used instead."
+                     + nfe.getMessage());
+         }
+         return builder.toFormatter();
+     }
+     public void setInstanceID() {
+         MDC.put(ONAPLogConstants.MDCs.INSTANCE_UUID, INSTANCE_UUID);
+     }
+     protected void initServerFqdnandIp() {
+         serverFqdn = getProperty(serverFqdnOverride);
+         serverIpAddress = getProperty(serverIpAddressOverride);
+         if (serverIpAddress.equals(Constants.DefaultValues.UNKNOWN)
+                 || serverFqdn.equals(Constants.DefaultValues.UNKNOWN)) {
+             try {
+                 InetAddress addr = InetAddress.getLocalHost();
+                 if (serverFqdn.equals(Constants.DefaultValues.UNKNOWN)) {
+                     serverFqdn = addr.getCanonicalHostName();
+                 }
+                 if (serverIpAddress.equals(Constants.DefaultValues.UNKNOWN)) {
+                     serverIpAddress = addr.getHostAddress();
+                 }
+             } catch (UnknownHostException e) {
+                 logger.trace("Cannot Resolve Host Name." + e.getMessage());
+             }
+         }
+     }
+     public void setServerFQDN() {
+         MDC.put(ONAPLogConstants.MDCs.SERVER_FQDN, serverFqdn);
+         MDC.put(ONAPLogConstants.MDCs.SERVER_IP_ADDRESS, serverIpAddress);
+     }
+     public void setClientIPAddress(HttpServletRequest httpServletRequest) {
+         String clientIpAddress = "";
+         if (httpServletRequest != null) {
+             // This logic is to avoid setting the client ip address to that of the load
+             // balancer in front of the application
+             String getForwadedFor = httpServletRequest.getHeader("X-Forwarded-For");
+             if (getForwadedFor != null) {
+                 clientIpAddress = getForwadedFor;
+             } else {
+                 clientIpAddress = httpServletRequest.getRemoteAddr();
+             }
+         }
+         MDC.put(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS, clientIpAddress);
+     }
+     public void setEntryTimeStamp() {
+         MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP, getCurrentTimeStamp());
+     }
+     public String getRequestId(SimpleMap headers) {
+         String requestId = null;
+         for (String headerName : this.prioritizedIdHeadersNames) {
+             logger.trace(checkHeaderLogPattern, headerName, ONAPLogConstants.Headers.REQUEST_ID);
+             requestId = headers.get(headerName);
+             if (requestId != null && !requestId.isEmpty()) {
+                 return requestId;
+             }
+         }
+         logger.trace("No valid requestId headers. Generating requestId: {}", requestId);
+         return UUID.randomUUID().toString();
+     }
+     public void setInvocationId(SimpleMap headers) {
+         String invocationId = headers.get(ONAPLogConstants.Headers.INVOCATION_ID);
+         if (invocationId == null || invocationId.isEmpty())
+             invocationId = UUID.randomUUID().toString();
+         MDC.put(ONAPLogConstants.MDCs.SERVER_INVOCATION_ID, invocationId);
+         MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, invocationId);
+     }
+     public void setMDCPartnerName(SimpleMap headers) {
+         String partnerName = getMDCPartnerName(headers);
+         MDC.put(ONAPLogConstants.MDCs.PARTNER_NAME, partnerName);
+     }
+     protected String getMDCPartnerName(SimpleMap headers) {
+         String partnerName = null;
+         for (String headerName : prioritizedPartnerHeadersNames) {
+             logger.trace(checkHeaderLogPattern, headerName, ONAPLogConstants.MDCs.PARTNER_NAME);
+             if (headerName.equals(HttpHeaders.AUTHORIZATION)) {
+                 partnerName = getBasicAuthUserName(headers);
+             } else {
+                 partnerName = headers.get(headerName);
+             }
+             if (partnerName != null && !partnerName.isEmpty()) {
+                 return partnerName;
+             }
+         }
+         logger.trace("{} value could not be determined, defaulting partnerName to {}.",
+                 ONAPLogConstants.MDCs.PARTNER_NAME, Constants.DefaultValues.UNKNOWN);
+         return Constants.DefaultValues.UNKNOWN;
+     }
+     public void setLogTimestamp() {
+         MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, getCurrentTimeStamp());
+     }
+     public void setElapsedTime() {
+         try {
+             DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+             ZonedDateTime entryTimestamp =
+                     ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP), timeFormatter);
+             ZonedDateTime endTimestamp =
+                     ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter);
+             MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME,
+                     Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp)));
+         } catch (Exception e) {
+             logger.trace("Unable to calculate elapsed time due to error: {}", e.getMessage());
+         }
+     }
+     public void setElapsedTimeInvokeTimestamp() {
+         try {
+             DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+             ZonedDateTime entryTimestamp =
+                     ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP), timeFormatter);
+             ZonedDateTime endTimestamp =
+                     ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter);
+             MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME,
+                     Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp)));
+         } catch (Exception e) {
+             logger.trace("Unable to calculate elapsed time due to error: {}", e.getMessage());
+         }
+     }
+     public void setResponseStatusCode(int code) {
+         String statusCode;
+         if (Response.Status.Family.familyOf(code).equals(Response.Status.Family.SUCCESSFUL)) {
+             statusCode = ONAPLogConstants.ResponseStatus.COMPLETE.toString();
+         } else {
+             statusCode = ONAPLogConstants.ResponseStatus.ERROR.toString();
+             setErrorCode(code);
+             setErrorDescription(code);
+         }
+         MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, statusCode);
+     }
+     public void setTargetEntity(ONAPComponentsList targetEntity) {
+         MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, targetEntity.toString());
+     }
+     public void clearClientMDCs() {
+         MDC.remove(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID);
+         MDC.remove(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION);
+         MDC.remove(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE);
+         MDC.remove(ONAPLogConstants.MDCs.RESPONSE_CODE);
+         MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY);
+         MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME);
+         MDC.remove(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP);
+         MDC.remove(ONAPLogConstants.MDCs.ERROR_CODE);
+         MDC.remove(ONAPLogConstants.MDCs.ERROR_DESC);
+     }
+     public void setResponseDescription(int statusCode) {
+         MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, extractDescription(statusCode));
+     }
+     private String extractDescription(int statusCode) {
+         Response.Status responseStatus = Response.Status.fromStatusCode(statusCode);
+         if (responseStatus != null) {
+             return responseStatus.toString();
+         }
+         CustomResponseStatus customResponseStatus = CustomResponseStatus.fromStatusCode(statusCode);
+         if (customResponseStatus != null) {
+             return customResponseStatus.toString();
+         }
+         return String.format("Unknown description for response code %d.", statusCode);
+     }
+     public void setErrorCode(int statusCode) {
+         MDC.put(ONAPLogConstants.MDCs.ERROR_CODE, String.valueOf(statusCode));
+     }
+     public void setErrorDescription(int statusCode) {
+         MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, extractDescription(statusCode));
+     }
+     public String getProperty(String property) {
+         String propertyValue = System.getProperty(property);
+         if (propertyValue == null || propertyValue.isEmpty()) {
+             propertyValue = System.getenv(property);
+             if (propertyValue == null || propertyValue.isEmpty()) {
+                 propertyValue = Constants.DefaultValues.UNKNOWN;
+             }
+         }
+         return propertyValue;
+     }
+     protected String getBasicAuthUserName(SimpleMap headers) {
+         String encodedAuthorizationValue = headers.get(HttpHeaders.AUTHORIZATION);
+         if (encodedAuthorizationValue != null && encodedAuthorizationValue.startsWith("Basic")) {
+             try {
+                 // This will strip the word Basic and single space
+                 encodedAuthorizationValue = encodedAuthorizationValue.substring(6);
+                 byte[] decodedBytes = Base64.getDecoder().decode(encodedAuthorizationValue);
+                 String decodedString = new String(decodedBytes);
+                 int idx = decodedString.indexOf(':');
+                 return decodedString.substring(0, idx);
+             } catch (IllegalArgumentException e) {
+                 logger.error("could not decode basic auth value " + encodedAuthorizationValue, e);
+             }
+         }
+         return null;
+     }
+ }
\ No newline at end of file
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMap.java b/services/src/main/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMap.java
new file mode 100644 (file)
index 0000000..244fc84
--- /dev/null
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - Logging
+ * ================================================================================
+ * Copyright (C) 2019 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.ccsdk.apps.filters;
+
+ import org.onap.logging.filter.base.SimpleMap;
+
+import jakarta.servlet.http.HttpServletRequest;
+ public class SimpleServletHeadersMap implements SimpleMap {
+     private HttpServletRequest request;
+     public SimpleServletHeadersMap(HttpServletRequest request) {
+         this.request = request;
+     }
+     @Override
+     public String get(String key) {
+         return request.getHeader(key);
+     }
+ }
\ No newline at end of file