2  * ========================LICENSE_START=================================
 
   4  * ======================================================================
 
   5  * Copyright (C) 2020 Nordix Foundation. All rights reserved.
 
   6  * ======================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ========================LICENSE_END===================================
 
  21 package org.onap.ccsdk.oran.a1policymanagementservice.tasks;
 
  23 import static org.assertj.core.api.Assertions.assertThat;
 
  24 import static org.mockito.ArgumentMatchers.any;
 
  25 import static org.mockito.Mockito.doReturn;
 
  26 import static org.mockito.Mockito.spy;
 
  27 import static org.mockito.Mockito.times;
 
  28 import static org.mockito.Mockito.verify;
 
  29 import static org.mockito.Mockito.verifyNoInteractions;
 
  30 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
  31 import static org.mockito.Mockito.when;
 
  33 import java.time.Duration;
 
  34 import java.time.Instant;
 
  35 import java.util.Arrays;
 
  36 import java.util.Collections;
 
  38 import org.junit.jupiter.api.BeforeEach;
 
  39 import org.junit.jupiter.api.Test;
 
  40 import org.junit.jupiter.api.extension.ExtendWith;
 
  41 import org.mockito.Mock;
 
  42 import org.mockito.junit.jupiter.MockitoExtension;
 
  43 import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client;
 
  44 import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory;
 
  45 import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory;
 
  46 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
 
  47 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig;
 
  48 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies;
 
  49 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy;
 
  50 import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyType;
 
  51 import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyTypes;
 
  52 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric;
 
  53 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric.RicState;
 
  54 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics;
 
  55 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Service;
 
  56 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services;
 
  58 import reactor.core.publisher.Flux;
 
  59 import reactor.core.publisher.Mono;
 
  61 @ExtendWith(MockitoExtension.class)
 
  62 class RicSynchronizationTaskTest {
 
  63     private static final String POLICY_TYPE_1_NAME = "type1";
 
  64     private static final PolicyType POLICY_TYPE_1 = PolicyType.builder() //
 
  65             .id(POLICY_TYPE_1_NAME) //
 
  69     private static final String RIC_1_NAME = "ric1";
 
  70     private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() //
 
  72             .baseUrl("baseUrl1") //
 
  73             .managedElementIds(Collections.emptyList()) //
 
  74             .controllerName("controllerName") //
 
  77     private static Policy createPolicy(String policyId, boolean isTransient) {
 
  78         return Policy.builder() //
 
  81                 .ownerServiceId("service") //
 
  83                 .type(POLICY_TYPE_1) //
 
  84                 .lastModified(Instant.now()) //
 
  85                 .isTransient(isTransient) //
 
  86                 .statusNotificationUri("statusNotificationUri") //
 
  90     private static final Policy POLICY_1 = createPolicy("policyId1", false);
 
  92     private static final String SERVICE_1_NAME = "service1";
 
  93     private static final String SERVICE_1_CALLBACK_URL = "callbackUrl";
 
  94     private static final Service SERVICE_1 = new Service(SERVICE_1_NAME, Duration.ofSeconds(1), SERVICE_1_CALLBACK_URL);
 
  97     private A1Client a1ClientMock;
 
 100     private A1ClientFactory a1ClientFactoryMock;
 
 102     private PolicyTypes policyTypes;
 
 103     private Policies policies;
 
 104     private Services services;
 
 107     private final ApplicationConfig appConfig = new ApplicationConfig();
 
 111         policyTypes = new PolicyTypes(appConfig);
 
 112         policies = new Policies(appConfig);
 
 113         services = new Services(appConfig);
 
 115         RIC_1.setState(RicState.UNAVAILABLE);
 
 116         RIC_1.clearSupportedPolicyTypes();
 
 119     private RicSynchronizationTask createTask() {
 
 120         ApplicationConfig config = new ApplicationConfig();
 
 121         AsyncRestClientFactory restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig());
 
 122         return new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services, restClientFactory,
 
 127     void ricAlreadySynchronizing_thenNoSynchronization() {
 
 128         RIC_1.setState(RicState.SYNCHRONIZING);
 
 129         RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
 
 131         policyTypes.put(POLICY_TYPE_1);
 
 132         policies.put(POLICY_1);
 
 134         RicSynchronizationTask synchronizerUnderTest = createTask();
 
 136         synchronizerUnderTest.run(RIC_1);
 
 138         verifyNoInteractions(a1ClientMock);
 
 140         assertThat(policyTypes.size()).isEqualTo(1);
 
 141         assertThat(policies.size()).isEqualTo(1);
 
 142         assertThat(RIC_1.getState()).isEqualTo(RicState.SYNCHRONIZING);
 
 143         assertThat(RIC_1.getSupportedPolicyTypeNames()).hasSize(1);
 
 147     void ricIdlePolicyTypeInRepo_thenSynchronizationWithReuseOfTypeFromRepoAndCorrectServiceNotified() {
 
 149         RIC_1.setState(RicState.AVAILABLE);
 
 151         policyTypes.put(POLICY_TYPE_1);
 
 153         services.put(SERVICE_1);
 
 154         Service serviceWithoutCallbackUrlShouldNotBeNotified = new Service("service2", Duration.ofSeconds(1), "");
 
 155         services.put(serviceWithoutCallbackUrlShouldNotBeNotified);
 
 157         setUpCreationOfA1Client();
 
 158         simulateRicWithOnePolicyType();
 
 160         RicSynchronizationTask synchronizerUnderTest = spy(createTask());
 
 162         synchronizerUnderTest.run(RIC_1);
 
 164         verify(a1ClientMock, times(1)).getPolicyTypeIdentities();
 
 165         verifyNoMoreInteractions(a1ClientMock);
 
 167         verify(synchronizerUnderTest).run(RIC_1);
 
 169         assertThat(policyTypes.size()).isEqualTo(1);
 
 170         assertThat(policies.size()).isZero();
 
 171         assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
 
 175     void ricIdlePolicyTypeNotInRepo_thenSynchronizationWithTypeFromRic() throws Exception {
 
 176         RIC_1.setState(RicState.AVAILABLE);
 
 179         setUpCreationOfA1Client();
 
 180         simulateRicWithOnePolicyType();
 
 181         String typeSchema = "schema";
 
 182         when(a1ClientMock.getPolicyTypeSchema(POLICY_TYPE_1_NAME)).thenReturn(Mono.just(typeSchema));
 
 184         RicSynchronizationTask synchronizerUnderTest = createTask();
 
 186         synchronizerUnderTest.run(RIC_1);
 
 188         verify(a1ClientMock).getPolicyTypeIdentities();
 
 189         verifyNoMoreInteractions(a1ClientMock);
 
 191         assertThat(policyTypes.size()).isEqualTo(1);
 
 192         assertThat(policyTypes.getType(POLICY_TYPE_1_NAME).getSchema()).isEqualTo(typeSchema);
 
 193         assertThat(policies.size()).isZero();
 
 194         assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
 
 198     void ricIdleAndHavePolicies_thenSynchronizationWithRecreationOfPolicies() {
 
 199         RIC_1.setState(RicState.AVAILABLE);
 
 202         Policy transientPolicy = createPolicy("transientPolicyId", true);
 
 204         policies.put(transientPolicy);
 
 205         policies.put(POLICY_1);
 
 207         setUpCreationOfA1Client();
 
 208         simulateRicWithNoPolicyTypes();
 
 210         when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.just("OK"));
 
 211         when(a1ClientMock.putPolicy(any(Policy.class))).thenReturn(Mono.just("OK"));
 
 213         RicSynchronizationTask synchronizerUnderTest = createTask();
 
 215         synchronizerUnderTest.run(RIC_1);
 
 217         verify(a1ClientMock).deleteAllPolicies();
 
 218         verify(a1ClientMock).putPolicy(POLICY_1);
 
 219         verifyNoMoreInteractions(a1ClientMock);
 
 221         assertThat(policyTypes.size()).isZero();
 
 222         assertThat(policies.size()).isEqualTo(1); // The transient policy shall be deleted
 
 223         assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
 
 227     void ricIdleAndErrorDeletingPoliciesFirstTime_thenSynchronizationWithDeletionOfPolicies() {
 
 228         RIC_1.setState(RicState.AVAILABLE);
 
 231         policies.put(POLICY_1);
 
 233         setUpCreationOfA1Client();
 
 234         simulateRicWithNoPolicyTypes();
 
 236         when(a1ClientMock.deleteAllPolicies()) //
 
 237                 .thenReturn(Flux.error(new Exception("Exception"))) //
 
 238                 .thenReturn(Flux.just("OK"));
 
 240         RicSynchronizationTask synchronizerUnderTest = createTask();
 
 242         synchronizerUnderTest.run(RIC_1);
 
 244         verify(a1ClientMock, times(2)).deleteAllPolicies();
 
 245         verifyNoMoreInteractions(a1ClientMock);
 
 247         assertThat(policyTypes.size()).isZero();
 
 248         assertThat(policies.size()).isZero();
 
 249         assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
 
 253     void ricIdleAndErrorDeletingPoliciesAllTheTime_thenSynchronizationWithFailedRecovery() {
 
 254         RIC_1.setState(RicState.AVAILABLE);
 
 256         policies.put(POLICY_1);
 
 258         setUpCreationOfA1Client();
 
 259         simulateRicWithNoPolicyTypes();
 
 261         String originalErrorMessage = "Exception";
 
 262         when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.error(new Exception(originalErrorMessage)));
 
 264         RicSynchronizationTask synchronizerUnderTest = createTask();
 
 266         synchronizerUnderTest.run(RIC_1);
 
 268         verify(a1ClientMock, times(2)).deleteAllPolicies();
 
 269         verifyNoMoreInteractions(a1ClientMock);
 
 271         assertThat(policyTypes.size()).isZero();
 
 272         assertThat(policies.size()).isZero();
 
 273         assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE);
 
 276     private void setUpCreationOfA1Client() {
 
 277         when(a1ClientFactoryMock.createA1Client(any(Ric.class))).thenReturn(Mono.just(a1ClientMock));
 
 278         doReturn(Flux.empty()).when(a1ClientMock).deleteAllPolicies();
 
 281     private void simulateRicWithOnePolicyType() {
 
 282         when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just(Arrays.asList(POLICY_TYPE_1_NAME)));
 
 285     private void simulateRicWithNoPolicyTypes() {
 
 286         when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just(Collections.emptyList()));