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