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 return createAutomationComposition(DeployState.DEPLOYING, LockState.NONE);
210 void testSendAutomationCompositionMigratingPrecheck() {
211 var automationComposition = createAutomationComposition(DeployState.DEPLOYED, LockState.LOCKED);
212 automationComposition.setSubState(SubState.MIGRATION_PRECHECKING);
213 for (var element : automationComposition.getElements().values()) {
214 element.setSubState(SubState.NONE);
215 if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
216 element.setSubState(SubState.MIGRATION_PRECHECKING);
219 testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE));
223 void testSendAutomationCompositionPrepare() {
224 var automationComposition = createAutomationComposition(DeployState.UNDEPLOYED, LockState.NONE);
225 automationComposition.setSubState(SubState.PREPARING);
226 for (var element : automationComposition.getElements().values()) {
227 element.setSubState(SubState.NONE);
228 if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
229 element.setSubState(SubState.PREPARING);
232 testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE));
236 void testSendAutomationCompositionUpdate() {
237 var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
238 automationComposition.setLockState(LockState.LOCKED);
239 automationComposition.setDeployState(DeployState.UPDATING);
240 for (var element : automationComposition.getElements().values()) {
241 element.setSubState(SubState.NONE);
242 element.setLockState(LockState.LOCKED);
243 if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
244 element.setDeployState(DeployState.UPDATING);
246 element.setDeployState(DeployState.DEPLOYED);
249 testSimpleScan(automationComposition, element -> element.setDeployState(DeployState.DEPLOYED));
252 private void testSimpleScan(AutomationComposition automationComposition, Consumer<AutomationCompositionElement> c) {
253 automationComposition.setInstanceId(INSTANCE_ID);
254 automationComposition.setLockState(LockState.NONE);
255 automationComposition.setCompositionId(COMPOSITION_ID);
256 automationComposition.setLastMsg(TimestampHelper.now());
257 var acProvider = mock(AutomationCompositionProvider.class);
258 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
259 var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
260 var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
261 acRuntimeParameterGroup, encryptionUtils);
262 simpleScanner.simpleScan(automationComposition, new UpdateSync());
263 verify(acProvider, times(0)).updateAutomationComposition(any());
265 automationComposition.getElements().values().forEach(c);
266 simpleScanner.simpleScan(automationComposition, new UpdateSync());
267 verify(acProvider).updateAutomationComposition(any());
271 void testScanMessageMigrationFail() {
272 var automationComposition = createAutomationComposition(DeployState.MIGRATING, LockState.LOCKED);
273 var elementId = UUID.randomUUID();
274 var docMessage = new DocMessage();
275 docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
276 docMessage.setStateChangeResult(StateChangeResult.FAILED);
277 docMessage.setInstanceId(INSTANCE_ID);
278 docMessage.setInstanceElementId(elementId);
279 docMessage.setDeployState(DeployState.UNDEPLOYED);
280 docMessage.setLockState(LockState.NONE);
281 var acProvider = mock(AutomationCompositionProvider.class);
282 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
283 var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
284 acRuntimeParameterGroup, new EncryptionUtils(acRuntimeParameterGroup));
285 var result = simpleScanner.scanMessage(automationComposition, docMessage);
286 assertTrue(result.isUpdated());
287 assertTrue(result.isToBeSync());
290 private AutomationComposition createAutomationComposition(DeployState deployState, LockState lockState) {
291 var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
292 automationComposition.setInstanceId(INSTANCE_ID);
293 automationComposition.setDeployState(deployState);
294 automationComposition.setLockState(lockState);
295 automationComposition.setPhase(0);
296 automationComposition.setLastMsg(TimestampHelper.now());
297 automationComposition.setCompositionId(COMPOSITION_ID);
298 for (var element : automationComposition.getElements().values()) {
299 element.setDeployState(deployState);
300 element.setLockState(lockState);
302 return automationComposition;