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);
 
  73     void beforeSetupDao() throws Exception {
 
  74         inputAutomationCompositions = CODER.decode(originalJson, AutomationCompositions.class);
 
  75         inputAutomationCompositionsJpa =
 
  76             ProviderUtils.getJpaAndValidateList(inputAutomationCompositions.getAutomationCompositionList(),
 
  77                 JpaAutomationComposition::new, "automation compositions");
 
  81     void testAutomationCompositionCreate() {
 
  82         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
  83         when(automationCompositionRepository.save(any(JpaAutomationComposition.class)))
 
  84             .thenReturn(inputAutomationCompositionsJpa.get(0));
 
  85         var inputAc = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
  87         var automationCompositionProvider = new AutomationCompositionProvider(
 
  88                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
  89                 mock(AutomationCompositionRollbackRepository.class));
 
  90         var createdAutomationComposition = automationCompositionProvider.createAutomationComposition(inputAc);
 
  91         inputAc.setInstanceId(createdAutomationComposition.getInstanceId());
 
  92         inputAc.setLastMsg(createdAutomationComposition.getLastMsg());
 
  93         assertEquals(inputAc, createdAutomationComposition);
 
  97     void testAutomationCompositionUpdate() {
 
  98         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
  99         var automationCompositionProvider = new AutomationCompositionProvider(
 
 100                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 101                 mock(AutomationCompositionRollbackRepository.class));
 
 102         assertThatThrownBy(() -> automationCompositionProvider.updateAutomationComposition(null))
 
 103             .hasMessageMatching(AC_IS_NULL);
 
 105         when(automationCompositionRepository.save(inputAutomationCompositionsJpa.get(0)))
 
 106             .thenReturn(inputAutomationCompositionsJpa.get(0));
 
 108         var createdAutomationComposition = automationCompositionProvider
 
 109             .updateAutomationComposition(inputAutomationCompositions.getAutomationCompositionList().get(0));
 
 111         assertEquals(inputAutomationCompositions.getAutomationCompositionList().get(0), createdAutomationComposition);
 
 115     void testGetAutomationCompositionsWithNull() {
 
 116         var automationCompositionProvider = new AutomationCompositionProvider(
 
 117                 mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class),
 
 118                 mock(AutomationCompositionRollbackRepository.class));
 
 119         assertThatThrownBy(() -> automationCompositionProvider
 
 120             .getAutomationCompositions(UUID.randomUUID(), null, null, null))
 
 121             .hasMessage("pageable is marked non-null but is null");
 
 123         assertThatThrownBy(() -> automationCompositionProvider
 
 124             .getAutomationCompositions(null, null, null, Pageable.unpaged()))
 
 125             .hasMessage("compositionId is marked non-null but is null");
 
 129     void testGetAutomationCompositions() {
 
 130         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 131         var automationCompositionProvider = new AutomationCompositionProvider(
 
 132                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 133                 mock(AutomationCompositionRollbackRepository.class));
 
 134         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 135         when(automationCompositionRepository
 
 136             .findAll(Mockito.any(), any(Pageable.class)))
 
 137             .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa));
 
 138         var acList = automationCompositionProvider.getAutomationCompositions(UUID.randomUUID(),
 
 139             automationComposition.getName(), automationComposition.getVersion(), Pageable.unpaged());
 
 140         assertThat(acList).hasSize(2);
 
 142         acList = automationCompositionProvider.getAutomationCompositions(automationComposition.getCompositionId(), null,
 
 143             null, Pageable.unpaged());
 
 144         assertThat(acList).hasSize(2);
 
 146         when(automationCompositionRepository
 
 147             .findAll(Mockito.any(), Mockito.any(Pageable.class)))
 
 148             .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa));
 
 149         acList = automationCompositionProvider.getAutomationCompositions(automationComposition.getCompositionId(), null,
 
 150             null, PageRequest.of(0, 10));
 
 151         assertThat(acList).hasSize(2);
 
 155     void testGetAutomationComposition() {
 
 156         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 157         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 158         var automationCompositionProvider = new AutomationCompositionProvider(
 
 159                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 160                 mock(AutomationCompositionRollbackRepository.class));
 
 162             () -> automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId()))
 
 163             .hasMessageMatching("AutomationComposition not found");
 
 165         when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString()))
 
 166             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 167         var ac = automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId());
 
 168         assertEquals(automationComposition, ac);
 
 172     void testFindAutomationComposition() {
 
 173         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 174         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 175         var automationCompositionProvider = new AutomationCompositionProvider(
 
 176                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 177                 mock(AutomationCompositionRollbackRepository.class));
 
 178         var acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId());
 
 179         assertThat(acOpt).isEmpty();
 
 181         acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
 
 182         assertThat(acOpt).isEmpty();
 
 184         when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString()))
 
 185             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 186         acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId());
 
 187         assertEquals(automationComposition, acOpt.get());
 
 189         when(automationCompositionRepository.findOne(Mockito.any()))
 
 190             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 191         acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
 
 192         assertEquals(automationComposition, acOpt.get());
 
 196     void testGetAcInstancesByCompositionId() {
 
 197         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 198         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 199         when(automationCompositionRepository.findByCompositionId(automationComposition.getCompositionId().toString()))
 
 200             .thenReturn(inputAutomationCompositionsJpa);
 
 201         var automationCompositionProvider = new AutomationCompositionProvider(
 
 202                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 203                 mock(AutomationCompositionRollbackRepository.class));
 
 205             automationCompositionProvider.getAcInstancesByCompositionId(automationComposition.getCompositionId());
 
 206         assertEquals(inputAutomationCompositions.getAutomationCompositionList(), acList);
 
 210     void testGetAcInstancesInTransition() {
 
 211         inputAutomationCompositions.getAutomationCompositionList().get(0).setDeployState(DeployState.DEPLOYING);
 
 212         inputAutomationCompositions.getAutomationCompositionList().get(1).setLockState(LockState.LOCKING);
 
 213         inputAutomationCompositionsJpa.get(0).setDeployState(DeployState.DEPLOYING);
 
 214         inputAutomationCompositionsJpa.get(1).setLockState(LockState.LOCKING);
 
 216         List<JpaAutomationComposition> res1 = new ArrayList<>();
 
 217         res1.add(inputAutomationCompositionsJpa.get(0));
 
 219         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 220         when(automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
 
 221             DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING)))
 
 223         when(automationCompositionRepository.findByLockStateIn(List.of(LockState.LOCKING, LockState.UNLOCKING)))
 
 224             .thenReturn(List.of(inputAutomationCompositionsJpa.get(1)));
 
 225         var automationCompositionProvider = new AutomationCompositionProvider(
 
 226                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 227                 mock(AutomationCompositionRollbackRepository.class));
 
 228         var acList = automationCompositionProvider.getAcInstancesInTransition();
 
 229         assertThat(acList).hasSize(2)
 
 230             .contains(inputAutomationCompositions.getAutomationCompositionList().get(0).getInstanceId())
 
 231             .contains(inputAutomationCompositions.getAutomationCompositionList().get(1).getInstanceId());
 
 235     void testDeleteAutomationComposition() {
 
 236         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 237         var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class);
 
 238         var automationCompositionProvider = new AutomationCompositionProvider(
 
 239                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 240                 acRollbackRepository);
 
 241         assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationComposition(UUID.randomUUID()))
 
 242             .hasMessageMatching(".*.failed, automation composition does not exist");
 
 244         assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationComposition(null))
 
 245                 .hasMessageMatching("instanceId is marked non-null but is null");
 
 247         var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 248         when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString()))
 
 249             .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0)));
 
 252             automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
 
 253         assertEquals(automationComposition, deletedAc);
 
 255         when(acRollbackRepository.existsById(automationComposition.getInstanceId().toString())).thenReturn(true);
 
 258                 automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
 
 259         assertEquals(automationComposition, deletedAc);
 
 260         verify(acRollbackRepository).deleteById(automationComposition.getInstanceId().toString());
 
 264     void testDeleteElementById() {
 
 265         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 266         var acElementRepository = mock(AutomationCompositionElementRepository.class);
 
 267         var automationCompositionProvider = new AutomationCompositionProvider(
 
 268                 automationCompositionRepository, acElementRepository,
 
 269                 mock(AutomationCompositionRollbackRepository.class));
 
 270         assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationCompositionElement(null))
 
 271             .hasMessageMatching(ACELEMENT_ID_IS_NULL);
 
 272         var elementId = UUID.randomUUID();
 
 273         automationCompositionProvider.deleteAutomationCompositionElement(elementId);
 
 274         verify(acElementRepository).deleteById(elementId.toString());
 
 278     void testValidateElementIds() {
 
 279         var ac = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 281         var acElementRepository = mock(AutomationCompositionElementRepository.class);
 
 282         var automationCompositionProvider = new AutomationCompositionProvider(
 
 283                 mock(AutomationCompositionRepository.class), acElementRepository,
 
 284                 mock(AutomationCompositionRollbackRepository.class));
 
 285         var result = automationCompositionProvider.validateElementIds(ac);
 
 286         assertThat(result.isValid()).isTrue();
 
 288         var jpaElement = new JpaAutomationCompositionElement(ac.getElements().values().iterator().next());
 
 289         when(acElementRepository.findAllById(anyIterable()))
 
 290             .thenReturn(List.of(jpaElement));
 
 292         ac.setInstanceId(null);
 
 293         result = automationCompositionProvider.validateElementIds(ac);
 
 294         assertThat(result.isValid()).isFalse();
 
 296         ac.setInstanceId(UUID.randomUUID());
 
 297         jpaElement.setInstanceId(UUID.randomUUID().toString());
 
 298         result = automationCompositionProvider.validateElementIds(ac);
 
 299         assertThat(result.isValid()).isFalse();
 
 301         ac.setInstanceId(UUID.randomUUID());
 
 302         jpaElement.setInstanceId(ac.getInstanceId().toString());
 
 303         result = automationCompositionProvider.validateElementIds(ac);
 
 304         assertThat(result.isValid()).isTrue();
 
 308     void testCopyAcElements() {
 
 309         var ac = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 310         var automationCompositionRepository = mock(AutomationCompositionRepository.class);
 
 311         var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class);
 
 312         var automationCompositionProvider = new AutomationCompositionProvider(
 
 313                 automationCompositionRepository, mock(AutomationCompositionElementRepository.class),
 
 314                 acRollbackRepository);
 
 315         automationCompositionProvider.copyAcElementsBeforeUpdate(ac);
 
 317         verify(acRollbackRepository).save(any(JpaAutomationCompositionRollback.class));
 
 318         var instanceId = ac.getInstanceId();
 
 319         assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider
 
 320             .getAutomationCompositionRollback(instanceId));
 
 324     void testGetRollbackSuccess() {
 
 325         var ac = inputAutomationCompositions.getAutomationCompositionList().get(0);
 
 326         var rollback = new JpaAutomationCompositionRollback();
 
 327         rollback.setInstanceId(ac.getInstanceId().toString());
 
 328         rollback.setCompositionId(ac.getCompositionId().toString());
 
 330         var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class);
 
 331         when(acRollbackRepository.findById(anyString())).thenReturn(Optional.of(rollback));
 
 333         var automationCompositionProvider = new AutomationCompositionProvider(
 
 334                 mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class),
 
 335                 acRollbackRepository);
 
 336         var rbFromDb = automationCompositionProvider.getAutomationCompositionRollback(ac.getInstanceId());
 
 337         assertNotNull(rbFromDb);
 
 341     void testGetRollbackEmpty() {
 
 342         var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class);
 
 343         var automationCompositionProvider = new AutomationCompositionProvider(
 
 344                 mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class),
 
 345                 acRollbackRepository);
 
 346         when(acRollbackRepository.findById(anyString())).thenReturn(Optional.empty());
 
 347         var compositionId = UUID.randomUUID();
 
 348         assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider
 
 349             .getAutomationCompositionRollback(compositionId));