Update springboot version of the Policy Management Service (version 2.5) 15/123215/2
authorPatrikBuhr <patrik.buhr@est.tech>
Mon, 9 Aug 2021 08:20:55 +0000 (10:20 +0200)
committerPatrikBuhr <patrik.buhr@est.tech>
Wed, 18 Aug 2021 08:01:22 +0000 (10:01 +0200)
This required some changes due to not backwards compatible changes.
 - The API to springboot WebClient is changed, which is wrapped in class AsyncRestClient.
 - The validation of trusted certs is made more strict. The Owner field of the peer cert must contain the name ofthe using host.
   The uniitest tests this, so the cert in config is updated (Owner is "localhost").

Change-Id: Ia954b0ee5942884cd4b9fd82769bc8089dc35c53
Issue-ID: CCSDK-3421
Signed-off-by: PatrikBuhr <patrik.buhr@est.tech>
13 files changed:
a1-policy-management/pom.xml
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1Client.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion1.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion2.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/Consts.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v1/ApplicationTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java
a1-policy-management/src/test/resources/keystore.jks [new file with mode: 0644]
a1-policy-management/src/test/resources/truststore.jks [new file with mode: 0644]

index 1907c42..bbc24af 100644 (file)
   ~ ============LICENSE_END=======================================================
   ~
 -->
-
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onap.ccsdk.parent</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
+        <artifactId>spring-boot-25-starter-parent</artifactId>
         <version>2.2.0-SNAPSHOT</version>
-        <relativePath/>
+        <relativePath />
     </parent>
     <groupId>org.onap.ccsdk.oran</groupId>
     <artifactId>a1-policy-management-service</artifactId>
index 2b8c4fa..ad2e221 100644 (file)
@@ -42,9 +42,7 @@ import org.springframework.web.reactive.function.client.WebClientResponseExcepti
 
 import reactor.core.publisher.Mono;
 import reactor.netty.http.client.HttpClient;
-import reactor.netty.resources.ConnectionProvider;
-import reactor.netty.tcp.ProxyProvider.Proxy;
-import reactor.netty.tcp.TcpClient;
+import reactor.netty.transport.ProxyProvider;
 
 /**
  * Generic reactive REST client.
@@ -200,32 +198,32 @@ public class AsyncRestClient {
                 && !httpProxyConfig.httpProxyHost().isEmpty();
     }
 
-    private TcpClient createTcpClient() {
-        TcpClient client = TcpClient.create(ConnectionProvider.newConnection()) //
+    private HttpClient buildHttpClient() {
+        HttpClient httpClient = HttpClient.create() //
                 .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
                 .doOnConnected(connection -> {
                     connection.addHandlerLast(new ReadTimeoutHandler(30));
                     connection.addHandlerLast(new WriteTimeoutHandler(30));
                 });
+
         if (this.sslContext != null) {
-            client = client.secure(c -> c.sslContext(sslContext));
+            httpClient = httpClient.secure(ssl -> ssl.sslContext(sslContext));
         }
+
         if (isHttpProxyConfigured()) {
-            client = client.proxy(proxy -> proxy.type(Proxy.HTTP).host(httpProxyConfig.httpProxyHost())
-                    .port(httpProxyConfig.httpProxyPort()));
+            httpClient = httpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP)
+                    .host(httpProxyConfig.httpProxyHost()).port(httpProxyConfig.httpProxyPort()));
         }
-        return client;
+        return httpClient;
     }
 
-    private WebClient createWebClient(String baseUrl, TcpClient tcpClient) {
-        HttpClient httpClient = HttpClient.from(tcpClient);
-
-        ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
+    private WebClient buildWebClient(String baseUrl) {
+        final HttpClient httpClient = buildHttpClient();
         ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() //
                 .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) //
                 .build();
         return WebClient.builder() //
-                .clientConnector(connector) //
+                .clientConnector(new ReactorClientHttpConnector(httpClient)) //
                 .baseUrl(baseUrl) //
                 .exchangeStrategies(exchangeStrategies) //
                 .build();
@@ -233,15 +231,9 @@ public class AsyncRestClient {
 
     private Mono<WebClient> getWebClient() {
         if (this.webClient == null) {
-            try {
-                TcpClient tcpClient = createTcpClient();
-                this.webClient = createWebClient(this.baseUrl, tcpClient);
-            } catch (Exception e) {
-                logger.error("Could not create WebClient {}", e.getMessage());
-                return Mono.error(e);
-            }
+            this.webClient = buildWebClient(baseUrl);
         }
-        return Mono.just(this.webClient);
+        return Mono.just(buildWebClient(baseUrl));
     }
 
 }
index db3834a..cde6647 100644 (file)
@@ -72,7 +72,7 @@ public class AsyncRestClientFactory {
         return createRestClient(baseUrl, false);
     }
 
-    public AsyncRestClient createRestClient(String baseUrl) {
+    public AsyncRestClient createRestClientUseHttpProxy(String baseUrl) {
         return createRestClient(baseUrl, true);
     }
 
@@ -190,5 +190,4 @@ public class AsyncRestClientFactory {
 
         }
     }
-
 }
index 7ded8ac..78a418a 100644 (file)
@@ -120,7 +120,7 @@ public class OscA1Client implements A1Client {
     private final UriBuilder uri;
 
     public OscA1Client(RicConfig ricConfig, AsyncRestClientFactory restClientFactory) {
-        this(ricConfig, restClientFactory.createRestClient(""));
+        this(ricConfig, restClientFactory.createRestClientUseHttpProxy(""));
     }
 
     public OscA1Client(RicConfig ricConfig, AsyncRestClient restClient) {
index 130f550..b158ad2 100644 (file)
@@ -97,7 +97,7 @@ public class StdA1ClientVersion1 implements A1Client {
     private final UriBuilder uri;
 
     public StdA1ClientVersion1(RicConfig ricConfig, AsyncRestClientFactory restClientFactory) {
-        this(restClientFactory.createRestClient(""), ricConfig);
+        this(restClientFactory.createRestClientUseHttpProxy(""), ricConfig);
     }
 
     public StdA1ClientVersion1(AsyncRestClient restClient, RicConfig ricConfig) {
index d79b2e7..d0f4da2 100644 (file)
@@ -124,7 +124,7 @@ public class StdA1ClientVersion2 implements A1Client {
     private final OranV2UriBuilder uriBuiler;
 
     public StdA1ClientVersion2(RicConfig ricConfig, AsyncRestClientFactory restClientFactory) {
-        this(ricConfig, restClientFactory.createRestClient(""));
+        this(ricConfig, restClientFactory.createRestClientUseHttpProxy(""));
     }
 
     public StdA1ClientVersion2(RicConfig ricConfig, AsyncRestClient restClient) {
index c3eff84..3e6bda7 100644 (file)
@@ -28,7 +28,7 @@ public class Consts {
     public static final String TRANSIENT_PARAM = "transient";
     public static final String MANAGED_ELEMENT_ID_PARAM = "managed_element_id";
 
-    public static final String V2_API_ROOT = "a1-policy/v2";
+    public static final String V2_API_ROOT = "/a1-policy/v2";
 
     public static final String V2_API_SERVICE_CALLBACKS_NAME = "Callbacks";
     public static final String V2_API_SERVICE_CALLBACKS_DESCRIPTION = "";
index bc22c14..240dd1d 100644 (file)
@@ -193,8 +193,7 @@ class ApplicationTest {
         this.addPolicyType("", "ric2");
         url = "/rics?policyType=";
 
-        // This tests also validation of trusted certs restClient(true)
-        rsp = restClient(true).get(url).block();
+        rsp = restClient().get(url).block();
         assertThat(rsp).contains("ric2") //
                 .doesNotContain("ric1") //
                 .contains("AVAILABLE");
index ab9b726..e31d0b9 100644 (file)
@@ -97,8 +97,8 @@ import reactor.util.annotation.Nullable;
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
 @TestPropertySource(properties = { //
-        "server.ssl.key-store=./config/keystore.jks", //
-        "app.webclient.trust-store=./config/truststore.jks", //
+        "server.ssl.key-store=./src/test/resources/keystore.jks", //
+        "app.webclient.trust-store=./src/test/resources/truststore.jks", //
         "app.vardata-directory=./target/testdata", //
         "app.filepath=" //
 })
@@ -308,6 +308,13 @@ class ApplicationTest {
         assertThat(receivedCallbacks.getReceivedInfo().size()).isEqualTo(1);
     }
 
+    @Test
+    void testTrustValidation() {
+        addRic("ric1");
+        String rsp = restClient(true).get("/rics").block(); // restClient(true) enables trust validation
+        assertThat(rsp).contains("ric1");
+    }
+
     @Test
     void testGetRics() throws Exception {
         addRic("ric1");
@@ -320,9 +327,7 @@ class ApplicationTest {
         addRic("ric2");
         this.addPolicyType("", "ric2");
         url = "/rics?policytype_id=";
-
-        // This tests also validation of trusted certs restClient(true)
-        rsp = restClient(true).get(url).block();
+        rsp = restClient().get(url).block();
         assertThat(rsp).contains("ric2") //
                 .doesNotContain("ric1") //
                 .contains("AVAILABLE");
@@ -891,8 +896,7 @@ class ApplicationTest {
     }
 
     private AsyncRestClient restClient(boolean useTrustValidation) {
-        String baseUrl = "https://localhost:" + port + Consts.V2_API_ROOT;
-        return restClient(baseUrl, useTrustValidation);
+        return restClient(baseUrl() + Consts.V2_API_ROOT, useTrustValidation);
     }
 
     private AsyncRestClient restClient() {
index 030b831..adb29a7 100644 (file)
@@ -162,14 +162,14 @@ class ConfigurationControllerTest {
                 .keyStorePassword(config.keyStorePassword()) //
                 .keyStore(config.keyStore()) //
                 .keyPassword(config.keyPassword()) //
-                .isTrustStoreUsed(true) //
+                .isTrustStoreUsed(false) //
                 .trustStore(config.trustStore()) //
                 .trustStorePassword(config.trustStorePassword()) //
                 .httpProxyConfig(config.httpProxyConfig()) //
                 .build();
 
         AsyncRestClientFactory f = new AsyncRestClientFactory(config);
-        return f.createRestClient("https://localhost:" + port);
+        return f.createRestClientNoHttpProxy("https://localhost:" + port);
 
     }
 }
index 9bd5c50..fae0547 100644 (file)
@@ -21,6 +21,7 @@
 package org.onap.ccsdk.oran.a1policymanagementservice.tasks;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -67,6 +68,7 @@ class RicSynchronizationTaskTest {
             .build();
 
     private static final String RIC_1_NAME = "ric1";
+
     private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() //
             .ricId(RIC_1_NAME) //
             .baseUrl("baseUrl1") //
@@ -160,6 +162,7 @@ class RicSynchronizationTaskTest {
         RicSynchronizationTask synchronizerUnderTest = spy(createTask());
 
         synchronizerUnderTest.run(RIC_1);
+        await().untilAsserted(() -> RicState.AVAILABLE.equals(RIC_1.getState()));
 
         verify(a1ClientMock, times(1)).getPolicyTypeIdentities();
         verifyNoMoreInteractions(a1ClientMock);
@@ -184,6 +187,7 @@ class RicSynchronizationTaskTest {
         RicSynchronizationTask synchronizerUnderTest = createTask();
 
         synchronizerUnderTest.run(RIC_1);
+        await().untilAsserted(() -> RicState.AVAILABLE.equals(RIC_1.getState()));
 
         verify(a1ClientMock).getPolicyTypeIdentities();
         verifyNoMoreInteractions(a1ClientMock);
@@ -213,7 +217,7 @@ class RicSynchronizationTaskTest {
         RicSynchronizationTask synchronizerUnderTest = createTask();
 
         synchronizerUnderTest.run(RIC_1);
-
+        await().untilAsserted(() -> RicState.AVAILABLE.equals(RIC_1.getState()));
         verify(a1ClientMock).deleteAllPolicies();
         verify(a1ClientMock).putPolicy(POLICY_1);
         verifyNoMoreInteractions(a1ClientMock);
@@ -240,6 +244,7 @@ class RicSynchronizationTaskTest {
         RicSynchronizationTask synchronizerUnderTest = createTask();
 
         synchronizerUnderTest.run(RIC_1);
+        await().untilAsserted(() -> RicState.AVAILABLE.equals(RIC_1.getState()));
 
         verify(a1ClientMock, times(2)).deleteAllPolicies();
         verifyNoMoreInteractions(a1ClientMock);
@@ -264,6 +269,7 @@ class RicSynchronizationTaskTest {
         RicSynchronizationTask synchronizerUnderTest = createTask();
 
         synchronizerUnderTest.run(RIC_1);
+        await().untilAsserted(() -> RicState.AVAILABLE.equals(RIC_1.getState()));
 
         verify(a1ClientMock, times(2)).deleteAllPolicies();
         verifyNoMoreInteractions(a1ClientMock);
diff --git a/a1-policy-management/src/test/resources/keystore.jks b/a1-policy-management/src/test/resources/keystore.jks
new file mode 100644 (file)
index 0000000..675785b
Binary files /dev/null and b/a1-policy-management/src/test/resources/keystore.jks differ
diff --git a/a1-policy-management/src/test/resources/truststore.jks b/a1-policy-management/src/test/resources/truststore.jks
new file mode 100644 (file)
index 0000000..e883cd6
Binary files /dev/null and b/a1-policy-management/src/test/resources/truststore.jks differ