2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024-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.participant.sim.main.handler;
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyInt;
25 import static org.mockito.ArgumentMatchers.anyString;
26 import static org.mockito.Mockito.doCallRealMethod;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 import static org.mockito.Mockito.withSettings;
33 import java.util.HashMap;
34 import java.util.List;
36 import java.util.UUID;
37 import org.junit.jupiter.api.Test;
38 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
39 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
40 import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState;
41 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
42 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
43 import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData;
44 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
45 import org.onap.policy.clamp.models.acm.concepts.DeployState;
46 import org.onap.policy.clamp.models.acm.concepts.LockState;
47 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
50 class AutomationCompositionElementHandlerTest {
52 private static final ToscaConceptIdentifier ELEMENT_DEFINITION_ID = new ToscaConceptIdentifier("name", "1.0.0");
53 private static final CompositionElementDto COMPOSITION_ELEMENT =
54 new CompositionElementDto(UUID.randomUUID(), ELEMENT_DEFINITION_ID, Map.of(), Map.of());
55 private static final InstanceElementDto INSTANCE_ELEMENT =
56 new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), Map.of(), new HashMap<>());
57 private static final CompositionDto COMPOSITION = new CompositionDto(UUID.randomUUID(),
58 Map.of(ELEMENT_DEFINITION_ID, Map.of()), Map.of(ELEMENT_DEFINITION_ID, new HashMap<>()));
62 var config = CommonTestData.createSimConfig();
63 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
64 var simulatorService = new SimulatorService(intermediaryApi);
65 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
66 simulatorService.setConfig(config);
67 acElementHandler.deploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
68 verify(intermediaryApi).updateAutomationCompositionElementState(
69 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
70 null, StateChangeResult.NO_ERROR, "Deployed");
72 config.setDeploySuccess(false);
73 acElementHandler.deploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
74 verify(intermediaryApi).updateAutomationCompositionElementState(
75 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED,
76 null, StateChangeResult.FAILED, "Deploy failed!");
81 var config = CommonTestData.createSimConfig();
82 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
83 var simulatorService = new SimulatorService(intermediaryApi);
84 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
85 simulatorService.setConfig(config);
86 acElementHandler.undeploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
87 verify(intermediaryApi).updateAutomationCompositionElementState(
88 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED,
89 null, StateChangeResult.NO_ERROR, "Undeployed");
91 config.setUndeploySuccess(false);
92 acElementHandler.undeploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
93 verify(intermediaryApi).updateAutomationCompositionElementState(
94 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
95 null, StateChangeResult.FAILED, "Undeploy failed!");
100 var config = CommonTestData.createSimConfig();
101 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
102 var simulatorService = new SimulatorService(intermediaryApi);
103 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
104 simulatorService.setConfig(config);
105 acElementHandler.lock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
106 verify(intermediaryApi).updateAutomationCompositionElementState(
107 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.LOCKED,
108 StateChangeResult.NO_ERROR, "Locked");
110 config.setLockSuccess(false);
111 acElementHandler.lock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
112 verify(intermediaryApi).updateAutomationCompositionElementState(
113 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.UNLOCKED,
114 StateChangeResult.FAILED, "Lock failed!");
119 var config = CommonTestData.createSimConfig();
120 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
121 var simulatorService = new SimulatorService(intermediaryApi);
122 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
123 simulatorService.setConfig(config);
124 acElementHandler.unlock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
125 verify(intermediaryApi).updateAutomationCompositionElementState(
126 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.UNLOCKED,
127 StateChangeResult.NO_ERROR, "Unlocked");
129 config.setUnlockSuccess(false);
130 acElementHandler.unlock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
131 verify(intermediaryApi).updateAutomationCompositionElementState(
132 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.LOCKED,
133 StateChangeResult.FAILED, "Unlock failed!");
138 var config = CommonTestData.createSimConfig();
139 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
140 var simulatorService = new SimulatorService(intermediaryApi);
141 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
142 simulatorService.setConfig(config);
143 var instanceElementUpdated = new InstanceElementDto(
144 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
145 Map.of("key", "value"), Map.of());
146 acElementHandler.update(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, instanceElementUpdated);
147 verify(intermediaryApi).updateAutomationCompositionElementState(
148 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
149 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
151 config.setUpdateSuccess(false);
152 acElementHandler.update(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, instanceElementUpdated);
153 verify(intermediaryApi).updateAutomationCompositionElementState(
154 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
155 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!");
160 var config = CommonTestData.createSimConfig();
161 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
162 var simulatorService = new SimulatorService(intermediaryApi);
163 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
164 simulatorService.setConfig(config);
165 acElementHandler.delete(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
166 verify(intermediaryApi).updateAutomationCompositionElementState(
167 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DELETED,
168 null, StateChangeResult.NO_ERROR, "Deleted");
170 config.setDeleteSuccess(false);
171 acElementHandler.delete(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
172 verify(intermediaryApi).updateAutomationCompositionElementState(
173 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED,
174 null, StateChangeResult.FAILED, "Delete failed!");
179 var config = CommonTestData.createSimConfig();
180 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
181 var simulatorService = new SimulatorService(intermediaryApi);
182 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
183 simulatorService.setConfig(config);
184 acElementHandler.prime(COMPOSITION);
185 verify(intermediaryApi).updateCompositionState(
186 COMPOSITION.compositionId(), AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed");
188 config.setPrimeSuccess(false);
189 acElementHandler.prime(COMPOSITION);
190 verify(intermediaryApi).updateCompositionState(
191 COMPOSITION.compositionId(), AcTypeState.COMMISSIONED, StateChangeResult.FAILED, "Prime failed!");
196 var config = CommonTestData.createSimConfig();
197 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
198 var simulatorService = new SimulatorService(intermediaryApi);
199 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
200 simulatorService.setConfig(config);
201 acElementHandler.deprime(COMPOSITION);
202 verify(intermediaryApi).updateCompositionState(
203 COMPOSITION.compositionId(), AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed");
205 config.setDeprimeSuccess(false);
206 acElementHandler.deprime(COMPOSITION);
207 verify(intermediaryApi).updateCompositionState(
208 COMPOSITION.compositionId(), AcTypeState.PRIMED, StateChangeResult.FAILED, "Deprime failed!");
213 var config = CommonTestData.createSimConfig();
214 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
215 var simulatorService = new SimulatorService(intermediaryApi);
216 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
217 simulatorService.setConfig(config);
218 var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
220 var instanceElementMigrated = new InstanceElementDto(
221 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
222 Map.of("key", "value"), new HashMap<>());
224 .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated, 0);
225 verify(intermediaryApi).updateAutomationCompositionElementState(
226 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
227 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
229 config.setMigrateSuccess(false);
231 .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated, 0);
232 verify(intermediaryApi).updateAutomationCompositionElementState(
233 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
234 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!");
238 void testMigrateStage() {
239 var config = CommonTestData.createSimConfig();
240 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
241 var simulatorService = new SimulatorService(intermediaryApi);
242 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
243 simulatorService.setConfig(config);
244 var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
245 Map.of("stage", List.of(1, 2)), Map.of());
246 var instanceElementMigrated = new InstanceElementDto(INSTANCE_ELEMENT.instanceId(),
247 INSTANCE_ELEMENT.elementId(), Map.of(), new HashMap<>());
249 .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated, 1);
250 verify(intermediaryApi).updateAutomationCompositionElementStage(
251 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
252 StateChangeResult.NO_ERROR, 2, "stage 1 Migrated");
256 void testMigrateAdd() {
257 var config = CommonTestData.createSimConfig();
258 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
259 var simulatorService = new SimulatorService(intermediaryApi);
260 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
261 simulatorService.setConfig(config);
262 var compositionElement = new CompositionElementDto(
263 UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NOT_PRESENT);
265 var instanceElement = new InstanceElementDto(
266 UUID.randomUUID(), UUID.randomUUID(), Map.of(), Map.of(), ElementState.NOT_PRESENT);
268 var compoElTargetAdd = new CompositionElementDto(
269 UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NEW);
270 var inElMigratedAdd = new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(),
271 Map.of(), new HashMap<>(), ElementState.NEW);
273 .migrate(compositionElement, compoElTargetAdd, instanceElement, inElMigratedAdd, 0);
274 verify(intermediaryApi).updateAutomationCompositionElementState(
275 instanceElement.instanceId(), instanceElement.elementId(),
276 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
280 void testMigrateRemove() {
281 var config = CommonTestData.createSimConfig();
282 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
283 var simulatorService = new SimulatorService(intermediaryApi);
284 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
285 simulatorService.setConfig(config);
287 var compoElTargetRemove = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
288 Map.of(), Map.of(), ElementState.REMOVED);
289 var inElMigratedRemove = new InstanceElementDto(
290 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
291 Map.of("key", "value"), Map.of(), ElementState.REMOVED);
293 .migrate(COMPOSITION_ELEMENT, compoElTargetRemove, INSTANCE_ELEMENT, inElMigratedRemove, 0);
294 verify(intermediaryApi).updateAutomationCompositionElementState(
295 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
296 DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
297 verify(intermediaryApi).updateAutomationCompositionElementState(
298 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
299 DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
303 void testMigratePrecheck() {
304 var config = CommonTestData.createSimConfig();
305 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
306 var simulatorService = new SimulatorService(intermediaryApi);
307 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
308 simulatorService.setConfig(config);
309 var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
311 var instanceElementMigrated = new InstanceElementDto(
312 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
313 Map.of("key", "value"), Map.of());
314 acElementHandler.migratePrecheck(COMPOSITION_ELEMENT, compositionElementTarget,
315 INSTANCE_ELEMENT, instanceElementMigrated);
316 verify(intermediaryApi).updateAutomationCompositionElementState(
317 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
318 DeployState.DEPLOYED, null,
319 StateChangeResult.NO_ERROR, "Migration precheck completed");
321 config.setMigratePrecheck(false);
322 acElementHandler.migratePrecheck(COMPOSITION_ELEMENT, compositionElementTarget,
323 INSTANCE_ELEMENT, instanceElementMigrated);
324 verify(intermediaryApi).updateAutomationCompositionElementState(
325 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
326 DeployState.DEPLOYED, null,
327 StateChangeResult.FAILED, "Migration precheck failed");
332 var config = CommonTestData.createSimConfig();
333 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
334 var simulatorService = new SimulatorService(intermediaryApi);
335 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
336 simulatorService.setConfig(config);
337 acElementHandler.prepare(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, 0);
338 verify(intermediaryApi).updateAutomationCompositionElementState(
339 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED,
340 null, StateChangeResult.NO_ERROR, "Prepare completed");
342 config.setPrepare(false);
343 acElementHandler.prepare(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, 0);
344 verify(intermediaryApi).updateAutomationCompositionElementState(
345 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED,
346 null, StateChangeResult.FAILED, "Prepare failed");
351 var config = CommonTestData.createSimConfig();
352 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
353 var simulatorService = new SimulatorService(intermediaryApi);
354 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
355 simulatorService.setConfig(config);
356 acElementHandler.review(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
357 verify(intermediaryApi).updateAutomationCompositionElementState(
358 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
359 null, StateChangeResult.NO_ERROR, "Review completed");
361 config.setReview(false);
362 acElementHandler.review(COMPOSITION_ELEMENT, INSTANCE_ELEMENT);
363 verify(intermediaryApi).updateAutomationCompositionElementState(
364 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
365 null, StateChangeResult.FAILED, "Review failed");
369 void testRollback() {
370 var config = CommonTestData.createSimConfig();
371 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
372 var simulatorService = new SimulatorService(intermediaryApi);
373 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
374 simulatorService.setConfig(config);
376 acElementHandler.rollbackMigration(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, DeployState.DEPLOYED.ordinal());
377 verify(intermediaryApi).updateAutomationCompositionElementState(
378 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
379 null, StateChangeResult.NO_ERROR, "Migration rollback done");
381 config.setRollback(false);
382 acElementHandler.rollbackMigration(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, DeployState.DEPLOYED.ordinal());
383 verify(intermediaryApi).updateAutomationCompositionElementState(
384 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
385 null, StateChangeResult.FAILED, "Migration rollback failed");
389 void testRollbackTimeout() {
390 var config = CommonTestData.createSimConfig();
391 var intermediaryApi = mock(ParticipantIntermediaryApi.class);
392 var simulatorService = mock(SimulatorService.class, withSettings().useConstructor(intermediaryApi));
394 when(simulatorService.getConfig()).thenReturn(config);
395 when(simulatorService.isInterrupted(anyInt(), anyString(), any())).thenReturn(true);
396 doCallRealMethod().when(simulatorService).rollback(INSTANCE_ELEMENT.instanceId(),
397 INSTANCE_ELEMENT.elementId());
399 var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService);
400 acElementHandler.rollbackMigration(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, DeployState.DEPLOYED.ordinal());
401 verify(simulatorService).rollback(INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId());
402 verify(intermediaryApi, times(0)).updateAutomationCompositionElementState(
403 INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED,
404 null, StateChangeResult.NO_ERROR, "Migration rollback done");