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.junit.jupiter.api.Assertions.assertFalse;
 
  25 import static org.junit.jupiter.api.Assertions.assertTrue;
 
  26 import static org.mockito.ArgumentMatchers.any;
 
  27 import static org.mockito.Mockito.mock;
 
  28 import static org.mockito.Mockito.times;
 
  29 import static org.mockito.Mockito.verify;
 
  32 import java.util.UUID;
 
  33 import java.util.function.Consumer;
 
  34 import org.junit.jupiter.api.Test;
 
  35 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
 
  36 import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
 
  37 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
 
  38 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
 
  39 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 
  40 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 
  41 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  42 import org.onap.policy.clamp.models.acm.concepts.LockState;
 
  43 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 
  44 import org.onap.policy.clamp.models.acm.concepts.SubState;
 
  45 import org.onap.policy.clamp.models.acm.document.concepts.DocMessage;
 
  46 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType;
 
  47 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
 
  48 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
 
  50 class SimpleScannerTest {
 
  52     private static final String AC_JSON = "src/test/resources/rest/acm/AutomationCompositionSmoke.json";
 
  53     private static final String ELEMENT_NAME =
 
  54             "org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement";
 
  56     private static final UUID COMPOSITION_ID = UUID.randomUUID();
 
  57     private static final UUID INSTANCE_ID = UUID.randomUUID();
 
  58     private static final Map<String, Object> OUT_PROPERTIES = Map.of("key", "value");
 
  61     void testFailScenario() {
 
  62         var automationComposition = createDeploying();
 
  63         var elementId = automationComposition.getElements().values().iterator().next().getId();
 
  64         var docMessage = new DocMessage();
 
  65         docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK);
 
  66         docMessage.setInstanceId(INSTANCE_ID);
 
  67         docMessage.setInstanceElementId(elementId);
 
  68         docMessage.setDeployState(DeployState.UNDEPLOYED);
 
  69         docMessage.setLockState(LockState.NONE);
 
  70         docMessage.setStateChangeResult(StateChangeResult.FAILED);
 
  71         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
  72         var acProvider = mock(AutomationCompositionProvider.class);
 
  73         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
  74         var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
  75                 acRuntimeParameterGroup, encryptionUtils);
 
  76         var result = simpleScanner.scanMessage(automationComposition, docMessage);
 
  77         assertTrue(result.isUpdated());
 
  78         assertTrue(result.isToBeSync());
 
  79         assertEquals(docMessage.getDeployState(),
 
  80                 automationComposition.getElements().get(elementId).getDeployState());
 
  81         assertEquals(docMessage.getLockState(),
 
  82                 automationComposition.getElements().get(elementId).getLockState());
 
  83         assertEquals(docMessage.getStateChangeResult(), automationComposition.getStateChangeResult());
 
  87     void testWithWrongData() {
 
  88         var automationComposition = createDeploying();
 
  89         var elementId = automationComposition.getElements().values().iterator().next().getId();
 
  90         var docMessage = new DocMessage();
 
  91         docMessage.setInstanceId(INSTANCE_ID);
 
  92         docMessage.setInstanceElementId(elementId);
 
  93         docMessage.setStateChangeResult(StateChangeResult.NO_ERROR);
 
  94         docMessage.setDeployState(DeployState.DEPLOYED);
 
  95         docMessage.setLockState(LockState.LOCKED);
 
  96         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
  97         var acProvider = mock(AutomationCompositionProvider.class);
 
  98         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
  99         var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 100                 acRuntimeParameterGroup, encryptionUtils);
 
 103         docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_PRIME_ACK);
 
 104         var result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 105         assertFalse(result.isUpdated());
 
 106         assertFalse(result.isToBeSync());
 
 108         // wrong elementId in outProperties
 
 109         docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_STATUS);
 
 110         docMessage.setInstanceElementId(UUID.randomUUID());
 
 111         docMessage.setOutProperties(OUT_PROPERTIES);
 
 112         result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 113         assertFalse(result.isUpdated());
 
 114         assertFalse(result.isToBeSync());
 
 116         // wrong elementId in StateChange
 
 117         docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
 
 118         result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 119         assertFalse(result.isUpdated());
 
 120         assertFalse(result.isToBeSync());
 
 122         // wrong Delete State
 
 123         docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
 
 124         docMessage.setInstanceElementId(elementId);
 
 125         docMessage.setDeployState(DeployState.DELETED);
 
 126         result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 127         assertFalse(result.isUpdated());
 
 128         assertFalse(result.isToBeSync());
 
 132     void testScanMessageOutProperties() {
 
 133         var automationComposition = createDeploying();
 
 134         var elementId = automationComposition.getElements().values().iterator().next().getId();
 
 135         var docMessage = new DocMessage();
 
 136         docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_STATUS);
 
 137         docMessage.setInstanceId(INSTANCE_ID);
 
 138         docMessage.setInstanceElementId(elementId);
 
 139         docMessage.setOutProperties(Map.of("key", "value"));
 
 140         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
 141         var acProvider = mock(AutomationCompositionProvider.class);
 
 142         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
 143         var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 144                 acRuntimeParameterGroup, encryptionUtils);
 
 145         var result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 146         assertTrue(result.isUpdated());
 
 147         assertTrue(result.isToBeSync());
 
 148         assertEquals(docMessage.getOutProperties(),
 
 149                 automationComposition.getElements().get(elementId).getOutProperties());
 
 153     void testScanMessageStateChange() {
 
 154         var automationComposition = createDeploying();
 
 155         var elementId = automationComposition.getElements().values().iterator().next().getId();
 
 156         var docMessage = new DocMessage();
 
 157         docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK);
 
 158         docMessage.setStateChangeResult(StateChangeResult.NO_ERROR);
 
 159         docMessage.setInstanceId(INSTANCE_ID);
 
 160         docMessage.setInstanceElementId(elementId);
 
 161         docMessage.setDeployState(DeployState.DEPLOYED);
 
 162         docMessage.setLockState(LockState.LOCKED);
 
 163         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
 164         var acProvider = mock(AutomationCompositionProvider.class);
 
 165         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
 166         var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 167                 acRuntimeParameterGroup, encryptionUtils);
 
 168         var result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 169         assertTrue(result.isUpdated());
 
 170         assertFalse(result.isToBeSync());
 
 171         assertEquals(docMessage.getDeployState(),
 
 172                 automationComposition.getElements().get(elementId).getDeployState());
 
 173         assertEquals(docMessage.getLockState(),
 
 174                 automationComposition.getElements().get(elementId).getLockState());
 
 179     void testScanMessageStateChangeDelete() {
 
 180         var automationComposition = createDeploying();
 
 181         automationComposition.setDeployState(DeployState.DELETING);
 
 182         automationComposition.setLockState(LockState.NONE);
 
 183         var elementId = automationComposition.getElements().values().iterator().next().getId();
 
 184         var docMessage = new DocMessage();
 
 185         docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK);
 
 186         docMessage.setStateChangeResult(StateChangeResult.NO_ERROR);
 
 187         docMessage.setInstanceId(INSTANCE_ID);
 
 188         docMessage.setInstanceElementId(elementId);
 
 189         docMessage.setDeployState(DeployState.DELETED);
 
 190         docMessage.setLockState(LockState.NONE);
 
 191         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
 192         var acProvider = mock(AutomationCompositionProvider.class);
 
 193         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
 194         var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 195                 acRuntimeParameterGroup, encryptionUtils);
 
 196         var result = simpleScanner.scanMessage(automationComposition, docMessage);
 
 197         assertTrue(result.isUpdated());
 
 198         assertFalse(result.isToBeSync());
 
 199         assertEquals(docMessage.getDeployState(),
 
 200                 automationComposition.getElements().get(elementId).getDeployState());
 
 201         assertEquals(docMessage.getLockState(),
 
 202                 automationComposition.getElements().get(elementId).getLockState());
 
 205     private AutomationComposition createDeploying() {
 
 206         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
 207         automationComposition.setInstanceId(INSTANCE_ID);
 
 208         automationComposition.setDeployState(DeployState.DEPLOYING);
 
 209         automationComposition.setLockState(LockState.NONE);
 
 210         automationComposition.setPhase(0);
 
 211         automationComposition.setLastMsg(TimestampHelper.now());
 
 212         automationComposition.setCompositionId(COMPOSITION_ID);
 
 213         for (var element : automationComposition.getElements().values()) {
 
 214             element.setDeployState(DeployState.DEPLOYING);
 
 215             element.setLockState(LockState.NONE);
 
 217         return automationComposition;
 
 221     void testSendAutomationCompositionMigratingPrecheck() {
 
 222         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
 223         automationComposition.setLockState(LockState.LOCKED);
 
 224         automationComposition.setDeployState(DeployState.DEPLOYED);
 
 225         automationComposition.setSubState(SubState.MIGRATION_PRECHECKING);
 
 226         for (var element : automationComposition.getElements().values()) {
 
 227             element.setDeployState(DeployState.DEPLOYED);
 
 228             element.setSubState(SubState.NONE);
 
 229             element.setLockState(LockState.LOCKED);
 
 230             if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
 
 231                 element.setSubState(SubState.MIGRATION_PRECHECKING);
 
 234         testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE));
 
 238     void testSendAutomationCompositionPrepare() {
 
 239         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
 240         automationComposition.setLockState(LockState.NONE);
 
 241         automationComposition.setDeployState(DeployState.UNDEPLOYED);
 
 242         automationComposition.setSubState(SubState.PREPARING);
 
 243         for (var element : automationComposition.getElements().values()) {
 
 244             element.setDeployState(DeployState.UNDEPLOYED);
 
 245             element.setSubState(SubState.NONE);
 
 246             element.setLockState(LockState.NONE);
 
 247             if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
 
 248                 element.setSubState(SubState.PREPARING);
 
 251         testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE));
 
 255     void testSendAutomationCompositionUpdate() {
 
 256         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
 
 257         automationComposition.setLockState(LockState.LOCKED);
 
 258         automationComposition.setDeployState(DeployState.UPDATING);
 
 259         for (var element : automationComposition.getElements().values()) {
 
 260             element.setSubState(SubState.NONE);
 
 261             element.setLockState(LockState.LOCKED);
 
 262             if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
 
 263                 element.setDeployState(DeployState.UPDATING);
 
 265                 element.setDeployState(DeployState.DEPLOYED);
 
 268         testSimpleScan(automationComposition, element -> element.setDeployState(DeployState.DEPLOYED));
 
 271     private void testSimpleScan(AutomationComposition automationComposition, Consumer<AutomationCompositionElement> c) {
 
 272         automationComposition.setInstanceId(INSTANCE_ID);
 
 273         automationComposition.setLockState(LockState.NONE);
 
 274         automationComposition.setCompositionId(COMPOSITION_ID);
 
 275         automationComposition.setLastMsg(TimestampHelper.now());
 
 276         var acProvider = mock(AutomationCompositionProvider.class);
 
 277         var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
 
 278         var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
 
 279         var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
 
 280                 acRuntimeParameterGroup, encryptionUtils);
 
 281         simpleScanner.simpleScan(automationComposition, new UpdateSync());
 
 282         verify(acProvider, times(0)).updateAutomationComposition(any());
 
 284         automationComposition.getElements().values().forEach(c);
 
 285         simpleScanner.simpleScan(automationComposition, new UpdateSync());
 
 286         verify(acProvider).updateAutomationComposition(any());