2  * ============LICENSE_START=======================================================
 
   3  * Copyright (C) 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.acm.runtime.supervision.scanner;
 
  23 import static org.junit.jupiter.api.Assertions.assertEquals;
 
  24 import static org.mockito.ArgumentMatchers.any;
 
  25 import static org.mockito.Mockito.clearInvocations;
 
  26 import static org.mockito.Mockito.mock;
 
  27 import static org.mockito.Mockito.times;
 
  28 import static org.mockito.Mockito.verify;
 
  29 import static org.mockito.Mockito.when;
 
  30 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
 
  32 import java.util.List;
 
  34 import java.util.UUID;
 
  35 import org.junit.jupiter.api.Test;
 
  36 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
 
  37 import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
 
  38 import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher;
 
  39 import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher;
 
  40 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
 
  41 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
 
  42 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 
  43 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
 
  44 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  45 import org.onap.policy.clamp.models.acm.concepts.LockState;
 
  46 import org.onap.policy.clamp.models.acm.concepts.SubState;
 
  47 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
 
  48 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
 
  50 class StageScannerTest {
 
  51     private static final String AC_JSON = "src/test/resources/rest/acm/AutomationCompositionSmoke.json";
 
  52     private static final UUID COMPOSITION_ID = UUID.randomUUID();
 
  55     void testSendAutomationCompositionMigrate() {
 
  56         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
  57         automationComposition.setInstanceId(UUID.randomUUID());
 
  58         automationComposition.setDeployState(DeployState.MIGRATING);
 
  59         automationComposition.setCompositionId(COMPOSITION_ID);
 
  60         var compositionTargetId = UUID.randomUUID();
 
  61         automationComposition.setCompositionTargetId(compositionTargetId);
 
  62         automationComposition.setLockState(LockState.LOCKED);
 
  63         automationComposition.setLastMsg(TimestampHelper.now());
 
  64         automationComposition.setPhase(0);
 
  65         for (var element : automationComposition.getElements().values()) {
 
  66             element.setDeployState(DeployState.DEPLOYED);
 
  67             element.setLockState(LockState.LOCKED);
 
  69         // first element is not migrated yet
 
  70         var element = automationComposition.getElements().entrySet().iterator().next().getValue();
 
  71         element.setDeployState(DeployState.MIGRATING);
 
  73         var acProvider = mock(AutomationCompositionProvider.class);
 
  74         when(acProvider.updateAutomationComposition(any())).thenReturn(automationComposition);
 
  75         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
  76         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
  77         var supervisionScanner = new StageScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
  78                 mock(AutomationCompositionMigrationPublisher.class), mock(AcPreparePublisher.class),
 
  79                 acRuntimeParameterGroup, encryptionUtils);
 
  80         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
  81         var acDefinition = new AutomationCompositionDefinition();
 
  82         acDefinition.setServiceTemplate(serviceTemplate);
 
  83         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
  84         verify(acProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
 
  85         assertEquals(DeployState.MIGRATING, automationComposition.getDeployState());
 
  87         // send message for next stage
 
  88         clearInvocations(acProvider);
 
  89         var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
 
  90                 .get(element.getDefinition().getName());
 
  91         toscaNodeTemplate.setProperties(Map.of("stage", List.of(1)));
 
  93         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
  94         verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
 
  95         assertEquals(DeployState.MIGRATING, automationComposition.getDeployState());
 
  97         // first element is migrated
 
  98         clearInvocations(acProvider);
 
  99         element.setDeployState(DeployState.DEPLOYED);
 
 100         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 101         verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
 
 103         assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState());
 
 104         assertEquals(compositionTargetId, automationComposition.getCompositionId());
 
 108     void testSendAutomationCompositionMigrationReverting() {
 
 109         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
 110         automationComposition.setInstanceId(UUID.randomUUID());
 
 111         automationComposition.setDeployState(DeployState.MIGRATION_REVERTING);
 
 112         automationComposition.setCompositionId(COMPOSITION_ID);
 
 113         var compositionTargetId = UUID.randomUUID();
 
 114         automationComposition.setCompositionTargetId(compositionTargetId);
 
 115         automationComposition.setLockState(LockState.LOCKED);
 
 116         automationComposition.setLastMsg(TimestampHelper.now());
 
 117         automationComposition.setPhase(0);
 
 118         for (var element : automationComposition.getElements().values()) {
 
 119             element.setDeployState(DeployState.DEPLOYED);
 
 120             element.setLockState(LockState.LOCKED);
 
 122         // first element is not migrated yet
 
 123         var element = automationComposition.getElements().entrySet().iterator().next().getValue();
 
 124         element.setDeployState(DeployState.MIGRATION_REVERTING);
 
 126         var acProvider = mock(AutomationCompositionProvider.class);
 
 127         when(acProvider.updateAutomationComposition(any())).thenReturn(automationComposition);
 
 128         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
 129         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
 130         var supervisionScanner = new StageScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 131                 mock(AutomationCompositionMigrationPublisher.class), mock(AcPreparePublisher.class),
 
 132                 acRuntimeParameterGroup, encryptionUtils);
 
 133         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
 134         var acDefinition = new AutomationCompositionDefinition();
 
 135         acDefinition.setServiceTemplate(serviceTemplate);
 
 136         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 137         verify(acProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
 
 138         assertEquals(DeployState.MIGRATION_REVERTING, automationComposition.getDeployState());
 
 140         // send message for next stage
 
 141         clearInvocations(acProvider);
 
 142         var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
 
 143                 .get(element.getDefinition().getName());
 
 144         toscaNodeTemplate.setProperties(Map.of("stage", List.of(1)));
 
 146         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 147         verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
 
 148         assertEquals(DeployState.MIGRATION_REVERTING, automationComposition.getDeployState());
 
 150         // first element is migrated
 
 151         clearInvocations(acProvider);
 
 152         element.setDeployState(DeployState.DEPLOYED);
 
 153         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 154         verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
 
 156         assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState());
 
 157         assertEquals(compositionTargetId, automationComposition.getCompositionId());
 
 161     void testSendAutomationCompositionPrepare() {
 
 162         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
 163         automationComposition.setDeployState(DeployState.UNDEPLOYED);
 
 164         automationComposition.setSubState(SubState.PREPARING);
 
 165         automationComposition.setLockState(LockState.NONE);
 
 166         automationComposition.setCompositionId(COMPOSITION_ID);
 
 167         automationComposition.setLastMsg(TimestampHelper.now());
 
 168         automationComposition.setPhase(0);
 
 169         for (var element : automationComposition.getElements().values()) {
 
 170             element.setDeployState(DeployState.UNDEPLOYED);
 
 171             element.setLockState(LockState.NONE);
 
 172             element.setSubState(SubState.NONE);
 
 174         // first element is not prepared yet
 
 175         var element = automationComposition.getElements().entrySet().iterator().next().getValue();
 
 176         element.setSubState(SubState.PREPARING);
 
 178         var acProvider = mock(AutomationCompositionProvider.class);
 
 179         when(acProvider.updateAutomationComposition(any())).thenReturn(automationComposition);
 
 181         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
 182         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
 183         var supervisionScanner = new StageScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 184                 mock(AutomationCompositionMigrationPublisher.class), mock(AcPreparePublisher.class),
 
 185                 acRuntimeParameterGroup, encryptionUtils);
 
 187         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
 188         var acDefinition = new AutomationCompositionDefinition();
 
 189         acDefinition.setServiceTemplate(serviceTemplate);
 
 190         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 191         verify(acProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
 
 192         assertEquals(SubState.PREPARING, automationComposition.getSubState());
 
 194         // send message for next stage
 
 195         clearInvocations(acProvider);
 
 196         var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
 
 197                 .get(element.getDefinition().getName());
 
 198         var prepare = Map.of("prepare", List.of(1));
 
 199         toscaNodeTemplate.setProperties(Map.of("stage", prepare));
 
 201         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 202         verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
 
 203         assertEquals(SubState.PREPARING, automationComposition.getSubState());
 
 205         // first element is prepared
 
 206         clearInvocations(acProvider);
 
 207         element.setSubState(SubState.NONE);
 
 208         supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
 
 209         verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
 
 211         assertEquals(SubState.NONE, automationComposition.getSubState());