23709728ddab8cc5fff7cc38d8aade6fa73fc3f6
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021-2024 Nordix Foundation.
4  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.clamp.acm.runtime.instantiation;
23
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.assertj.core.api.Assertions.assertThatThrownBy;
26 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.Mockito.doNothing;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
33
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Optional;
38 import java.util.UUID;
39 import org.junit.jupiter.api.BeforeAll;
40 import org.junit.jupiter.api.Test;
41 import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
42 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
43 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
44 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
45 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
46 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
47 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
48 import org.onap.policy.clamp.models.acm.concepts.DeployState;
49 import org.onap.policy.clamp.models.acm.concepts.LockState;
50 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
51 import org.onap.policy.clamp.models.acm.concepts.SubState;
52 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
53 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
54 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
55 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder;
56 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
57 import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
58 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
59 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
60 import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils;
61 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
62 import org.onap.policy.models.base.PfConceptKey;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
64 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
65 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
66
67 /**
68  * Class to perform unit test of {@link AutomationCompositionInstantiationProvider}}.
69  *
70  */
71 class AutomationCompositionInstantiationProviderTest {
72     private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
73     private static final String AC_INSTANTIATION_UPDATE_JSON =
74             "src/test/resources/rest/acm/AutomationCompositionUpdate.json";
75     private static final String AC_MIGRATE_JSON = "src/test/resources/rest/acm/AutomationCompositionMigrate.json";
76
77     private static final String AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
78             "src/test/resources/rest/acm/AutomationCompositionElementsNotFound.json";
79     private static final String AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON =
80             "src/test/resources/rest/acm/AutomationCompositionNotFound.json";
81     private static final String DELETE_BAD_REQUEST = "Automation composition state is still %s";
82
83     private static final String AC_ELEMENT_NAME_NOT_FOUND = """
84             "AutomationComposition" INVALID, item has status INVALID
85               "entry PMSHInstance0AcElementNotFound" INVALID, item has status INVALID
86                 "entry org.onap.domain.pmsh.DCAEMicroservice" INVALID, Not found
87                 "entry org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement" INVALID, Not found
88             """;
89     private static final String AC_DEFINITION_NOT_FOUND = """
90             "AutomationComposition" INVALID, item has status INVALID
91               item "ServiceTemplate" value "%s" INVALID, Commissioned automation composition definition not found
92             """;
93
94     private static final String DO_NOT_MATCH = " do not match with ";
95
96     private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
97
98     @BeforeAll
99     public static void setUpBeforeClass() {
100         serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
101         var jpa =
102                 ProviderUtils.getJpaAndValidate(serviceTemplate, JpaToscaServiceTemplate::new, "toscaServiceTemplate");
103         serviceTemplate = jpa.toAuthorative();
104     }
105
106     @Test
107     void testInstantiationCrud() {
108         var acDefinitionProvider = mock(AcDefinitionProvider.class);
109         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
110         var compositionId = acDefinition.getCompositionId();
111         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
112         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
113         var acProvider = mock(AutomationCompositionProvider.class);
114         var supervisionAcHandler = mock(SupervisionAcHandler.class);
115         var participantProvider = mock(ParticipantProvider.class);
116         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
117                 null, supervisionAcHandler, participantProvider,
118                 CommonTestData.getTestParamaterGroup());
119         var automationCompositionCreate =
120                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
121         automationCompositionCreate.setCompositionId(compositionId);
122         when(acProvider.createAutomationComposition(automationCompositionCreate))
123                 .thenReturn(automationCompositionCreate);
124
125         var instantiationResponse = instantiationProvider.createAutomationComposition(
126                 automationCompositionCreate.getCompositionId(), automationCompositionCreate);
127         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionCreate);
128
129         verify(acProvider).createAutomationComposition(automationCompositionCreate);
130
131         when(acProvider.getAutomationCompositions(compositionId, automationCompositionCreate.getName(),
132                 automationCompositionCreate.getVersion())).thenReturn(List.of(automationCompositionCreate));
133
134         var automationCompositionsGet = instantiationProvider.getAutomationCompositions(compositionId,
135                 automationCompositionCreate.getName(), automationCompositionCreate.getVersion());
136         assertThat(automationCompositionCreate)
137                 .isEqualTo(automationCompositionsGet.getAutomationCompositionList().get(0));
138
139         var automationCompositionUpdate =
140                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
141         automationCompositionUpdate.setCompositionId(compositionId);
142         when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
143                 .thenReturn(automationCompositionUpdate);
144         when(acProvider.updateAutomationComposition(automationCompositionUpdate))
145                 .thenReturn(automationCompositionUpdate);
146
147         instantiationResponse = instantiationProvider.updateAutomationComposition(
148                 automationCompositionUpdate.getCompositionId(), automationCompositionUpdate);
149         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionUpdate);
150
151         verify(acProvider).updateAutomationComposition(automationCompositionUpdate);
152
153         when(acProvider.deleteAutomationComposition(automationCompositionUpdate.getInstanceId()))
154                 .thenReturn(automationCompositionUpdate);
155         doNothing().when(participantProvider).verifyParticipantState(any());
156         instantiationProvider.deleteAutomationComposition(automationCompositionCreate.getCompositionId(),
157                 automationCompositionCreate.getInstanceId());
158
159         verify(supervisionAcHandler).delete(any(), any());
160     }
161
162     @Test
163     void testInstantiationUpdate() {
164         var acDefinitionProvider = mock(AcDefinitionProvider.class);
165         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
166         var compositionId = acDefinition.getCompositionId();
167         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
168
169         var automationCompositionUpdate =
170                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
171         automationCompositionUpdate.setCompositionId(compositionId);
172         automationCompositionUpdate.setInstanceId(UUID.randomUUID());
173         automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
174         automationCompositionUpdate.setLockState(LockState.LOCKED);
175         var acProvider = mock(AutomationCompositionProvider.class);
176         var acmFromDb = new AutomationComposition(automationCompositionUpdate);
177         when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId())).thenReturn(acmFromDb);
178         when(acProvider.updateAutomationComposition(acmFromDb)).thenReturn(acmFromDb);
179
180         var supervisionAcHandler = mock(SupervisionAcHandler.class);
181         var participantProvider = mock(ParticipantProvider.class);
182         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
183                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
184                 CommonTestData.getTestParamaterGroup());
185         var instantiationResponse = instantiationProvider.updateAutomationComposition(
186                 automationCompositionUpdate.getCompositionId(), automationCompositionUpdate);
187
188         verify(supervisionAcHandler).update(any());
189         verify(acProvider).updateAutomationComposition(acmFromDb);
190         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionUpdate);
191
192         var elements = new ArrayList<>(automationCompositionUpdate.getElements().values());
193         automationCompositionUpdate.getElements().clear();
194         for (var element : elements) {
195             element.setId(UUID.randomUUID());
196             automationCompositionUpdate.getElements().put(element.getId(), element);
197         }
198         assertThatThrownBy(
199             () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
200             .hasMessageStartingWith("Element id not present ");
201     }
202
203     @Test
204     void testUpdateBadRequest() {
205         var automationCompositionUpdate =
206                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
207         automationCompositionUpdate.setDeployState(DeployState.DEPLOYING);
208         automationCompositionUpdate.setLockState(LockState.NONE);
209         var acProvider = mock(AutomationCompositionProvider.class);
210         when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
211                 .thenReturn(automationCompositionUpdate);
212
213         var instantiationProvider =
214             new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
215                 new AcInstanceStateResolver(), mock(SupervisionAcHandler.class), mock(ParticipantProvider.class),
216                 mock(AcRuntimeParameterGroup.class));
217
218         var compositionId = automationCompositionUpdate.getCompositionId();
219         assertThatThrownBy(
220                 () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
221                         .hasMessageMatching(
222                                 "Not allowed to UPDATE in the state " + automationCompositionUpdate.getDeployState());
223
224         automationCompositionUpdate.setDeployState(DeployState.UPDATING);
225         automationCompositionUpdate.setLockState(LockState.LOCKED);
226         automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID());
227         assertThatThrownBy(
228                 () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
229                         .hasMessageMatching(
230                                 "Not allowed to MIGRATE in the state " + automationCompositionUpdate.getDeployState());
231     }
232
233     @Test
234     void testUpdateRestartedBadRequest() {
235         var automationCompositionUpdate =
236                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
237         automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
238         automationCompositionUpdate.setLockState(LockState.LOCKED);
239         automationCompositionUpdate.setRestarting(true);
240         var acProvider = mock(AutomationCompositionProvider.class);
241         when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
242                 .thenReturn(automationCompositionUpdate);
243
244         var instantiationProvider =
245                 new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null,
246                         mock(SupervisionAcHandler.class), mock(ParticipantProvider.class),
247                         mock(AcRuntimeParameterGroup.class));
248
249         var compositionId = automationCompositionUpdate.getCompositionId();
250         assertThatThrownBy(
251                 () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
252                         .hasMessageMatching("There is a restarting process, Update not allowed");
253
254         automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID());
255         assertThatThrownBy(
256                 () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
257                 .hasMessageMatching("There is a restarting process, Update not allowed");
258
259         automationCompositionUpdate.setDeployState(DeployState.UNDEPLOYED);
260         automationCompositionUpdate.setLockState(LockState.NONE);
261
262         var instanceId = automationCompositionUpdate.getInstanceId();
263         assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(compositionId, instanceId))
264                 .hasMessageMatching("There is a restarting process, Delete not allowed");
265     }
266
267     @Test
268     void testUpdateCompositionRestartedBadRequest() {
269         var acDefinitionProvider = mock(AcDefinitionProvider.class);
270         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
271         acDefinition.setRestarting(true);
272         var compositionId = acDefinition.getCompositionId();
273         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
274
275         var automationCompositionUpdate =
276                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
277         automationCompositionUpdate.setCompositionId(compositionId);
278         automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
279         automationCompositionUpdate.setLockState(LockState.LOCKED);
280         var acProvider = mock(AutomationCompositionProvider.class);
281         when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
282                 .thenReturn(automationCompositionUpdate);
283         when(acProvider.updateAutomationComposition(automationCompositionUpdate))
284                 .thenReturn(automationCompositionUpdate);
285
286         var supervisionAcHandler = mock(SupervisionAcHandler.class);
287         var participantProvider = mock(ParticipantProvider.class);
288         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
289                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
290                 mock(AcRuntimeParameterGroup.class));
291         var message =
292                   """
293                   "AutomationComposition" INVALID, item has status INVALID
294                     item "ServiceTemplate.restarting" value "true" INVALID, There is a restarting process in composition
295                   """;
296
297         assertThatThrownBy(
298                 () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
299                         .hasMessageMatching(message);
300     }
301
302     @Test
303     void testMigrationAddRemoveElements() {
304         var acDefinitionProvider = mock(AcDefinitionProvider.class);
305         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
306         var compositionId = acDefinition.getCompositionId();
307         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
308         var instanceId = UUID.randomUUID();
309
310         var automationComposition =
311                 InstantiationUtils.getAutomationCompositionFromResource(AC_MIGRATE_JSON, "Crud");
312         automationComposition.setCompositionId(compositionId);
313         automationComposition.setInstanceId(instanceId);
314         automationComposition.setDeployState(DeployState.DEPLOYED);
315         automationComposition.setLockState(LockState.LOCKED);
316         var acProvider = mock(AutomationCompositionProvider.class);
317         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
318                 .thenReturn(automationComposition);
319
320         var automationCompositionTarget = new AutomationComposition(automationComposition);
321         automationCompositionTarget.setInstanceId(instanceId);
322         automationCompositionTarget.setCompositionId(compositionId);
323         // Add a new element
324         var uuid = UUID.randomUUID();
325         var newElement = new AutomationCompositionElement();
326         newElement.setId(uuid);
327         newElement.setDefinition(new ToscaConceptIdentifier(
328                 "org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement", "1.2.3"));
329         newElement.setProperties(Map.of("testVar", "1", "testVar2", "2"));
330         automationCompositionTarget.getElements().put(uuid, newElement);
331
332         //Remove an existing element
333         var elementIdToRemove = UUID.randomUUID();
334         for (var element : automationCompositionTarget.getElements().values()) {
335             if (element.getDefinition().getName()
336                     .equals("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement")) {
337                 elementIdToRemove = element.getId();
338             }
339         }
340         automationCompositionTarget.getElements().remove(elementIdToRemove);
341
342         var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
343         var compositionTargetId = acDefinitionTarget.getCompositionId();
344         automationCompositionTarget.setCompositionTargetId(compositionTargetId);
345         when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
346         when(acProvider.updateAutomationComposition(any())).thenReturn(automationCompositionTarget);
347
348         var supervisionAcHandler = mock(SupervisionAcHandler.class);
349         var participantProvider = mock(ParticipantProvider.class);
350         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
351                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
352                 new AcRuntimeParameterGroup());
353
354         automationCompositionTarget.setPrecheck(true);
355         var preCheckResponse = instantiationProvider.updateAutomationComposition(compositionId,
356                 automationCompositionTarget);
357         verify(supervisionAcHandler).migratePrecheck(any());
358         InstantiationUtils.assertInstantiationResponse(preCheckResponse, automationCompositionTarget);
359
360         automationCompositionTarget.setPrecheck(false);
361         AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED,
362                 SubState.NONE);
363         var instantiationResponse = instantiationProvider.updateAutomationComposition(compositionId,
364                         automationCompositionTarget);
365
366         verify(supervisionAcHandler).migrate(any());
367         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionTarget);
368
369     }
370
371     @Test
372     void testVersionCompatibility() {
373         var acProvider = mock(AutomationCompositionProvider.class);
374         var acDefinitionProvider = mock(AcDefinitionProvider.class);
375         var supervisionAcHandler = mock(SupervisionAcHandler.class);
376         var participantProvider = mock(ParticipantProvider.class);
377         var newDefinition = new PfConceptKey("policy.clamp.element", "1.2.3");
378         var oldDefinition = new PfConceptKey("policy.clamp.element", "2.2.3");
379
380         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
381                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
382                 new AcRuntimeParameterGroup());
383         var instanceId = UUID.randomUUID();
384         assertDoesNotThrow(() -> {
385             instantiationProvider.checkCompatibility(newDefinition, oldDefinition, instanceId);
386         }, "No exception for major version update");
387
388         // Not compatible
389         newDefinition.setName("policy.clamp.newElement");
390         newDefinition.setVersion("2.2.4");
391
392         assertThatThrownBy(() -> instantiationProvider
393                 .checkCompatibility(newDefinition, oldDefinition, instanceId))
394                 .hasMessageContaining("is not compatible");
395     }
396
397     @Test
398     void testInstantiationMigration() {
399         var acDefinitionProvider = mock(AcDefinitionProvider.class);
400         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
401         var compositionId = acDefinition.getCompositionId();
402         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
403
404         var automationComposition =
405                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
406         automationComposition.setCompositionId(compositionId);
407         automationComposition.setDeployState(DeployState.DEPLOYED);
408         automationComposition.setLockState(LockState.LOCKED);
409         automationComposition.setCompositionTargetId(UUID.randomUUID());
410         var acProvider = mock(AutomationCompositionProvider.class);
411         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
412                 .thenReturn(automationComposition);
413         when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
414
415         var supervisionAcHandler = mock(SupervisionAcHandler.class);
416         var participantProvider = mock(ParticipantProvider.class);
417         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
418             new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup());
419
420         assertThatThrownBy(() -> instantiationProvider
421                 .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
422                         .hasMessageMatching(
423                                 String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
424
425         var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
426         var compositionTargetId = acDefinitionTarget.getCompositionId();
427         when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
428
429         automationComposition.setCompositionTargetId(compositionTargetId);
430
431         var instantiationResponse = instantiationProvider
432                 .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition);
433
434         verify(supervisionAcHandler).migrate(any());
435         verify(acProvider).updateAutomationComposition(automationComposition);
436         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition);
437     }
438
439
440     @Test
441     void testInstantiationMigrationPrecheck() {
442         var acDefinitionProvider = mock(AcDefinitionProvider.class);
443         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
444         var compositionId = acDefinition.getCompositionId();
445         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
446
447         var automationComposition =
448             InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
449         automationComposition.setCompositionId(compositionId);
450         automationComposition.setDeployState(DeployState.DEPLOYED);
451         automationComposition.setLockState(LockState.LOCKED);
452         automationComposition.setCompositionTargetId(UUID.randomUUID());
453         automationComposition.setPrecheck(true);
454         var acProvider = mock(AutomationCompositionProvider.class);
455         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
456             .thenReturn(automationComposition);
457         when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
458
459         var supervisionAcHandler = mock(SupervisionAcHandler.class);
460         var acmParticipantProvider = mock(ParticipantProvider.class);
461         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
462             new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup());
463
464         assertThatThrownBy(() -> instantiationProvider
465             .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
466             .hasMessageMatching(
467                 String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
468
469         var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
470         var compositionTargetId = acDefinitionTarget.getCompositionId();
471         when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
472
473         automationComposition.setCompositionTargetId(compositionTargetId);
474
475         var instantiationResponse = instantiationProvider
476             .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition);
477
478         verify(supervisionAcHandler).migratePrecheck(any());
479         verify(acProvider).updateAutomationComposition(automationComposition);
480         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition);
481     }
482
483     @Test
484     void testMigrateBadRequest() {
485         var acDefinitionProvider = mock(AcDefinitionProvider.class);
486         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
487         var compositionId = acDefinition.getCompositionId();
488         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
489
490         var automationComposition =
491                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
492         automationComposition.setCompositionId(compositionId);
493         automationComposition.setDeployState(DeployState.DEPLOYED);
494         automationComposition.setLockState(LockState.LOCKED);
495         var acProvider = mock(AutomationCompositionProvider.class);
496         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
497                 .thenReturn(automationComposition);
498         when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
499
500         var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
501         var compositionTargetId = acDefinitionTarget.getCompositionId();
502         when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
503
504         var acMigrate = new AutomationComposition(automationComposition);
505         acMigrate.setCompositionTargetId(compositionTargetId);
506         automationComposition.setDeployState(DeployState.DEPLOYING);
507
508         var supervisionAcHandler = mock(SupervisionAcHandler.class);
509         var participantProvider = mock(ParticipantProvider.class);
510         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
511                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
512                 new AcRuntimeParameterGroup());
513
514         assertThatThrownBy(() -> instantiationProvider
515                 .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
516                 .hasMessageStartingWith("Not allowed to MIGRATE in the state DEPLOYING");
517     }
518
519     @Test
520     void testMigratePrecheckBadRequest() {
521         var acDefinitionProvider = mock(AcDefinitionProvider.class);
522         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
523         var compositionId = acDefinition.getCompositionId();
524         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
525
526         var automationComposition =
527                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
528         automationComposition.setCompositionId(compositionId);
529         automationComposition.setDeployState(DeployState.DEPLOYED);
530         automationComposition.setLockState(LockState.LOCKED);
531         automationComposition.setPrecheck(true);
532         var acProvider = mock(AutomationCompositionProvider.class);
533         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
534                 .thenReturn(automationComposition);
535         when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
536
537         var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
538         var compositionTargetId = acDefinitionTarget.getCompositionId();
539         when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
540
541         var acMigrate = new AutomationComposition(automationComposition);
542         acMigrate.setCompositionTargetId(compositionTargetId);
543         automationComposition.setDeployState(DeployState.DEPLOYING);
544         automationComposition.setPrecheck(true);
545
546         var supervisionAcHandler = mock(SupervisionAcHandler.class);
547         var participantProvider = mock(ParticipantProvider.class);
548         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
549                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
550                 new AcRuntimeParameterGroup());
551
552         assertThatThrownBy(() -> instantiationProvider
553                 .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
554                 .hasMessageStartingWith("Not allowed to NONE in the state DEPLOYING");
555     }
556
557     @Test
558     void testInstantiationDelete() {
559         var automationComposition =
560                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
561         automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
562         var acProvider = mock(AutomationCompositionProvider.class);
563         var acDefinitionProvider = mock(AcDefinitionProvider.class);
564         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
565         var compositionId = acDefinition.getCompositionId();
566         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
567         automationComposition.setCompositionId(compositionId);
568         var supervisionAcHandler = mock(SupervisionAcHandler.class);
569         var participantProvider = mock(ParticipantProvider.class);
570         var acRuntimeParameterGroup = mock(AcRuntimeParameterGroup.class);
571
572         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
573                 null, supervisionAcHandler, participantProvider, acRuntimeParameterGroup);
574
575         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
576                 .thenReturn(automationComposition);
577
578         var wrongCompositionId = UUID.randomUUID();
579         var instanceId = automationComposition.getInstanceId();
580         assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(wrongCompositionId, instanceId))
581                 .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
582
583         assertThatDeleteThrownBy(automationComposition, DeployState.DEPLOYED, LockState.LOCKED);
584         assertThatDeleteThrownBy(automationComposition, DeployState.DEPLOYING, LockState.NONE);
585         assertThatDeleteThrownBy(automationComposition, DeployState.UNDEPLOYING, LockState.LOCKED);
586         assertThatDeleteThrownBy(automationComposition, DeployState.DELETING, LockState.NONE);
587
588         automationComposition.setDeployState(DeployState.UNDEPLOYED);
589         automationComposition.setLockState(LockState.NONE);
590         when(acProvider.deleteAutomationComposition(instanceId)).thenReturn(automationComposition);
591
592         instantiationProvider.deleteAutomationComposition(compositionId, instanceId);
593         verify(supervisionAcHandler).delete(any(), any());
594     }
595
596     private void assertThatDeleteThrownBy(AutomationComposition automationComposition, DeployState deployState,
597             LockState lockState) {
598         automationComposition.setDeployState(deployState);
599         automationComposition.setLockState(lockState);
600         var acProvider = mock(AutomationCompositionProvider.class);
601         var acDefinitionProvider = mock(AcDefinitionProvider.class);
602         var acRuntimeParamaterGroup = mock(AcRuntimeParameterGroup.class);
603
604         var instantiationProvider =
605                 new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, null,
606                         acRuntimeParamaterGroup);
607
608         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
609                 .thenReturn(automationComposition);
610
611         var compositionId = automationComposition.getCompositionId();
612         var instanceId = automationComposition.getInstanceId();
613         assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(compositionId, instanceId))
614                 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, deployState));
615     }
616
617     @Test
618     void testCreateAutomationCompositions_NoDuplicates() {
619         var acDefinitionProvider = mock(AcDefinitionProvider.class);
620         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
621         var compositionId = acDefinition.getCompositionId();
622         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
623
624         var automationCompositionCreate =
625                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "NoDuplicates");
626         automationCompositionCreate.setCompositionId(compositionId);
627         automationCompositionCreate.setInstanceId(UUID.randomUUID());
628
629         var acProvider = mock(AutomationCompositionProvider.class);
630         when(acProvider.createAutomationComposition(automationCompositionCreate))
631                 .thenReturn(automationCompositionCreate);
632         var participantProvider = mock(ParticipantProvider.class);
633
634         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
635                 null, null, participantProvider,
636                 CommonTestData.getTestParamaterGroup());
637
638         var instantiationResponse = instantiationProvider.createAutomationComposition(
639                 automationCompositionCreate.getCompositionId(), automationCompositionCreate);
640         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionCreate);
641
642         when(acProvider.findAutomationComposition(automationCompositionCreate.getKey().asIdentifier()))
643                 .thenReturn(Optional.of(automationCompositionCreate));
644
645         assertThatThrownBy(
646                 () -> instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate))
647                         .hasMessageMatching(automationCompositionCreate.getKey().asIdentifier() + " already defined");
648     }
649
650     @Test
651     void testCreateAutomationCompositions_CommissionedAcElementNotFound() {
652         var acDefinitionProvider = mock(AcDefinitionProvider.class);
653         var participantProvider = mock(ParticipantProvider.class);
654         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
655         var compositionId = acDefinition.getCompositionId();
656         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
657         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(
658                 AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "AcElementNotFound");
659         automationComposition.setCompositionId(compositionId);
660
661         var acProvider = mock(AutomationCompositionProvider.class);
662         var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null,
663                 participantProvider, CommonTestData.getTestParamaterGroup());
664
665         assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
666                 .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
667
668         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
669                 .thenReturn(automationComposition);
670
671         assertThatThrownBy(() -> provider.updateAutomationComposition(compositionId, automationComposition))
672                 .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
673     }
674
675     @Test
676     void testAcDefinitionNotFound() {
677         var automationComposition = InstantiationUtils
678                 .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
679
680         var acProvider = mock(AutomationCompositionProvider.class);
681         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
682                 .thenReturn(automationComposition);
683         var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
684                 null, null, null,
685                 mock(AcRuntimeParameterGroup.class));
686
687         var compositionId = automationComposition.getCompositionId();
688         assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
689                 .hasMessageMatching(String.format(AC_DEFINITION_NOT_FOUND, compositionId));
690
691         assertThatThrownBy(() -> provider.updateAutomationComposition(compositionId, automationComposition))
692                 .hasMessageMatching(String.format(AC_DEFINITION_NOT_FOUND, compositionId));
693     }
694
695     @Test
696     void testCompositionIdDoNotMatch() {
697         var automationComposition = InstantiationUtils
698                 .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
699
700         var acProvider = mock(AutomationCompositionProvider.class);
701         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
702                 .thenReturn(automationComposition);
703         var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
704                 null, null, null,
705                 mock(AcRuntimeParameterGroup.class));
706
707         var compositionId = automationComposition.getCompositionId();
708         var wrongCompositionId = UUID.randomUUID();
709         assertThatThrownBy(() -> provider.createAutomationComposition(wrongCompositionId, automationComposition))
710                 .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
711
712         assertThatThrownBy(() -> provider.updateAutomationComposition(wrongCompositionId, automationComposition))
713                 .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
714
715         assertThatThrownBy(
716                 () -> provider.getAutomationComposition(wrongCompositionId, automationComposition.getInstanceId()))
717                         .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
718         assertThatThrownBy(() -> provider.compositionInstanceState(wrongCompositionId,
719                 automationComposition.getInstanceId(), new AcInstanceStateUpdate()))
720                         .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
721
722         var compositionTargetId = UUID.randomUUID();
723         automationComposition.setCompositionTargetId(compositionTargetId);
724         assertThatThrownBy(
725                 () -> provider.getAutomationComposition(wrongCompositionId, automationComposition.getInstanceId()))
726                         .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
727
728         var result = provider.getAutomationComposition(compositionTargetId, automationComposition.getInstanceId());
729         assertThat(result).isNotNull();
730     }
731
732     @Test
733     void testCompositionNotPrimed() {
734         var acDefinitionProvider = mock(AcDefinitionProvider.class);
735         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.COMMISSIONED);
736         var compositionId = acDefinition.getCompositionId();
737         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
738         var acProvider = mock(AutomationCompositionProvider.class);
739         var provider =
740                 new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, null,
741                         null);
742
743         var automationComposition =
744                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
745         automationComposition.setCompositionId(compositionId);
746         var message = """
747                       "AutomationComposition" INVALID, item has status INVALID
748                         item "ServiceTemplate.state" value "COMMISSIONED" INVALID, Commissioned automation composition \
749                       definition not primed
750                       """;
751
752         assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
753                 .hasMessageMatching(message);
754     }
755
756     @Test
757     void testCompositionInstanceState() {
758         var acDefinitionProvider = mock(AcDefinitionProvider.class);
759         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.COMMISSIONED);
760         var compositionId = acDefinition.getCompositionId();
761         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
762
763         var automationComposition = InstantiationUtils
764                 .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
765         var instanceId = UUID.randomUUID();
766         automationComposition.setCompositionId(compositionId);
767         automationComposition.setInstanceId(instanceId);
768         var acProvider = mock(AutomationCompositionProvider.class);
769         when(acProvider.getAutomationComposition(instanceId)).thenReturn(automationComposition);
770
771         var supervisionAcHandler = mock(SupervisionAcHandler.class);
772         var participantProvider = mock(ParticipantProvider.class);
773         var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
774                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
775                 mock(AcRuntimeParameterGroup.class));
776
777         var acInstanceStateUpdate = new AcInstanceStateUpdate();
778         acInstanceStateUpdate.setDeployOrder(DeployOrder.DEPLOY);
779         acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
780         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
781         verify(supervisionAcHandler).deploy(any(AutomationComposition.class),
782                 any(AutomationCompositionDefinition.class));
783
784         automationComposition.setDeployState(DeployState.DEPLOYED);
785         automationComposition.setLockState(LockState.LOCKED);
786         acInstanceStateUpdate.setDeployOrder(DeployOrder.UNDEPLOY);
787         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
788         verify(supervisionAcHandler).undeploy(any(AutomationComposition.class),
789                 any(AutomationCompositionDefinition.class));
790
791         automationComposition.setDeployState(DeployState.DEPLOYED);
792         automationComposition.setLockState(LockState.LOCKED);
793         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
794         acInstanceStateUpdate.setLockOrder(LockOrder.UNLOCK);
795         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
796         verify(supervisionAcHandler).unlock(any(AutomationComposition.class),
797                 any(AutomationCompositionDefinition.class));
798
799         automationComposition.setDeployState(DeployState.DEPLOYED);
800         automationComposition.setLockState(LockState.UNLOCKED);
801         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
802         acInstanceStateUpdate.setLockOrder(LockOrder.LOCK);
803         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
804         verify(supervisionAcHandler).lock(any(AutomationComposition.class), any(AutomationCompositionDefinition.class));
805
806         automationComposition.setDeployState(DeployState.UNDEPLOYED);
807         automationComposition.setLockState(LockState.NONE);
808         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
809         acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
810         acInstanceStateUpdate.setSubOrder(SubOrder.PREPARE);
811         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
812         verify(supervisionAcHandler).prepare(any(AutomationComposition.class));
813
814         automationComposition.setDeployState(DeployState.DEPLOYED);
815         automationComposition.setLockState(LockState.LOCKED);
816         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
817         acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
818         acInstanceStateUpdate.setSubOrder(SubOrder.REVIEW);
819         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
820         verify(supervisionAcHandler).review(any(AutomationComposition.class));
821     }
822 }