From e8d29ab5e3775472f59a4997fa3a5df9319de306 Mon Sep 17 00:00:00 2001 From: Eylon Malin Date: Thu, 10 Oct 2019 15:22:07 +0300 Subject: use logging interceptor in SDC client Issue-ID: VID-253 Change-Id: I67947886fd8945a224ee81d5eb0a8fedf1f7317c Signed-off-by: Eylon Malin --- .../java/org/onap/vid/asdc/rest/SdcRestClient.java | 4 --- .../java/org/onap/vid/client/SyncRestClient.java | 30 +++++++++++++++----- .../org/onap/vid/controller/LoggerController.java | 2 +- .../java/org/onap/vid/controller/WebConfig.java | 4 ++- .../ApacheClientMetricRequestInterceptor.java | 33 ++++++++++++++++++++++ .../ApacheClientMetricResponseInterceptor.java | 33 ++++++++++++++++++++++ .../java/org/onap/vid/logging/VidLoggerAspect.java | 16 +++++++++-- .../onap/vid/asdc/rest/SdcRestClientITTest.java | 12 +------- 8 files changed, 108 insertions(+), 26 deletions(-) create mode 100644 vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricRequestInterceptor.java create mode 100644 vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricResponseInterceptor.java (limited to 'vid-app-common') diff --git a/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java b/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java index 96be59123..9efb3893a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java @@ -29,8 +29,6 @@ import static org.onap.vid.client.SyncRestClientInterface.HEADERS.AUTHORIZATION; import static org.onap.vid.client.SyncRestClientInterface.HEADERS.CONTENT_TYPE; import static org.onap.vid.client.SyncRestClientInterface.HEADERS.X_ECOMP_INSTANCE_ID; import static org.onap.vid.client.UnirestPatchKt.extractRawAsString; -import static org.onap.vid.logging.Headers.PARTNER_NAME; -import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; import com.att.eelf.configuration.EELFLogger; import com.google.common.collect.ImmutableMap; @@ -153,9 +151,7 @@ public class SdcRestClient implements AsdcClient { private Map prepareHeaders(String auth, String contentType) { return ImmutableMap.of( X_ECOMP_INSTANCE_ID, SystemProperties.getProperty(APP_DISPLAY_NAME), - PARTNER_NAME.getHeaderName(), PARTNER_NAME.getHeaderValue(), AUTHORIZATION, auth, - REQUEST_ID_HEADER_KEY, Logging.extractOrGenerateRequestId(), CONTENT_TYPE, contentType ); } diff --git a/vid-app-common/src/main/java/org/onap/vid/client/SyncRestClient.java b/vid-app-common/src/main/java/org/onap/vid/client/SyncRestClient.java index 5c65c8af4..0883b3084 100644 --- a/vid-app-common/src/main/java/org/onap/vid/client/SyncRestClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/client/SyncRestClient.java @@ -49,10 +49,13 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.eclipse.jetty.util.security.Password; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.logging.ApacheClientMetricRequestInterceptor; +import org.onap.vid.logging.ApacheClientMetricResponseInterceptor; import org.onap.vid.properties.VidProperties; import org.onap.vid.utils.Logging; import org.springframework.http.HttpMethod; @@ -68,22 +71,29 @@ public class SyncRestClient implements SyncRestClientInterface { private RestClient restClient; public SyncRestClient(Logging loggingService) { - this(null, null, loggingService); + this(null, null, loggingService, false); + } + + public SyncRestClient(Logging loggingService, boolean useLoggingInterceptor) { + this(null, null, loggingService, useLoggingInterceptor); } public SyncRestClient(ObjectMapper objectMapper, Logging loggingService) { - this(null, objectMapper, loggingService); + this(null, objectMapper, loggingService, false); } public SyncRestClient(CloseableHttpClient httpClient, Logging loggingService) { - this(httpClient, null, loggingService); + this(httpClient, null, loggingService, false); } - public SyncRestClient(CloseableHttpClient httpClient, ObjectMapper objectMapper, Logging loggingService) { + public SyncRestClient(CloseableHttpClient httpClient, + ObjectMapper objectMapper, + Logging loggingService, + boolean useLoggingInterceptor) { restClient = RestClient .newClient() .objectMapper(ObjectUtils.defaultIfNull(objectMapper, defaultObjectMapper())) - .httpClient(ObjectUtils.defaultIfNull(httpClient , defaultHttpClient())) + .httpClient(ObjectUtils.defaultIfNull(httpClient , defaultHttpClient(useLoggingInterceptor))) .build(); this.loggingService = loggingService; this.outgoingRequestsLogger = Logging.getRequestsLogger("syncRestClient"); @@ -253,7 +263,7 @@ public class SyncRestClient implements SyncRestClientInterface { return JOSHWORKS_JACKSON_OBJECT_MAPPER; } - private CloseableHttpClient defaultHttpClient() { + private CloseableHttpClient defaultHttpClient(boolean useLoggingInterceptor) { try { String trustStorePath = SystemProperties.getProperty(VidProperties.VID_TRUSTSTORE_FILENAME); String trustStorePass = SystemProperties.getProperty(VidProperties.VID_TRUSTSTORE_PASSWD_X); @@ -263,7 +273,13 @@ public class SyncRestClient implements SyncRestClientInterface { SSLContext sslContext = trustOwnCACerts(decryptedTrustStorePass, trustStore); SSLConnectionSocketFactory sslSf = allowTLSProtocols(sslContext); - return HttpClients.custom().setSSLSocketFactory(sslSf).build(); + HttpClientBuilder httpClientBuilder = HttpClients.custom().setSSLSocketFactory(sslSf); + if (useLoggingInterceptor) { + httpClientBuilder + .addInterceptorFirst(new ApacheClientMetricRequestInterceptor()) + .addInterceptorLast(new ApacheClientMetricResponseInterceptor()); + } + return httpClientBuilder.build(); } catch (IOException | CertificateException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) { logger.warn("Cannot initialize custom http client from current configuration. Using default one.", e); return HttpClients.createDefault(); diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java b/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java index 928e19357..48677120d 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java @@ -65,7 +65,7 @@ public class LoggerController extends RestrictedBaseController { this.logfilePathCreator = logfilePathCreator; } - @GetMapping(value = "/{loggerName:audit|audit2019|error|metrics}") + @GetMapping(value = "/{loggerName:audit|audit2019|error|metrics|metrics2019}") public String getLog(@PathVariable String loggerName, HttpServletRequest request, @RequestParam(value="limit", defaultValue = "5000") Integer limit) throws IOException { diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java b/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java index 9faa7ade5..6936d0a71 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java @@ -160,7 +160,9 @@ public class WebConfig { String protocol = asdcClientConfiguration.getAsdcClientProtocol(); int port = asdcClientConfiguration.getAsdcClientPort(); - return new SdcRestClient(protocol + "://" + host + ":" + port + "/", auth, new SyncRestClient(loggingService), loggingService); + return new SdcRestClient(protocol + "://" + host + ":" + port + "/", auth, + new SyncRestClient( loggingService, true), + loggingService); } @Bean diff --git a/vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricRequestInterceptor.java b/vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricRequestInterceptor.java new file mode 100644 index 000000000..0cc5a2aaa --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricRequestInterceptor.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 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.vid.logging; + +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.protocol.HttpContext; + +public class ApacheClientMetricRequestInterceptor extends ApacheClientMetricInterceptor implements HttpRequestInterceptor { + + @Override + public void process(HttpRequest request, HttpContext context) { + this.pre(request, request); + } +} diff --git a/vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricResponseInterceptor.java b/vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricResponseInterceptor.java new file mode 100644 index 000000000..72b54e7a5 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/logging/ApacheClientMetricResponseInterceptor.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 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.vid.logging; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.protocol.HttpContext; + +public class ApacheClientMetricResponseInterceptor extends ApacheClientMetricInterceptor implements HttpResponseInterceptor { + + @Override + public void process(HttpResponse response, HttpContext context) { + this.post(null, response); + } +} diff --git a/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggerAspect.java b/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggerAspect.java index 309ead40c..f87297c37 100644 --- a/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggerAspect.java +++ b/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggerAspect.java @@ -32,6 +32,7 @@ import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.portalsdk.core.logging.aspect.EELFLoggerAdvice; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.service.AppService; @@ -39,6 +40,7 @@ import org.onap.portalsdk.core.util.SystemProperties; import org.onap.portalsdk.core.web.support.UserUtils; import org.onap.vid.controller.ControllersUtils; import org.onap.vid.utils.SystemPropertiesWrapper; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -87,9 +89,10 @@ public class VidLoggerAspect { Object[] passOnArgs = new Object[] {joinPoint.getSignature().getDeclaringType().getName(),joinPoint.getSignature().getName()}; Object[] returnArgs = advice.before(securityEventType, fabricateArgsWithNull(), passOnArgs); - fixSetRequestBasedDefaultsIntoGlobalLoggingContext(httpServletRequestOrNull(joinPoint), + HttpServletRequest httpServletRequest = httpServletRequestOrNull(joinPoint); + fixSetRequestBasedDefaultsIntoGlobalLoggingContext(httpServletRequest, joinPoint.getSignature().getDeclaringType().getName()); - + addRequestIdToMdcForMetricFilter(httpServletRequest); fixServerFqdnInMDC(); //Execute the actual method @@ -108,6 +111,14 @@ public class VidLoggerAspect { return result; } + //prepare MDC for org.onap.logging.filter.base.AbstractMetricLogFilter + private void addRequestIdToMdcForMetricFilter(HttpServletRequest httpServletRequest) { + if (httpServletRequest!=null) { + String requestId = UserUtils.getRequestId(httpServletRequest); + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId); + } + } + // Set the status code into MDC *before* the metrics log is written by advice.after() private void fixStatusCodeInMDC(String restStatus) { EELFLoggerDelegate.mdcPut(SystemProperties.STATUS_CODE, restStatus); @@ -155,6 +166,7 @@ public class VidLoggerAspect { String loginId = controllersUtils.extractUserId(httpServletRequest); logger.setRequestBasedDefaultsIntoGlobalLoggingContext(httpServletRequest, appName, requestId, loginId); + } } diff --git a/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java b/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java index 7cbf0805b..3a76a33e2 100644 --- a/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java @@ -24,18 +24,13 @@ import static com.xebialabs.restito.semantics.Action.ok; import static com.xebialabs.restito.semantics.Action.stringContent; import static org.apache.http.client.config.RequestConfig.custom; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.collection.IsIterableContainingInOrder.contains; -import static org.hamcrest.collection.IsMapContaining.hasEntry; import static org.hamcrest.collection.IsMapContaining.hasKey; -import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.onap.vid.client.SyncRestClientInterface.HEADERS.X_ECOMP_INSTANCE_ID; -import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; import com.fasterxml.jackson.core.JsonProcessingException; import com.xebialabs.restito.semantics.Call; @@ -129,12 +124,7 @@ public class SdcRestClientITTest { assertTrue(first.isPresent()); - assertThat(first.get().getHeaders(), - allOf( - hasEntry(equalToIgnoringCase(REQUEST_ID_HEADER_KEY), contains(matchesPattern(UUID_REGEX))), - hasKey(equalToIgnoringCase(X_ECOMP_INSTANCE_ID)), - hasEntry(equalToIgnoringCase("x-onap-partnerName"), contains(equalTo("VID.VID"))) - )); + assertThat(first.get().getHeaders(), hasKey(equalToIgnoringCase(X_ECOMP_INSTANCE_ID))); } private Service getExpectedService(String stringId) { -- cgit 1.2.3-korg