diff options
Diffstat (limited to 'services')
13 files changed, 1191 insertions, 0 deletions
diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractServletFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractServletFilter.java new file mode 100644 index 00000000..992345cc --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/AbstractServletFilter.java @@ -0,0 +1,58 @@ +/*- + * ============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.util.Enumeration; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; + +public abstract class AbstractServletFilter { + + protected String getSecureRequestHeaders(HttpServletRequest httpRequest) { + StringBuilder sb = new StringBuilder(); + String header; + for (Enumeration<String> e = httpRequest.getHeaderNames(); e.hasMoreElements();) { + header = e.nextElement(); + sb.append(header); + sb.append(":"); + if (header.equalsIgnoreCase(HttpHeaders.AUTHORIZATION)) { + sb.append(Constants.REDACTED); + } else { + sb.append(httpRequest.getHeader(header)); + } + sb.append(";"); + } + return sb.toString(); + } + + protected String formatResponseHeaders(HttpServletResponse response) { + StringBuilder sb = new StringBuilder(); + for (String headerName : response.getHeaderNames()) { + sb.append(headerName); + sb.append(":"); + sb.append(response.getHeader(headerName)); + sb.append(";"); + } + return sb.toString(); + } +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/Constants.java b/services/src/main/java/org/onap/ccsdk/apps/filters/Constants.java new file mode 100644 index 00000000..efbfe90e --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/Constants.java @@ -0,0 +1,45 @@ +/*- + * ============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; + +public class Constants { + protected static final String REDACTED = "***REDACTED***"; + + public static final class DefaultValues { + public static final String UNKNOWN = "UNKNOWN"; + public static final String UNKNOWN_TARGET_ENTITY = "Unknown-Target-Entity"; + } + + public static final class HttpHeaders { + public static final String HEADER_FROM_APP_ID = "X-FromAppId"; + public static final String ONAP_PARTNER_NAME = "X-ONAP-PartnerName"; + public static final String HEADER_REQUEST_ID = "X-RequestID"; + public static final String TRANSACTION_ID = "X-TransactionID"; + public static final String ECOMP_REQUEST_ID = "X-ECOMP-RequestID"; + public static final String ONAP_REQUEST_ID = "X-ONAP-RequestID"; + public static final String INVOCATION_ID_HEADER = "X-InvocationID"; + public static final String TARGET_ENTITY_HEADER = "X-Target-Entity"; + } + + public static final class Property { + public static final String PARTNER_NAME = "partnerName"; + } +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptor.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptor.java new file mode 100644 index 00000000..3f89ee14 --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptor.java @@ -0,0 +1,68 @@ +/*- + * ============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.spring; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Providers; +import org.onap.ccsdk.apps.filters.AbstractAuditLogFilter; +import org.onap.ccsdk.apps.filters.SimpleServletHeadersMap; +import org.onap.logging.filter.base.SimpleMap; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +@Component +public class LoggingInterceptor extends AbstractAuditLogFilter<HttpServletRequest, HttpServletResponse> + implements HandlerInterceptor { + + @Context + private Providers providers; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + SimpleMap headers = new SimpleServletHeadersMap(request); + pre(headers, request, request); + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + post(response); + } + + @Override + protected int getResponseCode(HttpServletResponse response) { + return response.getStatus(); + } + + @Override + protected void setServiceName(HttpServletRequest request) { + MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, request.getRequestURI()); + } + +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/MDCTaskDecorator.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/MDCTaskDecorator.java new file mode 100644 index 00000000..6969c3ec --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/MDCTaskDecorator.java @@ -0,0 +1,43 @@ +/*- + * ============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.spring; + +import java.util.Map; +import org.slf4j.MDC; +import org.springframework.core.task.TaskDecorator; + +public class MDCTaskDecorator implements TaskDecorator { + + @Override + public Runnable decorate(Runnable runnable) { + Map<String, String> contextMap = MDC.getCopyOfContextMap(); + return () -> { + try { + if (contextMap != null) { + MDC.setContextMap(contextMap); + runnable.run(); + } + } finally { + MDC.clear(); + } + }; + } +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilter.java new file mode 100644 index 00000000..42002fef --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilter.java @@ -0,0 +1,99 @@ +/*- + * ============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.spring; + +import java.io.IOException; +import java.util.List; +import org.onap.logging.filter.base.AbstractMetricLogFilter; +import org.onap.logging.filter.base.Constants; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; + +public class SpringClientFilter extends AbstractMetricLogFilter<HttpRequest, ClientHttpResponse, HttpHeaders> + implements ClientHttpRequestInterceptor { + + public SpringClientFilter() { + + } + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) + throws IOException { + pre(request, request.getHeaders()); + ClientHttpResponse response = execution.execute(request, body); + post(request, response); + return response; + } + + @Override + protected void addHeader(HttpHeaders requestHeaders, String headerName, String headerValue) { + requestHeaders.add(headerName, headerValue); + } + + @Override + protected String getTargetServiceName(HttpRequest request) { + return request.getURI().toString(); + } + + @Override + protected int getHttpStatusCode(ClientHttpResponse response) { + try { + return response.getStatusCode().value(); + } catch (IOException e) { + // TODO figure out the right thing to do here + return 500; + } + } + + @Override + protected String getResponseCode(ClientHttpResponse response) { + try { + return response.getStatusCode().toString(); + } catch (IOException e) { + return "500"; + } + } + + @Override + protected String getTargetEntity(HttpRequest clientRequest) { + HttpHeaders headers = clientRequest.getHeaders(); + String headerTargetEntity = null; + List<String> headerTargetEntityList = headers.get(Constants.HttpHeaders.TARGET_ENTITY_HEADER); + if (headerTargetEntityList != null && !headerTargetEntityList.isEmpty()) + headerTargetEntity = headerTargetEntityList.get(0); + String targetEntity = MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY); + if (targetEntity != null && !targetEntity.isEmpty()) { + return targetEntity; + } else if (headerTargetEntity != null && !headerTargetEntity.isEmpty()) { + targetEntity = headerTargetEntity; + } else { + targetEntity = Constants.DefaultValues.UNKNOWN_TARGET_ENTITY; + logger.warn("Could not Target Entity: {}", clientRequest.getURI()); + } + return targetEntity; + } + +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientPayloadFilter.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientPayloadFilter.java new file mode 100644 index 00000000..db14a7e0 --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringClientPayloadFilter.java @@ -0,0 +1,69 @@ +/*- + * ============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.spring; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.util.StreamUtils; + +public class SpringClientPayloadFilter implements ClientHttpRequestInterceptor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) + throws IOException { + logRequest(request, body); + ClientHttpResponse response = execution.execute(request, body); + logResponse(response); + return response; + } + + protected void logRequest(HttpRequest request, byte[] body) throws IOException { + if (logger.isDebugEnabled()) { + logger.debug("===========================request begin================================================"); + logger.debug("URI : {}", request.getURI()); + logger.debug("Method : {}", request.getMethod()); + logger.debug("Headers : {}", request.getHeaders()); + logger.debug("Request body: {}", new String(body, StandardCharsets.UTF_8)); + logger.debug("==========================request end================================================"); + } + } + + protected void logResponse(ClientHttpResponse response) throws IOException { + if (logger.isDebugEnabled()) { + logger.debug("============================response begin=========================================="); + logger.debug("Status code : {}", response.getStatusCode()); + logger.debug("Status text : {}", response.getStatusText()); + logger.debug("Headers : {}", response.getHeaders()); + logger.debug("Response body: {}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset())); + logger.debug("=======================response end================================================="); + } + } + +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringScheduledTasksMDCSetupAspect.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringScheduledTasksMDCSetupAspect.java new file mode 100644 index 00000000..7e8c7494 --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/SpringScheduledTasksMDCSetupAspect.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - Logging + * ================================================================================ + * Copyright (C) 2020 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.spring; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.onap.logging.filter.base.AbstractMDCSetupAspect; +import org.onap.logging.filter.base.ScheduledTaskException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class SpringScheduledTasksMDCSetupAspect extends AbstractMDCSetupAspect { + + protected static Logger logger = LoggerFactory.getLogger(SpringScheduledTasksMDCSetupAspect.class); + + @Around("@annotation(org.onap.logging.filter.base.ScheduledLogging)") + public void logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { + setupMDC(joinPoint.getSignature().getName()); + try { + joinPoint.proceed(); + } catch (ScheduledTaskException e) { + errorMDCSetup(e.getErrorCode(), e.getMessage()); + logger.error("ScheduledTaskException: ", e); + } + exitAndClearMDC(); + } +} diff --git a/services/src/main/java/org/onap/ccsdk/apps/filters/spring/StatusLoggingInterceptor.java b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/StatusLoggingInterceptor.java new file mode 100644 index 00000000..931b2dd8 --- /dev/null +++ b/services/src/main/java/org/onap/ccsdk/apps/filters/spring/StatusLoggingInterceptor.java @@ -0,0 +1,73 @@ +/*- + * ============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.spring; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Providers; +import org.onap.ccsdk.apps.filters.AbstractServletFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +@Component +public class StatusLoggingInterceptor extends AbstractServletFilter implements HandlerInterceptor { + + private static final Logger logger = LoggerFactory.getLogger(StatusLoggingInterceptor.class); + + @Context + private Providers providers; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + if (logger.isDebugEnabled()) { + logRequestInformation(request); + } + return true; + } + + protected void logRequestInformation(HttpServletRequest request) { + logger.debug("===========================request begin================================================"); + logger.debug("URI : {}", request.getRequestURI()); + logger.debug("Method : {}", request.getMethod()); + logger.debug("Headers : {}", getSecureRequestHeaders(request)); + logger.debug("===========================request end=================================================="); + } + + // TODO previously no response information was being logged, I followed the format in SpringClientPayloadFilter + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + if (logger.isDebugEnabled()) { + logger.debug("============================response begin=========================================="); + logger.debug("Status code : {}", response.getStatus()); + logger.debug("Status text : {}", Response.Status.fromStatusCode(response.getStatus())); + logger.debug("Headers : {}", formatResponseHeaders(response)); + logger.debug("============================response end============================================"); + } + } +} diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/AuditLogServletFilterTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/AuditLogServletFilterTest.java new file mode 100644 index 00000000..8a9a6565 --- /dev/null +++ b/services/src/test/java/org/onap/ccsdk/apps/filters/AuditLogServletFilterTest.java @@ -0,0 +1,82 @@ +/*- + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; + +@RunWith(MockitoJUnitRunner.class) +public class AuditLogServletFilterTest { + + @Mock + private ServletRequest request; + + @Mock + private ServletResponse response; + + @Mock + private HttpServletRequest servletRequest; + + @Mock + private HttpServletResponse servletResponse; + + @Spy + @InjectMocks + private AuditLogServletFilter auditLogServletFilter; + + @After + public void tearDown() { + MDC.clear(); + } + + @Test + public void preTest() { + when(servletRequest.getRequestURI()).thenReturn("onap/so/serviceInstances"); + auditLogServletFilter.pre(servletRequest); + + assertNotNull(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)); + assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME)); + assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE)); + } + + @Test + public void getResponseCodeTest() { + when(servletResponse.getStatus()).thenReturn(200); + int responseCode = auditLogServletFilter.getResponseCode(servletResponse); + + assertEquals(200, responseCode); + } + +} diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/MDCSetupTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/MDCSetupTest.java new file mode 100644 index 00000000..2f7f73de --- /dev/null +++ b/services/src/test/java/org/onap/ccsdk/apps/filters/MDCSetupTest.java @@ -0,0 +1,335 @@ +/*- + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.HashMap; +import jakarta.servlet.http.HttpServletRequest; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.logging.filter.base.ONAPComponents; +import org.onap.logging.filter.base.SimpleMap; +import org.onap.logging.filter.base.SimpleHashMap; +import org.onap.logging.filter.base.SimpleJaxrsHeadersMap; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; + +@RunWith(MockitoJUnitRunner.class) +public class MDCSetupTest extends MDCSetup { + + @Mock + private HttpServletRequest httpServletRequest; + + private String requestId = "4d31fe02-4918-4975-942f-fe51a44e6a9b"; + private String invocationId = "4d31fe02-4918-4975-942f-fe51a44e6a9a"; + + @After + public void tearDown() { + MDC.clear(); + System.clearProperty("partnerName"); + } + + @Test + public void setElapsedTimeTest() { + String expected = "318"; + MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP, "2019-06-18T02:09:06.024Z"); + MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, "2019-06-18T02:09:06.342Z"); + + setElapsedTime(); + assertEquals(expected, MDC.get(ONAPLogConstants.MDCs.ELAPSED_TIME)); + } + + @Test + public void setElapsedTimeInvokeTimestampTest() { + String expected = "318"; + MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, "2019-06-18T02:09:06.024Z"); + MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, "2019-06-18T02:09:06.342Z"); + + setElapsedTimeInvokeTimestamp(); + assertEquals(expected, MDC.get(ONAPLogConstants.MDCs.ELAPSED_TIME)); + } + + @Test + public void setRequestIdTest() { + HashMap<String, String> headers = new HashMap<>(); + headers.put(ONAPLogConstants.Headers.REQUEST_ID, requestId); + String fetchedRequestId = getRequestId(new SimpleHashMap(headers)); + assertEquals(requestId, fetchedRequestId); + } + + @Test + public void setRequestIdRequestIdHeaderTest() { + HashMap<String, String> headers = new HashMap<>(); + headers.put(Constants.HttpHeaders.HEADER_REQUEST_ID, requestId); + String fetchedRequestId = getRequestId(new SimpleHashMap(headers)); + assertEquals(requestId, fetchedRequestId); + } + + @Test + public void setRequestIdTransactionIdHeaderTest() { + HashMap<String, String> headers = new HashMap<>(); + headers.put(Constants.HttpHeaders.TRANSACTION_ID, requestId); + String fetchedRequestId = getRequestId(new SimpleHashMap(headers)); + assertEquals(requestId, fetchedRequestId); + } + + @Test + public void setRequestIdEcompRequestIdHeaderTest() { + HashMap<String, String> headers = new HashMap<>(); + headers.put(Constants.HttpHeaders.ECOMP_REQUEST_ID, requestId); + String fetchedRequestId = getRequestId(new SimpleHashMap(headers)); + assertEquals(requestId, fetchedRequestId); + } + + @Test + public void setRequestIdNoHeaderTest() { + HashMap<String, String> headers = new HashMap<>(); + String fetchedRequestId = getRequestId(new SimpleHashMap(headers)); + assertNotNull(fetchedRequestId); + } + + @Test + public void setInvocationIdTest() { + HashMap<String, String> headers = new HashMap<>(); + headers.put(ONAPLogConstants.Headers.INVOCATION_ID, invocationId); + setInvocationId(new SimpleHashMap(headers)); + assertEquals(invocationId, MDC.get(ONAPLogConstants.MDCs.SERVER_INVOCATION_ID)); + assertEquals(invocationId, MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID)); + } + + @Test + public void setInvocationIdNoHeaderTest() { + HashMap<String, String> headers = new HashMap<>(); + setInvocationId(new SimpleHashMap(headers)); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.SERVER_INVOCATION_ID)); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID)); + } + + @Test + public void setResponseStatusCodeTest() { + setResponseStatusCode(200); + assertEquals("COMPLETE", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE)); + } + + @Test + public void setResponseStatusCodeErrorTest() { + setResponseStatusCode(400); + assertEquals("ERROR", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE)); + assertEquals("400", MDC.get(ONAPLogConstants.MDCs.ERROR_CODE)); + assertEquals("Bad Request", MDC.get(ONAPLogConstants.MDCs.ERROR_DESC)); + } + + @Test + public void clearClientMDCsTest() { + MDC.put(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID, "7b77143c-9b50-410c-ac2f-05758a68e3e9"); + MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, "Bad Gateway"); + MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, "Bad Gateway"); + MDC.put(ONAPLogConstants.MDCs.ERROR_CODE, "502"); + MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, "502"); + MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, "502"); + MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, "SO"); + MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, "SDNC"); + MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, "2019-06-18T02:09:06.024Z"); + + clearClientMDCs(); + assertNull(MDC.get(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID)); + assertNull(MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION)); + assertNull(MDC.get(ONAPLogConstants.MDCs.ERROR_CODE)); + assertNull(MDC.get(ONAPLogConstants.MDCs.ERROR_DESC)); + assertNull(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE)); + assertNull(MDC.get(ONAPLogConstants.MDCs.RESPONSE_CODE)); + assertNull(MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY)); + assertNull(MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME)); + assertNull(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP)); + } + + @Test + public void setTargetEntityTest() { + setTargetEntity(ONAPComponents.SO); + assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY)); + } + + @Test + public void setResponseDescriptionTest() { + setResponseDescription(502); + assertEquals("Bad Gateway", MDC.get(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION)); + } + + @Test + public void setMDCPartnerNameBearerToken() { + MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); + String value = "Bearer some-compex-token"; + headerMap.putSingle(HttpHeaders.AUTHORIZATION, value); + SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap); + + setMDCPartnerName(headers); + + assertEquals(Constants.DefaultValues.UNKNOWN, MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)); + } + + @Test + public void setMDCPartnerNameFromBasicAuth() { + MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); + String value = "Basic dXNlcjpwYXNz"; // decodes to user:pass + headerMap.putSingle(HttpHeaders.AUTHORIZATION, value); + SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap); + + setMDCPartnerName(headers); + + assertEquals("user", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)); + } + + @Test + public void setMDCPartnerNameTest() { + MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); + headerMap.putSingle(ONAPLogConstants.Headers.PARTNER_NAME, "SO"); + SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap); + + setMDCPartnerName(headers); + + assertEquals("SO", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)); + } + + @Test + public void setMDCPartnerNameUserAgentHeaderTest() { + MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); + headerMap.putSingle(HttpHeaders.USER_AGENT, "Apache-HttpClient/4.5.8 (Java/1.8.0_191)"); + SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap); + + setMDCPartnerName(headers); + + assertEquals("Apache-HttpClient/4.5.8 (Java/1.8.0_191)", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)); + } + + @Test + public void setMDCPartnerNameNoHeaderTest() { + MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); + SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap); + + setMDCPartnerName(headers); + + assertEquals("UNKNOWN", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)); + } + + @Test + public void setServerFQDNTest() { + setServerFQDN(); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.SERVER_IP_ADDRESS)); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.SERVER_FQDN)); + } + + @Test + public void setClientIPAddressTest() { + when(httpServletRequest.getHeader("X-Forwarded-For")).thenReturn("127.0.0.2"); + setClientIPAddress(httpServletRequest); + + assertEquals("127.0.0.2", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS)); + } + + @Test + public void setClientIPAddressNoHeaderTest() { + when(httpServletRequest.getRemoteAddr()).thenReturn("127.0.0.1"); + setClientIPAddress(httpServletRequest); + + assertEquals("127.0.0.1", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS)); + } + + @Test + public void setClientIPAddressNullTest() { + setClientIPAddress(null); + + assertEquals("", MDC.get(ONAPLogConstants.MDCs.CLIENT_IP_ADDRESS)); + } + + @Test + public void setEntryTimeStampTest() { + setEntryTimeStamp(); + + assertNotNull(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP)); + } + + @Test + public void setLogTimestampTest() { + setLogTimestamp(); + + assertNotNull(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP)); + } + + @Test + public void setInstanceIDTest() { + setInstanceID(); + + assertNotNull(MDC.get(ONAPLogConstants.MDCs.INSTANCE_UUID)); + } + + @Test + public void getPropertyTest() { + System.setProperty("partnerName", "partnerName"); + + String partnerName = getProperty("partnerName"); + assertEquals("partnerName", partnerName); + } + + @Test + public void getPropertyNullTest() { + String partnerName = getProperty("partner"); + assertEquals("UNKNOWN", partnerName); + } + + @Test + public void overrideServerIp() { + String ip = "127.0.0.1"; + System.setProperty(serverIpAddressOverride, ip); + MDCSetup m = new MDCSetup(); + assertEquals(ip, m.serverIpAddress); + } + + @Test + public void overrideServerFqdn() { + String nodeName = "node300"; + System.setProperty(serverFqdnOverride, nodeName); + MDCSetup m = new MDCSetup(); + assertEquals(nodeName, m.serverFqdn); + } + + @Test + public void testPrecision() { + System.setProperty(MDCSetup.INSTANT_PRECISION_OVERRIDE, "3"); + ZonedDateTime zdt = ZonedDateTime.now(ZoneOffset.UTC); + zdt = zdt.withNano(333666999); + MDCSetup m = new MDCSetup(); + String currentTimestamp = m.getCurrentTimeStamp(); + assertEquals(24, currentTimestamp.length()); + } + +} diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMapTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMapTest.java new file mode 100644 index 00000000..72beacd3 --- /dev/null +++ b/services/src/test/java/org/onap/ccsdk/apps/filters/SimpleServletHeadersMapTest.java @@ -0,0 +1,51 @@ +/*- + * ============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 static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import jakarta.servlet.http.HttpServletRequest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SimpleServletHeadersMapTest { + + @Mock + private HttpServletRequest request; + + @Spy + @InjectMocks + private SimpleServletHeadersMap map; + + @Test + public void getTest() { + when(request.getHeader("testHeader")).thenReturn("testResult"); + String result = map.get("testHeader"); + + assertEquals("testResult", result); + } + +} diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptorTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptorTest.java new file mode 100644 index 00000000..a0599127 --- /dev/null +++ b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/LoggingInterceptorTest.java @@ -0,0 +1,58 @@ +/*- + * ============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.spring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; + +@RunWith(MockitoJUnitRunner.class) +public class LoggingInterceptorTest { + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + @Mock + private Object handler; + + @Spy + @InjectMocks + private LoggingInterceptor loggingInterceptor; + + @Test + public void preHandleTest() throws Exception { + loggingInterceptor.preHandle(request, response, handler); + assertEquals(MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE), "INPROGRESS"); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)); + } +} diff --git a/services/src/test/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilterTest.java b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilterTest.java new file mode 100644 index 00000000..040f6e57 --- /dev/null +++ b/services/src/test/java/org/onap/ccsdk/apps/filters/spring/SpringClientFilterTest.java @@ -0,0 +1,161 @@ +/*- + * ============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.spring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.apps.filters.MDCSetup; +import org.onap.logging.filter.base.Constants; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpResponse; + +@RunWith(MockitoJUnitRunner.class) +public class SpringClientFilterTest extends SpringClientFilter { + + @Mock + private MDCSetup mdcSetup; + + @Mock + private ClientHttpResponse response; + + @Mock + private HttpRequest clientRequest; + + @Mock + private ClientHttpRequestExecution execution; + + @Spy + @InjectMocks + private SpringClientFilter springClientFilter; + + @After + public void tearDown() { + MDC.clear(); + } + + @Test + public void processResponseTest() throws IOException { + String partnerName = getPartnerName(); + assertEquals("UNKNOWN", partnerName); + } + + @Test + public void extractTargetEntityTest() { + HttpHeaders headers = new HttpHeaders(); + headers.add(Constants.HttpHeaders.TARGET_ENTITY_HEADER, "SO"); + when(clientRequest.getHeaders()).thenReturn(headers); + + String targetEntity = springClientFilter.getTargetEntity(clientRequest); + assertEquals("SO", targetEntity); + } + + @Test + public void extractTargetEntityMDCTest() { + MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, "SO"); + HttpHeaders headers = new HttpHeaders(); + when(clientRequest.getHeaders()).thenReturn(headers); + + String targetEntity = springClientFilter.getTargetEntity(clientRequest); + assertEquals("SO", targetEntity); + } + + @Test + public void extractTargetEntityNoHeaderTest() { + HttpHeaders headers = new HttpHeaders(); + when(clientRequest.getHeaders()).thenReturn(headers); + + String targetEntity = springClientFilter.getTargetEntity(clientRequest); + assertEquals("Unknown-Target-Entity", targetEntity); + } + + @Test + public void setupMDCTest() throws URISyntaxException { + URI uri = new URI("onap/so/serviceInstances"); + when(clientRequest.getURI()).thenReturn(uri); + when(clientRequest.getHeaders()).thenReturn(new HttpHeaders()); + setupMDC(clientRequest); + assertEquals("onap/so/serviceInstances", MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME)); + assertEquals("INPROGRESS", MDC.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE)); + assertNotNull(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE); + assertNotNull(ONAPLogConstants.MDCs.SERVICE_NAME); + assertNotNull(ONAPLogConstants.MDCs.SERVER_FQDN); + } + + @Test + public void setupHeadersTest() { + HttpHeaders headers = new HttpHeaders(); + setupHeaders(clientRequest, headers, "0a908a5d-e774-4558-96ff-6edcbba65483", + "4d93e6e2-ff27-4818-9752-1cfe3090d3f1"); + + assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(ONAPLogConstants.Headers.REQUEST_ID)); + assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.HEADER_REQUEST_ID)); + assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.TRANSACTION_ID)); + assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.TRANSACTION_ID)); + assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", headers.getFirst(Constants.HttpHeaders.ECOMP_REQUEST_ID)); + assertNotNull(headers.getFirst(ONAPLogConstants.Headers.INVOCATION_ID)); + assertEquals("UNKNOWN", headers.getFirst(ONAPLogConstants.Headers.PARTNER_NAME)); + } + + @Test + public void extractRequestIDTest() { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, "0a908a5d-e774-4558-96ff-6edcbba65483"); + String requestId = extractRequestID(); + assertEquals("0a908a5d-e774-4558-96ff-6edcbba65483", requestId); + } + + @Test + public void extractRequestIDNullTest() { + // NPE exception will occur when extractRequestID is called if INVOKE_TIMESTAMP is null + MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, + ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT)); + String requestId = extractRequestID(); + assertNotNull(requestId); + assertNotNull(ONAPLogConstants.MDCs.LOG_TIMESTAMP); + assertNotNull(ONAPLogConstants.MDCs.ELAPSED_TIME); + } + + @Test + public void interceptTest() throws IOException { + byte[] body = new byte[3]; + doReturn(response).when(execution).execute(clientRequest, body); + ClientHttpResponse httpResponse = springClientFilter.intercept(clientRequest, body, execution); + assertEquals(response, httpResponse); + } +} |