2  * ============LICENSE_START=======================================================
 
   3  * Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved.
 
   4  * ================================================================================
 
   5  * Licensed under the Apache License, Version 2.0 (the "License");
 
   6  * you may not use this file except in compliance with the License.
 
   7  * You may obtain a copy of the License at
 
   9  *      http://www.apache.org/licenses/LICENSE-2.0
 
  11  * Unless required by applicable law or agreed to in writing, software
 
  12  * distributed under the License is distributed on an "AS IS" BASIS,
 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  * See the License for the specific language governing permissions and
 
  15  * limitations under the License.
 
  17  * SPDX-License-Identifier: Apache-2.0
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.policy.clamp.models.acm.persistence.provider;
 
  23 import static org.assertj.core.api.Assertions.assertThat;
 
  24 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
  25 import static org.junit.jupiter.api.Assertions.assertEquals;
 
  26 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
  27 import static org.junit.jupiter.api.Assertions.assertThrows;
 
  28 import static org.mockito.ArgumentMatchers.any;
 
  29 import static org.mockito.ArgumentMatchers.anyIterable;
 
  30 import static org.mockito.ArgumentMatchers.anyString;
 
  31 import static org.mockito.Mockito.mock;
 
  32 import static org.mockito.Mockito.verify;
 
  33 import static org.mockito.Mockito.when;
 
  35 import java.util.ArrayList;
 
  36 import java.util.List;
 
  37 import java.util.Optional;
 
  38 import java.util.UUID;
 
  39 import org.junit.jupiter.api.BeforeEach;
 
  40 import org.junit.jupiter.api.Test;
 
  41 import org.mockito.Mockito;
 
  42 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
 
  43 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  44 import org.onap.policy.clamp.models.acm.concepts.LockState;
 
  45 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition;
 
  46 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement;
 
  47 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionRollback;
 
  48 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository;
 
  49 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository;
 
  50 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRollbackRepository;
 
  51 import org.onap.policy.common.utils.coder.Coder;
 
  52 import org.onap.policy.common.utils.coder.StandardCoder;
 
  53 import org.onap.policy.common.utils.resources.ResourceUtils;
 
  54 import org.onap.policy.models.base.PfModelRuntimeException;
 
  55 import org.springframework.data.domain.PageImpl;
 
  56 import org.springframework.data.domain.PageRequest;
 
  57 import org.springframework.data.domain.Pageable;
 
  59 class AutomationCompositionProviderTest {
 
  61     private static final String AC_IS_NULL = "automationComposition is marked non-null but is null";
 
  62     private static final String ACELEMENT_ID_IS_NULL = "elementId is marked non-null but is null";
 
  64     private static final Coder CODER = new StandardCoder();
 
  65     private static final String AUTOMATION_COMPOSITION_JSON =
 
  66         "src/test/resources/providers/TestAutomationCompositions.json";
 
  68     private AutomationCompositions inputAutomationCompositions;
 
  69     private List<JpaAutomationComposition> inputAutomationCompositionsJpa;
 
  70     private final String originalJson = ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON);
 
  72     private AutomationCompositionProvider automationCompositionProvider;
 
  73     private AutomationCompositionRepository automationCompositionRepository;
 
  74     private AutomationCompositionElementRepository acElementRepository;
 
  75     private AutomationCompositionRollbackRepository acRollbackRepository;
 
  78     void beforeSetupDao() throws Exception {
 
  79         inputAutomationCompositions = CODER.decode(originalJson, AutomationCompositions.class);
 
  80         inputAutomationCompositionsJpa =
 
  81             ProviderUtils.getJpaAndValidateList(inputAutomationCompositions.getAutomationCompositionList(),
 
  82                 JpaAutomationComposition::new, "automation compositions");
 
  85         automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
  86         acElementRepository = mock(AutomationCompositionElementRepository.class);
 
  87         acRollbackRepository = mock(AutomationCompositionRollbackRepository.class);
 
  88         automationCompositionProvider =
 
  89             new AutomationCompositionProvider(automationCompositionRepository, acElementRepository,
 
  90                 acRollbackRepository);
 
  94     void testAutomationCompositionCreate() {
 
  95         when(automationCompositionRepository.save(any(JpaAutomationComposition.class)))
 
  96             .thenReturn(inputAutomationCompositionsJpa.get(0));
 
  97         var inputAc = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
  99         var createdAutomationComposition = automationCompositionProvider.createAutomationComposition(inputAc);
 
 100         inputAc.setInstanceId(createdAutomationComposition.getInstanceId());
 
 101         inputAc.setLastMsg(createdAutomationComposition.getLastMsg());
 
 102         assertEquals(inputAc, createdAutomationComposition);
 
 106     void testAutomationCompositionUpdate() {
 
 107         assertThatThrownBy(() -> automationCompositionProvider.updateAutomationComposition(null))
 
 108             .hasMessageMatching(AC_IS_NULL);
 
 110         when(automationCompositionRepository.save(inputAutomationCompositionsJpa.get(0)))
 
 111             .thenReturn(inputAutomationCompositionsJpa.get(0));
 
 113         var createdAutomationComposition = automationCompositionProvider
 
 114             .updateAutomationComposition(inputAutomationCompositions.getAutomationCompositionList().get(0));
 
 116         assertEquals(inputAutomationCompositions.getAutomationCompositionList().get(0), createdAutomationComposition);
 
 120     void testGetAutomationCompositionsWithNull() {
 
 121         assertThatThrownBy(() -> automationCompositionProvider
 
 122             .getAutomationCompositions(UUID.randomUUID(), null, null, null))
 
 123             .hasMessage("pageable is marked non-null but is null");
 
 125         assertThatThrownBy(() -> automationCompositionProvider
 
 126             .getAutomationCompositions(null, null, null, Pageable.unpaged()))
 
 127             .hasMessage("compositionId is marked non-null but is null");
 
 131     void testGetAutomationCompositions() {
 
 132         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 133         when(automationCompositionRepository
 
 134             .findAll(Mockito.any(), any(Pageable.class)))
 
 135             .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa));
 
 136         var acList = automationCompositionProvider.getAutomationCompositions(UUID.randomUUID(),
 
 137             automationComposition.getName(), automationComposition.getVersion(), Pageable.unpaged());
 
 138         assertThat(acList).hasSize(2);
 
 140         acList = automationCompositionProvider.getAutomationCompositions(automationComposition.getCompositionId(), null,
 
 141             null, Pageable.unpaged());
 
 142         assertThat(acList).hasSize(2);
 
 144         when(automationCompositionRepository
 
 145             .findAll(Mockito.any(), Mockito.any(Pageable.class)))
 
 146             .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa));
 
 147         acList = automationCompositionProvider.getAutomationCompositions(automationComposition.getCompositionId(), null,
 
 148             null, PageRequest.of(0, 10));
 
 149         assertThat(acList).hasSize(2);
 
 153     void testGetAutomationComposition() {
 
 154         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 156             () -> automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId()))
 
 157             .hasMessageMatching("AutomationComposition not found");
 
 159         when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString()))
 
 160             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 161         var ac = automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId());
 
 162         assertEquals(automationComposition, ac);
 
 166     void testFindAutomationComposition() {
 
 167         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 168         var acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId());
 
 169         assertThat(acOpt).isEmpty();
 
 171         acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
 
 172         assertThat(acOpt).isEmpty();
 
 174         when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString()))
 
 175             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 176         acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId());
 
 177         assertEquals(automationComposition, acOpt.get());
 
 179         when(automationCompositionRepository.findOne(Mockito.any()))
 
 180             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 181         acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
 
 182         assertEquals(automationComposition, acOpt.get());
 
 186     void testGetAcInstancesByCompositionId() {
 
 187         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 188         when(automationCompositionRepository.findByCompositionId(automationComposition.getCompositionId().toString()))
 
 189             .thenReturn(inputAutomationCompositionsJpa);
 
 191             automationCompositionProvider.getAcInstancesByCompositionId(automationComposition.getCompositionId());
 
 192         assertEquals(inputAutomationCompositions.getAutomationCompositionList(), acList);
 
 196     void testGetAcInstancesInTransition() {
 
 197         inputAutomationCompositions.getAutomationCompositionList().get(0).setDeployState(DeployState.DEPLOYING);
 
 198         inputAutomationCompositions.getAutomationCompositionList().get(1).setLockState(LockState.LOCKING);
 
 199         inputAutomationCompositionsJpa.get(0).setDeployState(DeployState.DEPLOYING);
 
 200         inputAutomationCompositionsJpa.get(1).setLockState(LockState.LOCKING);
 
 202         List<JpaAutomationComposition> res1 = new ArrayList<>();
 
 203         res1.add(inputAutomationCompositionsJpa.get(0));
 
 205         when(automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
 
 206             DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING)))
 
 208         when(automationCompositionRepository.findByLockStateIn(List.of(LockState.LOCKING, LockState.UNLOCKING)))
 
 209             .thenReturn(List.of(inputAutomationCompositionsJpa.get(1)));
 
 210         var acList = automationCompositionProvider.getAcInstancesInTransition();
 
 211         assertThat(acList).hasSize(2)
 
 212             .contains(inputAutomationCompositions.getAutomationCompositionList().get(0).getInstanceId())
 
 213             .contains(inputAutomationCompositions.getAutomationCompositionList().get(1).getInstanceId());
 
 217     void testDeleteAutomationComposition() {
 
 218         assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationComposition(UUID.randomUUID()))
 
 219             .hasMessageMatching(".*.failed, automation composition does not exist");
 
 221         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 222         when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString()))
 
 223             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 226             automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
 
 227         assertEquals(automationComposition, deletedAc);
 
 231     void testDeleteElementById() {
 
 232         assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationCompositionElement(null))
 
 233             .hasMessageMatching(ACELEMENT_ID_IS_NULL);
 
 234         var elementId = UUID.randomUUID();
 
 235         automationCompositionProvider.deleteAutomationCompositionElement(elementId);
 
 236         verify(acElementRepository).deleteById(elementId.toString());
 
 240     void testValidateElementIds() {
 
 241         var ac = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 243         var result = automationCompositionProvider.validateElementIds(ac);
 
 244         assertThat(result.isValid()).isTrue();
 
 246         var jpaElement = new JpaAutomationCompositionElement(ac.getElements().values().iterator().next());
 
 247         when(acElementRepository.findAllById(anyIterable()))
 
 248             .thenReturn(List.of(jpaElement));
 
 250         ac.setInstanceId(null);
 
 251         result = automationCompositionProvider.validateElementIds(ac);
 
 252         assertThat(result.isValid()).isFalse();
 
 254         ac.setInstanceId(UUID.randomUUID());
 
 255         jpaElement.setInstanceId(UUID.randomUUID().toString());
 
 256         result = automationCompositionProvider.validateElementIds(ac);
 
 257         assertThat(result.isValid()).isFalse();
 
 259         ac.setInstanceId(UUID.randomUUID());
 
 260         jpaElement.setInstanceId(ac.getInstanceId().toString());
 
 261         result = automationCompositionProvider.validateElementIds(ac);
 
 262         assertThat(result.isValid()).isTrue();
 
 266     void testCopyAcElements() {
 
 267         var ac = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 268         automationCompositionProvider.copyAcElementsBeforeUpdate(ac);
 
 270         verify(acRollbackRepository).save(any(JpaAutomationCompositionRollback.class));
 
 271         assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider // NOSONAR
 
 272             .getAutomationCompositionRollback(ac.getInstanceId().toString()));
 
 276     void testGetRollbackSuccess() {
 
 277         var ac = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 278         var rollback = new JpaAutomationCompositionRollback();
 
 279         rollback.setInstanceId(ac.getInstanceId().toString());
 
 280         rollback.setCompositionId(ac.getCompositionId().toString());
 
 282         when(acRollbackRepository.findById(anyString())).thenReturn(Optional.of(rollback));
 
 284         var rbFromDb = automationCompositionProvider.getAutomationCompositionRollback(ac.getInstanceId()
 
 286         assertNotNull(rbFromDb);
 
 290     void testGetRollbackEmpty() {
 
 291         when(acRollbackRepository.findById(anyString())).thenReturn(Optional.empty());
 
 292         assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider
 
 293             .getAutomationCompositionRollback("empty"));