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