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