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