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