diff options
author | Fiete Ostkamp <Fiete.Ostkamp@telekom.de> | 2023-09-06 08:32:33 +0200 |
---|---|---|
committer | Fiete Ostkamp <Fiete.Ostkamp@telekom.de> | 2023-09-11 10:29:53 +0200 |
commit | c3c2eec967891108459c45786f8e98a85004e678 (patch) | |
tree | 2d79ce5e08658f05d054367693a905813dd80172 /lib | |
parent | 1a23a1bcdf17ba4cf1cafb8e65babd1ad8666e59 (diff) |
Add Micrometer [bff]montreal
- add Micrometer dependencies
- uses Zipkin as trace protocol, typically for port 9411
- requires changing dependency injection of WebClient.Builder [1]
[1] Micrometer is injecting the trace context into the WebClient.Builder bean.
To add the ExchangeFilterFunctions for authentication, errorhandling and logging, the existing bean needs to be modified instead of statically creating a new one
Issue-ID: PORTALNG-57
Change-Id: I13dd18d297cd56fa2dfbb525723c79f4abb41f87
Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/build.gradle | 5 | ||||
-rw-r--r-- | lib/src/main/java/org/onap/portalng/bff/config/BeansConfig.java | 31 | ||||
-rw-r--r-- | lib/src/main/java/org/onap/portalng/bff/config/WebClientConfig.java | 56 |
3 files changed, 65 insertions, 27 deletions
diff --git a/lib/build.gradle b/lib/build.gradle index e72062d..93064db 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -30,6 +30,11 @@ dependencies { implementation "org.mapstruct.extensions.spring:mapstruct-spring-annotations:$mapStructExtensionsVersion" implementation "org.mapstruct.extensions.spring:mapstruct-spring-extensions:$mapStructExtensionsVersion" + implementation(platform("io.micrometer:micrometer-tracing-bom:$micrometerVersion")) + implementation("io.micrometer:micrometer-tracing") + implementation("io.micrometer:micrometer-tracing-bridge-otel") + implementation("io.opentelemetry:opentelemetry-exporter-zipkin") + annotationProcessor "org.mapstruct:mapstruct-processor:$mapStructVersion" annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' diff --git a/lib/src/main/java/org/onap/portalng/bff/config/BeansConfig.java b/lib/src/main/java/org/onap/portalng/bff/config/BeansConfig.java index 926108a..3eb5f87 100644 --- a/lib/src/main/java/org/onap/portalng/bff/config/BeansConfig.java +++ b/lib/src/main/java/org/onap/portalng/bff/config/BeansConfig.java @@ -33,11 +33,8 @@ import java.util.List; import lombok.extern.slf4j.Slf4j; import org.onap.portalng.bff.exceptions.DownstreamApiProblemException; import org.onap.portalng.bff.utils.Logger; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; @@ -46,7 +43,6 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeStrategies; -import org.springframework.web.reactive.function.client.WebClient; import org.zalando.problem.jackson.ProblemModule; import reactor.core.publisher.Mono; @@ -55,12 +51,12 @@ import reactor.core.publisher.Mono; public class BeansConfig { public static final String OAUTH2_EXCHANGE_FILTER_FUNCTION = "oauth2ExchangeFilterFunction"; - private static final String ID_TOKEN_EXCHANGE_FILTER_FUNCTION = "idTokenExchangeFilterFunction"; - private static final String ERROR_HANDLING_EXCHANGE_FILTER_FUNCTION = + public static final String ID_TOKEN_EXCHANGE_FILTER_FUNCTION = "idTokenExchangeFilterFunction"; + public static final String ERROR_HANDLING_EXCHANGE_FILTER_FUNCTION = "errorHandlingExchangeFilterFunction"; - private static final String LOG_REQUEST_EXCHANGE_FILTER_FUNCTION = + public static final String LOG_REQUEST_EXCHANGE_FILTER_FUNCTION = "logRequestExchangeFilterFunction"; - private static final String LOG_RESPONSE_EXCHANGE_FILTER_FUNCTION = + public static final String LOG_RESPONSE_EXCHANGE_FILTER_FUNCTION = "logResponseExchangeFilterFunction"; private static final String CLIENT_REGISTRATION_ID = "keycloak"; public static final String X_REQUEST_ID = "X-Request-Id"; @@ -148,25 +144,6 @@ public class BeansConfig { .build(); } - // we need to use prototype scope to always create new instance of the bean - // because internally WebClient.Builder is mutable - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - WebClient.Builder webClientBuilder( - ExchangeStrategies exchangeStrategies, - @Qualifier(ID_TOKEN_EXCHANGE_FILTER_FUNCTION) - ExchangeFilterFunction idTokenExchangeFilterFunction, - @Qualifier(ERROR_HANDLING_EXCHANGE_FILTER_FUNCTION) - ExchangeFilterFunction errorHandlingExchangeFilterFunction, - @Qualifier(LOG_RESPONSE_EXCHANGE_FILTER_FUNCTION) - ExchangeFilterFunction logResponseExchangeFilterFunction) { - return WebClient.builder() - .exchangeStrategies(exchangeStrategies) - .filter(idTokenExchangeFilterFunction) - .filter(errorHandlingExchangeFilterFunction) - .filter(logResponseExchangeFilterFunction); - } - @Bean Clock clock() { return Clock.systemUTC(); diff --git a/lib/src/main/java/org/onap/portalng/bff/config/WebClientConfig.java b/lib/src/main/java/org/onap/portalng/bff/config/WebClientConfig.java new file mode 100644 index 0000000..7aa31bf --- /dev/null +++ b/lib/src/main/java/org/onap/portalng/bff/config/WebClientConfig.java @@ -0,0 +1,56 @@ +package org.onap.portalng.bff.config; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.ExchangeStrategies; +import org.springframework.web.reactive.function.client.WebClient; + +@Configuration +public class WebClientConfig { + + @Component + public static class WebClientBeanPostProcessor implements BeanPostProcessor { + + private final ExchangeStrategies exchangeStrategies; + private final ExchangeFilterFunction idTokenExchangeFilterFunction; + private final ExchangeFilterFunction errorHandlingExchangeFilterFunction; + private final ExchangeFilterFunction logResponseExchangeFilterFunction; + + public WebClientBeanPostProcessor( + ExchangeStrategies exchangeStrategies, + @Qualifier(BeansConfig.ID_TOKEN_EXCHANGE_FILTER_FUNCTION) + ExchangeFilterFunction idTokenExchangeFilterFunction, + @Qualifier(BeansConfig.ERROR_HANDLING_EXCHANGE_FILTER_FUNCTION) + ExchangeFilterFunction errorHandlingExchangeFilterFunction, + @Qualifier(BeansConfig.LOG_RESPONSE_EXCHANGE_FILTER_FUNCTION) + ExchangeFilterFunction logResponseExchangeFilterFunction) { + this.exchangeStrategies = exchangeStrategies; + this.idTokenExchangeFilterFunction = idTokenExchangeFilterFunction; + this.errorHandlingExchangeFilterFunction = errorHandlingExchangeFilterFunction; + this.logResponseExchangeFilterFunction = logResponseExchangeFilterFunction; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof WebClient.Builder builder) { + return builder + .exchangeStrategies(exchangeStrategies) + .filter(idTokenExchangeFilterFunction) + .filter(errorHandlingExchangeFilterFunction) + .filter(logResponseExchangeFilterFunction); + } + return bean; + } + } +} |