759b6eec0b4f475e0e136334c4cc989b1251fc0c
[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
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 = "Not valid order DELETE;";
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                 new AcInstanceStateResolver(), 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                 new AcInstanceStateResolver(), 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         automationComposition.setDeployState(DeployState.UNDEPLOYED);
535         automationComposition.setLockState(LockState.NONE);
536         when(acProvider.deleteAutomationComposition(instanceId)).thenReturn(automationComposition);
537         instantiationProvider.deleteAutomationComposition(compositionId, instanceId);
538         verify(supervisionAcHandler).delete(any(), any());
539     }
540
541     @Test
542     void testInstantiationDeleteError() {
543         var automationComposition =
544                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
545         automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
546         assertThatDeleteThrownBy(automationComposition, DeployState.DEPLOYED, LockState.LOCKED);
547         assertThatDeleteThrownBy(automationComposition, DeployState.DEPLOYING, LockState.NONE);
548         assertThatDeleteThrownBy(automationComposition, DeployState.UNDEPLOYING, LockState.LOCKED);
549         assertThatDeleteThrownBy(automationComposition, DeployState.DELETING, LockState.NONE);
550     }
551
552     private void assertThatDeleteThrownBy(AutomationComposition automationComposition, DeployState deployState,
553             LockState lockState) {
554         automationComposition.setDeployState(deployState);
555         automationComposition.setLockState(lockState);
556         var acProvider = mock(AutomationCompositionProvider.class);
557         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
558                 .thenReturn(automationComposition);
559         var acDefinitionProvider = mock(AcDefinitionProvider.class);
560         var acRuntimeParamaterGroup = mock(AcRuntimeParameterGroup.class);
561
562         var instantiationProvider =
563                 new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
564                         new AcInstanceStateResolver(), null, mock(ParticipantProvider.class),
565                         acRuntimeParamaterGroup, null);
566
567         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
568         var compositionId = acDefinition.getCompositionId();
569         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
570         automationComposition.setCompositionId(compositionId);
571
572         var instanceId = automationComposition.getInstanceId();
573         assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(compositionId, instanceId))
574                 .hasMessageStartingWith(String.format(DELETE_BAD_REQUEST));
575     }
576
577     @Test
578     void testCreateAutomationCompositions_NoDuplicates() {
579         var acDefinitionProvider = mock(AcDefinitionProvider.class);
580         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
581         var compositionId = acDefinition.getCompositionId();
582         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
583
584         var automationCompositionCreate =
585                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "NoDuplicates");
586         automationCompositionCreate.setCompositionId(compositionId);
587         automationCompositionCreate.setInstanceId(UUID.randomUUID());
588
589         var acProvider = mock(AutomationCompositionProvider.class);
590         when(acProvider.createAutomationComposition(automationCompositionCreate))
591                 .thenReturn(automationCompositionCreate);
592         var participantProvider = mock(ParticipantProvider.class);
593         var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
594
595         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
596                 null, null, participantProvider,
597                 CommonTestData.getTestParamaterGroup(), encryptionUtils);
598
599         var instantiationResponse = instantiationProvider.createAutomationComposition(
600                 automationCompositionCreate.getCompositionId(), automationCompositionCreate);
601         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionCreate);
602
603         when(acProvider.findAutomationComposition(automationCompositionCreate.getKey().asIdentifier()))
604                 .thenReturn(Optional.of(automationCompositionCreate));
605
606         assertThatThrownBy(
607                 () -> instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate))
608                         .hasMessageMatching(automationCompositionCreate.getKey().asIdentifier() + " already defined");
609     }
610
611     @Test
612     void testCreateAutomationCompositions_CommissionedAcElementNotFound() {
613         var acDefinitionProvider = mock(AcDefinitionProvider.class);
614         var participantProvider = mock(ParticipantProvider.class);
615         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
616         var compositionId = acDefinition.getCompositionId();
617         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
618         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(
619                 AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "AcElementNotFound");
620         automationComposition.setCompositionId(compositionId);
621
622         var acProvider = mock(AutomationCompositionProvider.class);
623         var encryptionUtils = mock(EncryptionUtils.class);
624         var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null,
625                 participantProvider, CommonTestData.getTestParamaterGroup(), encryptionUtils);
626
627         assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
628                 .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
629
630         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
631                 .thenReturn(automationComposition);
632
633         assertThatThrownBy(() -> provider.updateAutomationComposition(compositionId, automationComposition))
634                 .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
635     }
636
637     @Test
638     void testAcDefinitionNotFound() {
639         var automationComposition = InstantiationUtils
640                 .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
641
642         var acProvider = mock(AutomationCompositionProvider.class);
643         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
644                 .thenReturn(automationComposition);
645         var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
646                 null, null, null,
647                 mock(AcRuntimeParameterGroup.class), null);
648
649         var compositionId = automationComposition.getCompositionId();
650         assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
651                 .hasMessageMatching(String.format(AC_DEFINITION_NOT_FOUND, compositionId));
652
653         assertThatThrownBy(() -> provider.updateAutomationComposition(compositionId, automationComposition))
654                 .hasMessageMatching(String.format(AC_DEFINITION_NOT_FOUND, compositionId));
655     }
656
657     @Test
658     void testCompositionIdDoNotMatch() {
659         var automationComposition = InstantiationUtils
660                 .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
661
662         var acProvider = mock(AutomationCompositionProvider.class);
663         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
664                 .thenReturn(automationComposition);
665         var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
666                 null, null, null,
667                 mock(AcRuntimeParameterGroup.class), null);
668
669         var compositionId = automationComposition.getCompositionId();
670         var wrongCompositionId = UUID.randomUUID();
671         assertThatThrownBy(() -> provider.createAutomationComposition(wrongCompositionId, automationComposition))
672                 .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
673
674         assertThatThrownBy(() -> provider.updateAutomationComposition(wrongCompositionId, automationComposition))
675                 .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
676
677         assertThatThrownBy(
678                 () -> provider.getAutomationComposition(wrongCompositionId, automationComposition.getInstanceId()))
679                         .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
680         assertThatThrownBy(() -> provider.compositionInstanceState(wrongCompositionId,
681                 automationComposition.getInstanceId(), new AcInstanceStateUpdate()))
682                         .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
683
684         var compositionTargetId = UUID.randomUUID();
685         automationComposition.setCompositionTargetId(compositionTargetId);
686         assertThatThrownBy(
687                 () -> provider.getAutomationComposition(wrongCompositionId, automationComposition.getInstanceId()))
688                         .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
689
690         var result = provider.getAutomationComposition(compositionTargetId, automationComposition.getInstanceId());
691         assertThat(result).isNotNull();
692     }
693
694     @Test
695     void testCompositionNotPrimed() {
696         var acDefinitionProvider = mock(AcDefinitionProvider.class);
697         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.COMMISSIONED);
698         var compositionId = acDefinition.getCompositionId();
699         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
700         var acProvider = mock(AutomationCompositionProvider.class);
701         var provider =
702                 new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, null,
703                         null, null);
704
705         var automationComposition =
706                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
707         automationComposition.setCompositionId(compositionId);
708         var message = """
709                       "AutomationComposition" INVALID, item has status INVALID
710                         item "ServiceTemplate.state" value "COMMISSIONED" INVALID, Commissioned automation composition \
711                       definition not primed
712                       """;
713
714         assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
715                 .hasMessageMatching(message);
716     }
717
718     @Test
719     void testCompositionInstanceState() {
720         var acDefinitionProvider = mock(AcDefinitionProvider.class);
721         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.COMMISSIONED);
722         var compositionId = acDefinition.getCompositionId();
723         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
724
725         var automationComposition = InstantiationUtils
726                 .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
727         var instanceId = UUID.randomUUID();
728         automationComposition.setCompositionId(compositionId);
729         automationComposition.setInstanceId(instanceId);
730         var acProvider = mock(AutomationCompositionProvider.class);
731         when(acProvider.getAutomationComposition(instanceId)).thenReturn(automationComposition);
732
733         var supervisionAcHandler = mock(SupervisionAcHandler.class);
734         var participantProvider = mock(ParticipantProvider.class);
735         var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
736                 new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
737                 mock(AcRuntimeParameterGroup.class), null);
738
739         var acInstanceStateUpdate = new AcInstanceStateUpdate();
740         acInstanceStateUpdate.setDeployOrder(DeployOrder.DEPLOY);
741         acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
742         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
743         verify(supervisionAcHandler).deploy(any(AutomationComposition.class),
744                 any(AutomationCompositionDefinition.class));
745
746         automationComposition.setDeployState(DeployState.DEPLOYED);
747         automationComposition.setLockState(LockState.LOCKED);
748         acInstanceStateUpdate.setDeployOrder(DeployOrder.UNDEPLOY);
749         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
750         verify(supervisionAcHandler).undeploy(any(AutomationComposition.class),
751                 any(AutomationCompositionDefinition.class));
752
753         automationComposition.setDeployState(DeployState.DEPLOYED);
754         automationComposition.setLockState(LockState.LOCKED);
755         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
756         acInstanceStateUpdate.setLockOrder(LockOrder.UNLOCK);
757         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
758         verify(supervisionAcHandler).unlock(any(AutomationComposition.class),
759                 any(AutomationCompositionDefinition.class));
760
761         automationComposition.setDeployState(DeployState.DEPLOYED);
762         automationComposition.setLockState(LockState.UNLOCKED);
763         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
764         acInstanceStateUpdate.setLockOrder(LockOrder.LOCK);
765         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
766         verify(supervisionAcHandler).lock(any(AutomationComposition.class), any(AutomationCompositionDefinition.class));
767
768         automationComposition.setDeployState(DeployState.UNDEPLOYED);
769         automationComposition.setLockState(LockState.NONE);
770         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
771         acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
772         acInstanceStateUpdate.setSubOrder(SubOrder.PREPARE);
773         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
774         verify(supervisionAcHandler).prepare(any(AutomationComposition.class), any());
775
776         automationComposition.setDeployState(DeployState.DEPLOYED);
777         automationComposition.setLockState(LockState.LOCKED);
778         acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
779         acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
780         acInstanceStateUpdate.setSubOrder(SubOrder.REVIEW);
781         provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
782         verify(supervisionAcHandler).review(any(AutomationComposition.class));
783     }
784 }