From de7a573e413e5b32bd4c4d2b20d2488d6eca87a8 Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Thu, 31 Mar 2022 12:08:56 +0200 Subject: NONRTRIC PMS using authorization token Added support for PMS sending an authorization token in each REST call(in the HTTP header). The token is read from a file. Issue-ID: CCSDK-3560 Signed-off-by: PatrikBuhr Change-Id: I92229f67d2c1486530f3c6ebb22f60bd3b359676 --- a1-policy-management/config/application.yaml | 9 ++- .../a1policymanagementservice/BeanFactory.java | 6 +- .../clients/A1ClientFactory.java | 4 +- .../clients/AsyncRestClient.java | 94 +++++++++------------- .../clients/AsyncRestClientFactory.java | 11 +-- .../clients/SecurityContext.java | 76 +++++++++++++++++ .../dmaap/DmaapMessageConsumer.java | 5 +- .../tasks/RefreshConfigTask.java | 8 +- .../tasks/RicSupervision.java | 5 +- .../clients/A1ClientFactoryTest.java | 3 +- .../clients/AsyncRestClientTest.java | 3 +- .../clients/CcsdkA1AdapterClientTest.java | 2 +- .../controllers/v2/ApplicationTest.java | 24 +++++- .../v2/ConfigurationControllerTest.java | 3 +- .../controllers/v2/RappSimulatorController.java | 19 ++++- .../dmaap/DmaapMessageConsumerTest.java | 9 ++- .../tasks/RefreshConfigTaskTest.java | 8 +- .../tasks/RicSupervisionTest.java | 3 +- .../tasks/RicSynchronizationTaskTest.java | 4 +- .../utils/MockA1ClientFactory.java | 5 +- 20 files changed, 207 insertions(+), 94 deletions(-) create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java (limited to 'a1-policy-management') diff --git a/a1-policy-management/config/application.yaml b/a1-policy-management/config/application.yaml index 5684c463..7628624d 100644 --- a/a1-policy-management/config/application.yaml +++ b/a1-policy-management/config/application.yaml @@ -42,7 +42,7 @@ logging: org.springframework.data: ERROR org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR org.onap.ccsdk.oran.a1policymanagementservice: INFO - # org.onap.ccsdk.oran.a1policymanagementservice.tasks: TRACE + # org.onap.ccsdk.oran.a1policymanagementservice.tasks: TRACE file: name: /var/log/policy-agent/application.log server: @@ -74,7 +74,10 @@ app: http.proxy-type: HTTP # path where the service can store data vardata-directory: /var/policy-management-service - # the config-file-schema-path referres to a location in the jar file. If this property is empty or missing, - # no schema validation will be executed. + # the config-file-schema-path referres to a location in the jar file. If this property is empty or missing, + # no schema validation will be executed. config-file-schema-path: /application_configuration_schema.json + # A file containing an authorization token, which shall be inserted in each HTTP header (authorization). + # If the file name is empty, no authorization token is sent. + auth-token-file: diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/BeanFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/BeanFactory.java index 93fd2f77..bf161954 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/BeanFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/BeanFactory.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.catalina.connector.Connector; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; @@ -56,8 +57,9 @@ public class BeanFactory { } @Bean - public A1ClientFactory getA1ClientFactory(@Autowired ApplicationConfig applicationConfig) { - return new A1ClientFactory(applicationConfig); + public A1ClientFactory getA1ClientFactory(@Autowired ApplicationConfig applicationConfig, + @Autowired SecurityContext securityContext) { + return new A1ClientFactory(applicationConfig, securityContext); } @Bean diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java index 642385aa..1d465c3a 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java @@ -43,9 +43,9 @@ public class A1ClientFactory { private final AsyncRestClientFactory restClientFactory; @Autowired - public A1ClientFactory(ApplicationConfig appConfig) { + public A1ClientFactory(ApplicationConfig appConfig, SecurityContext securityContext) { this.appConfig = appConfig; - this.restClientFactory = new AsyncRestClientFactory(appConfig.getWebClientConfig()); + this.restClientFactory = new AsyncRestClientFactory(appConfig.getWebClientConfig(), securityContext); } /** diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java index 3461876d..959d85e2 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java @@ -2,7 +2,7 @@ * ========================LICENSE_START================================= * ONAP : ccsdk oran * ====================================================================== - * Copyright (C) 2019-2020 Nordix Foundation. All rights reserved. + * Copyright (C) 2019-2022 Nordix Foundation. 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. @@ -35,13 +35,14 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.lang.Nullable; +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.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec; -import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; +import reactor.netty.transport.ProxyProvider; /** * Generic reactive REST client. @@ -54,17 +55,17 @@ public class AsyncRestClient { private static final AtomicInteger sequenceNumber = new AtomicInteger(); private final SslContext sslContext; private final HttpProxyConfig httpProxyConfig; + private final SecurityContext securityContext; - public AsyncRestClient(String baseUrl, @Nullable SslContext sslContext, @Nullable HttpProxyConfig httpProxyConfig) { + public AsyncRestClient(String baseUrl, @Nullable SslContext sslContext, @Nullable HttpProxyConfig httpProxyConfig, + SecurityContext securityContext) { this.baseUrl = baseUrl; this.sslContext = sslContext; this.httpProxyConfig = httpProxyConfig; + this.securityContext = securityContext; } public Mono> postForEntity(String uri, @Nullable String body) { - Object traceTag = createTraceTag(); - logger.debug("{} POST uri = '{}{}'", traceTag, baseUrl, uri); - logger.trace("{} POST body: {}", traceTag, body); Mono bodyProducer = body != null ? Mono.just(body) : Mono.empty(); RequestHeadersSpec request = getWebClient() // @@ -72,7 +73,7 @@ public class AsyncRestClient { .uri(uri) // .contentType(MediaType.APPLICATION_JSON) // .body(bodyProducer, String.class); - return retrieve(traceTag, request); + return retrieve(request); } public Mono post(String uri, @Nullable String body) { @@ -81,41 +82,30 @@ public class AsyncRestClient { } public Mono postWithAuthHeader(String uri, String body, String username, String password) { - Object traceTag = createTraceTag(); - logger.debug("{} POST (auth) uri = '{}{}'", traceTag, baseUrl, uri); - logger.trace("{} POST body: {}", traceTag, body); - RequestHeadersSpec request = getWebClient() // .post() // .uri(uri) // .headers(headers -> headers.setBasicAuth(username, password)) // .contentType(MediaType.APPLICATION_JSON) // .bodyValue(body); - return retrieve(traceTag, request) // + return retrieve(request) // .map(this::toBody); } public Mono> putForEntity(String uri, String body) { - Object traceTag = createTraceTag(); - logger.debug("{} PUT uri = '{}{}'", traceTag, baseUrl, uri); - logger.trace("{} PUT body: {}", traceTag, body); - RequestHeadersSpec request = getWebClient() // .put() // .uri(uri) // .contentType(MediaType.APPLICATION_JSON) // .bodyValue(body); - return retrieve(traceTag, request); + return retrieve(request); } public Mono> putForEntity(String uri) { - Object traceTag = createTraceTag(); - logger.debug("{} PUT uri = '{}{}'", traceTag, baseUrl, uri); - logger.trace("{} PUT body: ", traceTag); RequestHeadersSpec request = getWebClient() // .put() // .uri(uri); - return retrieve(traceTag, request); + return retrieve(request); } public Mono put(String uri, String body) { @@ -124,12 +114,8 @@ public class AsyncRestClient { } public Mono> getForEntity(String uri) { - Object traceTag = createTraceTag(); - logger.debug("{} GET uri = '{}{}'", traceTag, baseUrl, uri); - RequestHeadersSpec request = getWebClient() // - .get() // - .uri(uri); - return retrieve(traceTag, request); + RequestHeadersSpec request = getWebClient().get().uri(uri); + return retrieve(request); } public Mono get(String uri) { @@ -138,12 +124,8 @@ public class AsyncRestClient { } public Mono> deleteForEntity(String uri) { - Object traceTag = createTraceTag(); - logger.debug("{} DELETE uri = '{}{}'", traceTag, baseUrl, uri); - RequestHeadersSpec request = getWebClient() // - .delete() // - .uri(uri); - return retrieve(traceTag, request); + RequestHeadersSpec request = getWebClient().delete().uri(uri); + return retrieve(request); } public Mono delete(String uri) { @@ -151,32 +133,18 @@ public class AsyncRestClient { .map(this::toBody); } - private Mono> retrieve(Object traceTag, RequestHeadersSpec request) { - final Class clazz = String.class; + private Mono> retrieve(RequestHeadersSpec request) { + if (securityContext.isConfigured()) { + request.headers(h -> h.setBearerAuth(securityContext.getBearerAuthToken())); + } return request.retrieve() // - .toEntity(clazz) // - .doOnNext(entity -> logReceivedData(traceTag, entity)) // - .doOnError(throwable -> onHttpError(traceTag, throwable)); - } - - private void logReceivedData(Object traceTag, ResponseEntity entity) { - logger.trace("{} Received: {} {}", traceTag, entity.getBody(), entity.getHeaders().getContentType()); + .toEntity(String.class); } private static Object createTraceTag() { return sequenceNumber.incrementAndGet(); } - private void onHttpError(Object traceTag, Throwable t) { - if (t instanceof WebClientResponseException) { - WebClientResponseException exception = (WebClientResponseException) t; - logger.debug("{} HTTP error status = '{}', body '{}'", traceTag, exception.getStatusCode(), - exception.getResponseBodyAsString()); - } else { - logger.debug("{} HTTP error {}", traceTag, t.getMessage()); - } - } - private String toBody(ResponseEntity entity) { if (entity.getBody() == null) { return ""; @@ -203,22 +171,36 @@ public class AsyncRestClient { } if (isHttpProxyConfigured()) { - httpClient = httpClient.proxy(proxy -> proxy.type(httpProxyConfig.httpProxyType()) // - .host(httpProxyConfig.httpProxyHost()) // - .port(httpProxyConfig.httpProxyPort())); + httpClient = httpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP) + .host(httpProxyConfig.httpProxyHost()).port(httpProxyConfig.httpProxyPort())); } return httpClient; } - private WebClient buildWebClient(String baseUrl) { + public WebClient buildWebClient(String baseUrl) { + Object traceTag = createTraceTag(); + final HttpClient httpClient = buildHttpClient(); ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() // .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) // .build(); + + ExchangeFilterFunction reqLogger = ExchangeFilterFunction.ofRequestProcessor(req -> { + logger.debug("{} {} uri = '{}''", traceTag, req.method(), req.url()); + return Mono.just(req); + }); + + ExchangeFilterFunction respLogger = ExchangeFilterFunction.ofResponseProcessor(resp -> { + logger.debug("{} resp: {}", traceTag, resp.statusCode()); + return Mono.just(resp); + }); + return WebClient.builder() // .clientConnector(new ReactorClientHttpConnector(httpClient)) // .baseUrl(baseUrl) // .exchangeStrategies(exchangeStrategies) // + .filter(reqLogger) // + .filter(respLogger) // .build(); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java index cde6647a..844db540 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java @@ -2,7 +2,7 @@ * ========================LICENSE_START================================= * ONAP : ccsdk oran * ====================================================================== - * Copyright (C) 2019-2020 Nordix Foundation. All rights reserved. + * Copyright (C) 2019-2022 Nordix Foundation. 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. @@ -50,14 +50,14 @@ import org.springframework.util.ResourceUtils; /** * Factory for a generic reactive REST client. */ -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally public class AsyncRestClientFactory { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final SslContextFactory sslContextFactory; private final HttpProxyConfig httpProxyConfig; + private final SecurityContext securityContext; - public AsyncRestClientFactory(WebClientConfig clientConfig) { + public AsyncRestClientFactory(WebClientConfig clientConfig, SecurityContext securityContext) { if (clientConfig != null) { this.sslContextFactory = new CachingSslContextFactory(clientConfig); this.httpProxyConfig = clientConfig.httpProxyConfig(); @@ -66,6 +66,7 @@ public class AsyncRestClientFactory { this.sslContextFactory = null; this.httpProxyConfig = null; } + this.securityContext = securityContext; } public AsyncRestClient createRestClientNoHttpProxy(String baseUrl) { @@ -80,13 +81,13 @@ public class AsyncRestClientFactory { if (this.sslContextFactory != null) { try { return new AsyncRestClient(baseUrl, this.sslContextFactory.createSslContext(), - useHttpProxy ? httpProxyConfig : null); + useHttpProxy ? httpProxyConfig : null, this.securityContext); } catch (Exception e) { String exceptionString = e.toString(); logger.error("Could not init SSL context, reason: {}", exceptionString); } } - return new AsyncRestClient(baseUrl, null, httpProxyConfig); + return new AsyncRestClient(baseUrl, null, httpProxyConfig, this.securityContext); } private class SslContextFactory { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java new file mode 100644 index 00000000..3566aada --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java @@ -0,0 +1,76 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2019-2022 Nordix Foundation. 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.oran.a1policymanagementservice.clients; + +import java.lang.invoke.MethodHandles; +import java.nio.file.Files; +import java.nio.file.Path; + +import lombok.Setter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.stereotype.Component; + +@EnableConfigurationProperties +@ConfigurationProperties() +@Component +public class SecurityContext { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private long tokenTimestamp = 0; + + private String authToken = ""; + + @Setter + private Path authTokenFilePath; + + public SecurityContext(@Value("${app.auth-token-file:\"\"}") String authTokenFilename) { + if (!authTokenFilename.isEmpty()) { + this.authTokenFilePath = Path.of(authTokenFilename); + } + } + + public boolean isConfigured() { + return authTokenFilePath != null; + } + + public synchronized String getBearerAuthToken() { + if (!isConfigured()) { + return ""; + } + try { + long lastModified = authTokenFilePath.toFile().lastModified(); + if (lastModified != this.tokenTimestamp) { + this.authToken = Files.readString(authTokenFilePath); + this.tokenTimestamp = lastModified; + } + } catch (Exception e) { + logger.warn("Could not read auth token file: {}, reason: {}", authTokenFilePath, e.getMessage()); + } + return this.authToken; + } + +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java index bc67e663..1224d00b 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java @@ -32,6 +32,7 @@ import java.util.List; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -109,11 +110,11 @@ public class DmaapMessageConsumer { } @Autowired - public DmaapMessageConsumer(ApplicationConfig applicationConfig) { + public DmaapMessageConsumer(ApplicationConfig applicationConfig, SecurityContext securityContext) { this.applicationConfig = applicationConfig; GsonBuilder gsonBuilder = new GsonBuilder(); this.gson = gsonBuilder.create(); - this.restClientFactory = new AsyncRestClientFactory(applicationConfig.getWebClientConfig()); + this.restClientFactory = new AsyncRestClientFactory(applicationConfig.getWebClientConfig(), securityContext); } /** diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java index 651ba5ed..e3d489b5 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java @@ -31,6 +31,7 @@ import lombok.Getter; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig.RicConfigUpdate; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser; @@ -88,7 +89,8 @@ public class RefreshConfigTask { @Autowired public RefreshConfigTask(ConfigurationFile configurationFile, ApplicationConfig appConfig, Rics rics, - Policies policies, Services services, PolicyTypes policyTypes, A1ClientFactory a1ClientFactory) { + Policies policies, Services services, PolicyTypes policyTypes, A1ClientFactory a1ClientFactory, + SecurityContext securityContext) { this.configurationFile = configurationFile; this.appConfig = appConfig; this.rics = rics; @@ -96,7 +98,7 @@ public class RefreshConfigTask { this.services = services; this.policyTypes = policyTypes; this.a1ClientFactory = a1ClientFactory; - this.restClientFactory = new AsyncRestClientFactory(appConfig.getWebClientConfig()); + this.restClientFactory = new AsyncRestClientFactory(appConfig.getWebClientConfig(), securityContext); } public void start() { @@ -171,7 +173,7 @@ public class RefreshConfigTask { /** * for an added RIC after a restart it is nesessary to get the suypported policy * types from the RIC unless a full synchronization is wanted. - * + * * @param ric the ric to get supprted types from * @return the same ric */ diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java index 2c037838..8926ec16 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java @@ -25,6 +25,7 @@ import java.util.Collection; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock.LockType; @@ -87,13 +88,13 @@ public class RicSupervision { @Autowired public RicSupervision(Rics rics, Policies policies, A1ClientFactory a1ClientFactory, PolicyTypes policyTypes, - Services services, ApplicationConfig config) { + Services services, ApplicationConfig config, SecurityContext securityContext) { this.rics = rics; this.policies = policies; this.a1ClientFactory = a1ClientFactory; this.policyTypes = policyTypes; this.services = services; - this.restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig()); + this.restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig(), securityContext); } /** diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java index 3ca35430..645f2353 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java @@ -79,7 +79,8 @@ class A1ClientFactoryTest { @BeforeEach void createFactoryUnderTest() { - factoryUnderTest = spy(new A1ClientFactory(applicationConfigMock)); + SecurityContext sec = new SecurityContext(""); + factoryUnderTest = spy(new A1ClientFactory(applicationConfigMock, sec)); this.ric = new Ric(ricConfig("")); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientTest.java index 2e583f65..69a74b67 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientTest.java @@ -58,7 +58,8 @@ class AsyncRestClientTest { InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE); Loggers.useJdkLoggers(); mockWebServer = new MockWebServer(); - clientUnderTest = new AsyncRestClient(mockWebServer.url(BASE_URL).toString(), null, null); + clientUnderTest = + new AsyncRestClient(mockWebServer.url(BASE_URL).toString(), null, null, new SecurityContext("")); } @AfterAll diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java index ced739ad..f49020ee 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java @@ -84,7 +84,7 @@ class CcsdkA1AdapterClientTest { @Test void createClientWithWrongProtocol_thenErrorIsThrown() { - AsyncRestClient asyncRestClient = new AsyncRestClient("", null, null); + AsyncRestClient asyncRestClient = new AsyncRestClient("", null, null, new SecurityContext("")); assertThrows(IllegalArgumentException.class, () -> { new CcsdkA1AdapterClient(A1ProtocolType.STD_V1_1, null, null, asyncRestClient); }); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java index 75215613..569cb577 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java @@ -2,7 +2,7 @@ * ========================LICENSE_START================================= * ONAP : ccsdk oran * ====================================================================== - * Copyright (C) 2019-2020 Nordix Foundation. All rights reserved. + * Copyright (C) 2019-2022 Nordix Foundation. 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. @@ -35,6 +35,7 @@ import java.io.IOException; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; import java.time.Instant; @@ -49,6 +50,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig.RicConfigUpdate; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; @@ -100,6 +102,7 @@ import reactor.util.annotation.Nullable; @TestPropertySource(properties = { // "server.ssl.key-store=./src/test/resources/keystore.jks", // "app.webclient.trust-store=./src/test/resources/truststore.jks", // + "app.webclient.trust-store-used=true", // "app.vardata-directory=./target/testdata", // "app.filepath=" // }) @@ -136,6 +139,9 @@ class ApplicationTest { @Autowired RefreshConfigTask refreshConfigTask; + @Autowired + SecurityContext securityContext; + private static Gson gson = new GsonBuilder().create(); /** @@ -174,6 +180,7 @@ class ApplicationTest { a1ClientFactory.reset(); this.rAppSimulator.getTestResults().clear(); this.a1ClientFactory.setPolicyTypes(policyTypes); // Default same types in RIC and in this app + this.securityContext.setAuthTokenFilePath(null); } @AfterEach @@ -831,7 +838,13 @@ class ApplicationTest { } @Test - void testServiceNotification() throws ServiceException { + void testServiceNotification() throws Exception { + + final String AUTH_TOKEN = "testToken"; + Path authFile = Files.createTempFile("pmsTestAuthToken", ".txt"); + Files.write(authFile, AUTH_TOKEN.getBytes()); + this.securityContext.setAuthTokenFilePath(authFile); + putService("junkService"); Service junkService = this.services.get("junkService"); junkService.setCallbackUrl("https://junk"); @@ -847,6 +860,11 @@ class ApplicationTest { ServiceCallbackInfo callbackInfo = receivedCallbacks.getReceivedInfo().get(0); assertThat(callbackInfo.ricId).isEqualTo("ric1"); assertThat(callbackInfo.eventType).isEqualTo(ServiceCallbackInfo.EventType.AVAILABLE); + + var headers = receivedCallbacks.receivedHeaders.get(0); + assertThat(headers).containsEntry("authorization", "Bearer " + AUTH_TOKEN); + + Files.delete(authFile); } private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException { @@ -941,7 +959,7 @@ class ApplicationTest { .httpProxyConfig(config.httpProxyConfig()) // .build(); - AsyncRestClientFactory f = new AsyncRestClientFactory(config); + AsyncRestClientFactory f = new AsyncRestClientFactory(config, new SecurityContext("")); return f.createRestClientNoHttpProxy(baseUrl); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java index d1c36e62..d500ba3e 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java @@ -34,6 +34,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.io.TempDir; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableWebClientConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig; @@ -176,7 +177,7 @@ class ConfigurationControllerTest { .httpProxyConfig(config.httpProxyConfig()) // .build(); - AsyncRestClientFactory f = new AsyncRestClientFactory(config); + AsyncRestClientFactory f = new AsyncRestClientFactory(config, new SecurityContext("")); return f.createRestClientNoHttpProxy("https://localhost:" + port); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RappSimulatorController.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RappSimulatorController.java index 1fa51246..d9c724fc 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RappSimulatorController.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RappSimulatorController.java @@ -31,6 +31,10 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.Vector; import lombok.Getter; @@ -44,6 +48,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; @RestController("RappCallbacksController") @@ -61,8 +66,12 @@ public class RappSimulatorController { @Getter private Vector receivedInfo = new Vector<>(); + public List> receivedHeaders = + Collections.synchronizedList(new ArrayList>()); + public void clear() { receivedInfo.clear(); + receivedHeaders.clear(); } } @@ -79,10 +88,18 @@ public class RappSimulatorController { ) public ResponseEntity serviceCallback( // - @RequestBody ServiceCallbackInfo body) { + @RequestBody ServiceCallbackInfo body, @RequestHeader Map headers) { + logHeaders(headers); logger.info("R-App callback body: {}", gson.toJson(body)); + this.testResults.receivedHeaders.add(headers); this.testResults.receivedInfo.add(body); return new ResponseEntity<>(HttpStatus.OK); } + private void logHeaders(Map headers) { + logger.debug("Header begin"); + headers.forEach((key, value) -> logger.debug(" key: {}, value: {}", key, value)); + logger.debug("Header end"); + } + } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumerTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumerTest.java index 3b810ad6..08491207 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumerTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumerTest.java @@ -43,6 +43,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.dmaap.DmaapRequestMessage.Operation; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; @@ -84,7 +85,7 @@ class DmaapMessageConsumerTest { @Test void successfulCase_dmaapNotConfigured_thenSleepAndRetryUntilConfig() throws Exception { - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); + messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock, new SecurityContext(""))); setTaskNumberOfLoops(3); disableTaskDelay(); @@ -104,7 +105,7 @@ class DmaapMessageConsumerTest { @Test void returnErrorFromDmapp_thenSleepAndRetry() throws Exception { - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); + messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock, new SecurityContext(""))); setTaskNumberOfLoops(2); disableTaskDelay(); @@ -129,7 +130,7 @@ class DmaapMessageConsumerTest { @Test void unParsableMessage_thenSendResponseAndContinue() throws Exception { - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); + messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock, new SecurityContext(""))); setTaskNumberOfLoops(2); setUpMrConfig(); @@ -157,7 +158,7 @@ class DmaapMessageConsumerTest { @Test void testMessageParsing() throws ServiceException { - messageConsumerUnderTest = new DmaapMessageConsumer(applicationConfigMock); + messageConsumerUnderTest = new DmaapMessageConsumer(applicationConfigMock, new SecurityContext("")); String json = gson.toJson(dmaapRequestMessage()); { String jsonArrayOfObject = jsonArray(json); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java index 1b1dad5c..f09bd05d 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java @@ -49,6 +49,7 @@ import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig.RicConfigUpdate.Type; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser; @@ -89,9 +90,10 @@ class RefreshConfigTaskTest { private RefreshConfigTask createTestObject(boolean configFileExists, Rics rics, Policies policies, boolean stubConfigFileExists) { - - RefreshConfigTask obj = spy(new RefreshConfigTask(configurationFileMock, appConfig, rics, policies, - new Services(appConfig), new PolicyTypes(appConfig), new A1ClientFactory(appConfig))); + SecurityContext secContext = new SecurityContext(""); + RefreshConfigTask obj = + spy(new RefreshConfigTask(configurationFileMock, appConfig, rics, policies, new Services(appConfig), + new PolicyTypes(appConfig), new A1ClientFactory(appConfig, secContext), secContext)); if (stubConfigFileExists) { when(configurationFileMock.readFile()).thenReturn(Optional.empty()); doReturn(123L).when(configurationFileMock).getLastModified(); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java index f6c93b95..b76131df 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java @@ -43,6 +43,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock; @@ -335,6 +336,6 @@ class RicSupervisionTest { private RicSupervision createRicSupervision() { ApplicationConfig config = new ApplicationConfig(); - return new RicSupervision(rics, policies, a1ClientFactory, types, null, config); + return new RicSupervision(rics, policies, a1ClientFactory, types, null, config, new SecurityContext("")); } } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java index 9dddcedb..a5795ac9 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java @@ -44,6 +44,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; @@ -121,7 +122,8 @@ class RicSynchronizationTaskTest { private RicSynchronizationTask createTask() { ApplicationConfig config = new ApplicationConfig(); - AsyncRestClientFactory restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig()); + AsyncRestClientFactory restClientFactory = + new AsyncRestClientFactory(config.getWebClientConfig(), new SecurityContext("")); return new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services, restClientFactory, rics); }; diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1ClientFactory.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1ClientFactory.java index 05df70ac..22f534cf 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1ClientFactory.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1ClientFactory.java @@ -29,6 +29,7 @@ import java.util.Map; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyTypes; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric; @@ -44,7 +45,7 @@ public class MockA1ClientFactory extends A1ClientFactory { private final ApplicationConfig appConfig; public MockA1ClientFactory(ApplicationConfig config, PolicyTypes policyTypes) { - super(config); + super(config, new SecurityContext("")); this.policyTypes = policyTypes; this.appConfig = config; } @@ -70,7 +71,7 @@ public class MockA1ClientFactory extends A1ClientFactory { /** * Simulate network latency. The REST responses will be generated by separate * threads - * + * * @param delay the delay between the request and the response */ public void setResponseDelay(Duration delay) { -- cgit 1.2.3-korg