Make StartupService use asynchronous client 82/2082/1
authorelinuxhenrik <henrik.b.andersson@est.tech>
Thu, 19 Dec 2019 14:50:38 +0000 (15:50 +0100)
committerelinuxhenrik <henrik.b.andersson@est.tech>
Thu, 19 Dec 2019 14:50:45 +0000 (15:50 +0100)
Change-Id: Ic54cc3183eb63a467d6f2d33309b3f758adb3f17
Issue-ID: NONRTRIC-81
Signed-off-by: elinuxhenrik <henrik.b.andersson@est.tech>
policy-agent/pom.xml
policy-agent/src/main/java/org/oransc/policyagent/Application.java
policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java
policy-agent/src/main/java/org/oransc/policyagent/clients/RicClient.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java
policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java
policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java

index 0969f14..551a95b 100644 (file)
@@ -52,8 +52,8 @@
         <sdk.version>1.1.6</sdk.version>
         <swagger.version>2.0.0</swagger.version>
         <json.version>20180130</json.version>
+        <awaitility.version>4.0.1</awaitility.version>
         <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
-        <junit-platform-surefire-provider.version>1.3.2</junit-platform-surefire-provider.version>
         <formatter-maven-plugin.version>2.8.1</formatter-maven-plugin.version>
         <spotless-maven-plugin.version>1.18.0</spotless-maven-plugin.version>
         <dockerfile-maven-plugin.version>1.4.13</dockerfile-maven-plugin.version>
             <version>${springfox.version}</version>
         </dependency>
         <!-- TEST -->
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <version>${awaitility.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>io.projectreactor</groupId>
             <artifactId>reactor-test</artifactId>
                 <configuration>
                     <skipTests>false</skipTests>
                 </configuration>
-                <dependencies>
-                    <dependency>
-                         <groupId>org.junit.platform</groupId>
-                         <artifactId>junit-platform-surefire-provider</artifactId>
-                         <version> ${junit-platform-surefire-provider.version}</version>
-                     </dependency>
-                 </dependencies>
+            </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
index 4f7a9dd..5a16bc2 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  * ========================LICENSE_END===================================
  */
+
 package org.oransc.policyagent.clients;
 
 import java.lang.invoke.MethodHandles;
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/RicClient.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/RicClient.java
deleted file mode 100644 (file)
index 709c023..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * 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.oransc.policyagent.clients;
-
-import java.util.Vector;
-
-import org.oransc.policyagent.repository.PolicyType;
-import org.springframework.stereotype.Service;
-
-@Service
-public class RicClient {
-
-    public void deleteAllPolicies(String url) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public Vector<PolicyType> getPolicyTypes(String url) {
-        return new Vector<>();
-    }
-
-}
index 68b07aa..18a2dc7 100644 (file)
@@ -144,9 +144,9 @@ public class Ric {
     /**
      * Checks if a type is supported by this Ric.
      *
-     * @param type the type to check if it is supported.
+     * @param typeName the name of the type to check if it is supported.
      *
-     * @return true if the given type issupported by this Ric, false otherwise.
+     * @return true if the given type is supported by this Ric, false otherwise.
      */
     public boolean isSupportingType(String typeName) {
         return supportedPolicyTypes.containsKey(typeName);
@@ -163,14 +163,6 @@ public class Ric {
         /**
          * The Ric is working fine.
          */
-        ACTIVE,
-        /**
-         * Something is wrong with the Ric.
-         */
-        FAULTY,
-        /**
-         * The node is unreachable at the moment.
-         */
-        UNREACHABLE
+        ACTIVE
     }
 }
index f2de7cf..3ab6152 100644 (file)
@@ -84,7 +84,7 @@ public class ServiceSupervision {
     private Mono<Policy> deletePolicyInRic(Policy policy) {
         return a1Client.deletePolicy(policy.ric().getConfig().baseUrl(), policy.id()) //
             .onErrorResume(exception -> handleDeleteFromRicFailure(policy, exception)) //
-            .flatMap((nothing) -> Mono.just(policy));
+            .map((nothing) -> policy);
     }
 
     private Mono<Void> handleDeleteFromRicFailure(Policy policy, Throwable e) {
index 1fa0aa8..6612e39 100644 (file)
 
 package org.oransc.policyagent.tasks;
 
-import java.util.Vector;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 
-import org.oransc.policyagent.clients.RicClient;
+import org.oransc.policyagent.clients.A1Client;
 import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.RicConfig;
+import org.oransc.policyagent.repository.ImmutablePolicyType;
 import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
@@ -35,12 +36,19 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
 /**
  * Loads information about RealTime-RICs at startup.
  */
 @Service("startupService")
 public class StartupService {
 
+    private static Gson gson = new GsonBuilder() //
+        .serializeNulls() //
+        .create(); //
+
     private static final Logger logger = LoggerFactory.getLogger(StartupService.class);
 
     @Autowired
@@ -53,13 +61,13 @@ public class StartupService {
     PolicyTypes policyTypes;
 
     @Autowired
-    private RicClient ricClient;
+    private A1Client a1Client;
 
-    StartupService(ApplicationConfig appConfig, Rics rics, PolicyTypes policyTypes, RicClient ricClient) {
+    StartupService(ApplicationConfig appConfig, Rics rics, PolicyTypes policyTypes, A1Client a1Client) {
         this.applicationConfig = appConfig;
         this.rics = rics;
         this.policyTypes = policyTypes;
-        this.ricClient = ricClient;
+        this.a1Client = a1Client;
     }
 
     /**
@@ -67,22 +75,55 @@ public class StartupService {
      */
     public void startup() {
         applicationConfig.initialize();
-        Vector<RicConfig> ricConfigs = applicationConfig.getRicConfigs();
-        for (RicConfig ricConfig : ricConfigs) {
-            Ric ric = new Ric(ricConfig);
-            String baseUrl = ricConfig.baseUrl();
-            ricClient.deleteAllPolicies(baseUrl);
-            Vector<PolicyType> types = ricClient.getPolicyTypes(baseUrl);
-            for (PolicyType policyType : types) {
-                if (!policyTypes.contains(policyType)) {
-                    policyTypes.put(policyType);
-                }
-            }
-            ric.addSupportedPolicyTypes(types);
-            ric.setState(RicState.ACTIVE);
-            rics.put(ric);
+        Flux.fromIterable(applicationConfig.getRicConfigs()) //
+            .map(ricConfig -> new Ric(ricConfig)) //
+            .doOnNext(ric -> logger.debug("Handling ric: {}", ric.getConfig().name())).flatMap(this::handlePolicyTypes)
+            .flatMap(this::setRicToActive) //
+            .flatMap(this::addRicToRepo) //
+            .subscribe();
+    }
+
+    private Mono<Ric> handlePolicyTypes(Ric ric) {
+        a1Client.getAllPolicyTypes(ric.getConfig().baseUrl()) //
+            .map(policyTypeString -> gson.fromJson(policyTypeString, ImmutablePolicyType.class)) //
+            .doOnNext(type -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().name(), type.name()))
+            .flatMap(this::addTypeToRepo) //
+            .flatMap(type -> addTypeToRic(ric, type)) //
+            .flatMap(type -> deletePoliciesForType(ric, type)) //
+            .subscribe();
+        return Mono.just(ric);
+    }
+
+    private Mono<PolicyType> addTypeToRepo(PolicyType policyType) {
+        if (!policyTypes.contains(policyType)) {
+            policyTypes.put(policyType);
         }
+        return Mono.just(policyType);
+    }
 
+    private Mono<PolicyType> addTypeToRic(Ric ric, PolicyType policyType) {
+        ric.addSupportedPolicyType(policyType);
+        return Mono.just(policyType);
     }
 
+    private Mono<Void> deletePoliciesForType(Ric ric, PolicyType policyType) {
+        a1Client.getPoliciesForType(ric.getConfig().baseUrl(), policyType.name()) //
+            .doOnNext(policyId -> logger.debug("deleting policy: {}, for ric: {}", policyId, ric.getConfig().name())) //
+            .flatMap(policyId -> a1Client.deletePolicy(ric.getConfig().baseUrl(), policyId)) //
+            .subscribe();
+
+        return Mono.empty();
+    }
+
+    private Mono<Ric> setRicToActive(Ric ric) {
+        ric.setState(RicState.ACTIVE);
+
+        return Mono.just(ric);
+    }
+
+    private Mono<Void> addRicToRepo(Ric ric) {
+        rics.put(ric);
+
+        return Mono.empty();
+    }
 }
index 084ab58..103777a 100644 (file)
@@ -26,9 +26,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
+
 import java.net.URL;
 import java.util.List;
 import java.util.Vector;
+
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.oransc.policyagent.configuration.ApplicationConfig;
@@ -53,6 +55,7 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 import org.springframework.boot.test.context.TestConfiguration;
 import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -62,6 +65,8 @@ import org.springframework.web.client.RestTemplate;
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
 public class ApplicationTest {
+    @Autowired
+    ApplicationContext context;
 
     @Autowired
     private Rics rics;
@@ -94,6 +99,16 @@ public class ApplicationTest {
         public ApplicationConfig getApplicationConfig() {
             return new MockApplicationConfig();
         }
+
+        @Bean
+        public Rics getRics() {
+            Rics rics = new Rics();
+            rics.put(new Ric(ImmutableRicConfig.builder().name("kista_1").baseUrl("kista_url")
+                .managedElementIds(new Vector<>()).build()));
+            rics.put(new Ric(ImmutableRicConfig.builder().name("ric1").baseUrl("ric_url")
+                .managedElementIds(new Vector<>()).build()));
+            return rics;
+        }
     }
 
     @LocalServerPort
index ff1db6a..9cfb616 100644 (file)
@@ -30,12 +30,14 @@ import static org.mockito.Mockito.verify;
 
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.read.ListAppender;
+
 import com.google.common.base.Charsets;
 import com.google.common.io.Resources;
 import com.google.gson.JsonIOException;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.google.gson.JsonSyntaxException;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -45,6 +47,7 @@ import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Properties;
 import java.util.Vector;
+
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -57,6 +60,7 @@ import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperti
 import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties;
 import org.oransc.policyagent.exceptions.ServiceException;
 import org.oransc.policyagent.utils.LoggingUtils;
+
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
index ec277c5..f75d820 100644 (file)
 
 package org.oransc.policyagent.tasks;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.oransc.policyagent.repository.Ric.RicState.ACTIVE;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
 import java.util.Vector;
 
 import org.junit.jupiter.api.Test;
@@ -37,7 +42,7 @@ import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.clients.RicClient;
+import org.oransc.policyagent.clients.A1Client;
 import org.oransc.policyagent.configuration.ApplicationConfig;
 import org.oransc.policyagent.configuration.ImmutableRicConfig;
 import org.oransc.policyagent.configuration.RicConfig;
@@ -48,6 +53,9 @@ import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
 import org.oransc.policyagent.repository.Rics;
 
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
 @ExtendWith(MockitoExtension.class)
 @RunWith(MockitoJUnitRunner.class)
 public class StartupServiceTest {
@@ -61,12 +69,18 @@ public class StartupServiceTest {
 
     private static final String POLICY_TYPE_1_NAME = "type1";
     private static final String POLICY_TYPE_2_NAME = "type2";
+    private static final String POLICY_ID_1 = "policy1";
+    private static final String POLICY_ID_2 = "policy2";
 
     @Mock
     ApplicationConfig appConfigMock;
 
     @Mock
-    RicClient ricClientMock;
+    A1Client a1ClientMock;
+
+    private static Gson gson = new GsonBuilder() //
+        .serializeNulls() //
+        .create(); //
 
     @Test
     public void startup_allOk() throws ServiceException {
@@ -75,31 +89,35 @@ public class StartupServiceTest {
         ricConfigs.add(getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C));
         when(appConfigMock.getRicConfigs()).thenReturn(ricConfigs);
 
-        Vector<PolicyType> firstTypes = new Vector<>();
         PolicyType type1 = ImmutablePolicyType.builder().name(POLICY_TYPE_1_NAME).jsonSchema("{}").build();
-        firstTypes.add(type1);
-        Vector<PolicyType> secondTypes = new Vector<>();
-        secondTypes.add(type1);
+        Flux<String> fluxType1 = Flux.just(gson.toJson(type1));
         PolicyType type2 = ImmutablePolicyType.builder().name(POLICY_TYPE_2_NAME).jsonSchema("{}").build();
-        secondTypes.add(type2);
-        when(ricClientMock.getPolicyTypes(anyString())).thenReturn(firstTypes, secondTypes);
+        Flux<String> fluxType2 = Flux.just(gson.toJson(type2));
+        when(a1ClientMock.getAllPolicyTypes(anyString())).thenReturn(fluxType1)
+            .thenReturn(fluxType1.concatWith(fluxType2));
+        Flux<String> policies = Flux.just(new String[] {POLICY_ID_1, POLICY_ID_2});
+        when(a1ClientMock.getPoliciesForType(anyString(), anyString())).thenReturn(policies);
+        when(a1ClientMock.deletePolicy(anyString(), anyString())).thenReturn(Mono.empty());
 
         Rics rics = new Rics();
         PolicyTypes policyTypes = new PolicyTypes();
-        StartupService serviceUnderTest = new StartupService(appConfigMock, rics, policyTypes, ricClientMock);
+        StartupService serviceUnderTest = new StartupService(appConfigMock, rics, policyTypes, a1ClientMock);
 
         serviceUnderTest.startup();
 
-        verify(ricClientMock).deleteAllPolicies(FIRST_RIC_URL);
-        verify(ricClientMock).getPolicyTypes(FIRST_RIC_URL);
-        verify(ricClientMock).deleteAllPolicies(SECOND_RIC_URL);
-        verify(ricClientMock).getPolicyTypes(SECOND_RIC_URL);
-        verifyNoMoreInteractions(ricClientMock);
+        await().untilAsserted(() -> assertThat(policyTypes.size()).isEqualTo(2));
+
+        verify(a1ClientMock).getAllPolicyTypes(FIRST_RIC_URL);
+        verify(a1ClientMock).deletePolicy(FIRST_RIC_URL, POLICY_ID_1);
+        verify(a1ClientMock).deletePolicy(FIRST_RIC_URL, POLICY_ID_2);
+
+        verify(a1ClientMock).getAllPolicyTypes(SECOND_RIC_URL);
+        verify(a1ClientMock, times(2)).deletePolicy(SECOND_RIC_URL, POLICY_ID_1);
+        verify(a1ClientMock, times(2)).deletePolicy(SECOND_RIC_URL, POLICY_ID_2);
 
-        assertEquals(2, policyTypes.size(), "Not correct number of policy types added.");
         assertEquals(type1, policyTypes.getType(POLICY_TYPE_1_NAME), "Not correct type added.");
         assertEquals(type2, policyTypes.getType(POLICY_TYPE_2_NAME), "Not correct type added.");
-        assertEquals(2, rics.size(), "Correct nymber of Rics not added to Rics");
+        assertEquals(2, rics.size(), "Correct number of Rics not added to Rics");
 
         Ric firstRic = rics.getRic(FIRST_RIC_NAME);
         assertNotNull(firstRic, "Ric \"" + FIRST_RIC_NAME + "\" not added to repositpry");