ec61f886e9e872aa397c6615db64de46f3e7aa38
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021-2024 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.acm.participant.intermediary.handler;
22
23 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.Mockito.clearInvocations;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.times;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.UUID;
37 import org.junit.jupiter.api.Test;
38 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
39 import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData;
40 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
41 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
42 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
43 import org.onap.policy.clamp.models.acm.concepts.DeployState;
44 import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
45 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy;
46 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck;
47 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
48 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange;
49 import org.onap.policy.clamp.models.acm.messages.kafka.participant.PropertiesUpdate;
50 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
51 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
53
54 class AutomationCompositionHandlerTest {
55
56     @Test
57     void handleAutomationCompositionStateChangeNullTest() {
58         var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
59         var cacheProvider = mock(CacheProvider.class);
60         var ach =
61                 new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, mock(ThreadHandler.class));
62
63         var automationCompositionStateChange = new AutomationCompositionStateChange();
64         assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(automationCompositionStateChange));
65
66         automationCompositionStateChange.setAutomationCompositionId(UUID.randomUUID());
67         automationCompositionStateChange.setDeployOrderedState(DeployOrder.DELETE);
68         assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(automationCompositionStateChange));
69         verify(participantMessagePublisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class));
70
71         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
72         automationCompositionStateChange.setAutomationCompositionId(automationComposition.getInstanceId());
73         when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
74                 .thenReturn(automationComposition);
75         automationCompositionStateChange.setDeployOrderedState(DeployOrder.UPDATE);
76         assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(automationCompositionStateChange));
77     }
78
79     @Test
80     void handleAutomationCompositionStateChangeUndeployTest() {
81         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
82         var cacheProvider = mock(CacheProvider.class);
83         when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
84                 .thenReturn(automationComposition);
85         when(cacheProvider.getCommonProperties(any(UUID.class), any(UUID.class))).thenReturn(Map.of());
86
87         var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
88         var listener = mock(ThreadHandler.class);
89         var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener);
90         Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
91         for (var element : automationComposition.getElements().values()) {
92             map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
93         }
94         when(cacheProvider.getAcElementsDefinitions())
95             .thenReturn(Map.of(automationComposition.getCompositionId(), map));
96         var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(),
97             automationComposition.getInstanceId(), DeployOrder.UNDEPLOY, LockOrder.NONE);
98
99         ach.handleAutomationCompositionStateChange(automationCompositionStateChange);
100         verify(listener, times(automationComposition.getElements().size())).undeploy(any(), any(), any());
101         for (var element : automationComposition.getElements().values()) {
102             assertEquals(DeployState.UNDEPLOYING, element.getDeployState());
103         }
104     }
105
106     @Test
107     void handleAutomationCompositionStateChangeDeleteTest() {
108         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
109         var cacheProvider = mock(CacheProvider.class);
110         when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
111                 .thenReturn(automationComposition);
112         when(cacheProvider.getCommonProperties(any(UUID.class), any(UUID.class))).thenReturn(Map.of());
113
114         var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
115         var listener = mock(ThreadHandler.class);
116         var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener);
117         Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
118         for (var element : automationComposition.getElements().values()) {
119             map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
120         }
121         when(cacheProvider.getAcElementsDefinitions())
122             .thenReturn(Map.of(automationComposition.getCompositionId(), map));
123         var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(),
124             automationComposition.getInstanceId(), DeployOrder.DELETE, LockOrder.NONE);
125         ach.handleAutomationCompositionStateChange(automationCompositionStateChange);
126         verify(listener, times(automationComposition.getElements().size())).delete(any(), any(), any());
127         for (var element : automationComposition.getElements().values()) {
128             assertEquals(DeployState.DELETING, element.getDeployState());
129         }
130     }
131
132     @Test
133     void handleAcPropertyUpdateTest() {
134         var cacheProvider = mock(CacheProvider.class);
135         var listener = mock(ThreadHandler.class);
136         var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
137         var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener);
138
139         var updateMsg = new PropertiesUpdate();
140         assertDoesNotThrow(() -> ach.handleAcPropertyUpdate(updateMsg));
141
142         updateMsg.setParticipantId(CommonTestData.getParticipantId());
143         when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
144         var participantDeploy = new ParticipantDeploy();
145         participantDeploy.setParticipantId(CommonTestData.getParticipantId());
146         updateMsg.getParticipantUpdatesList().add(participantDeploy);
147
148         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
149         updateMsg.setAutomationCompositionId(automationComposition.getInstanceId());
150         when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
151                 .thenReturn(automationComposition);
152         var acElementDeploy = new AcElementDeploy();
153         acElementDeploy.setProperties(Map.of());
154         acElementDeploy.setId(automationComposition.getElements().values().iterator().next().getId());
155         participantDeploy.getAcElementList().add(acElementDeploy);
156
157         Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
158         for (var element : automationComposition.getElements().values()) {
159             map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
160         }
161         when(cacheProvider.getAcElementsDefinitions())
162             .thenReturn(Map.of(automationComposition.getCompositionId(), map));
163         ach.handleAcPropertyUpdate(updateMsg);
164         verify(listener).update(any(), any(), any(), any());
165     }
166
167     @Test
168     void handleAutomationCompositionDeployTest() {
169         var cacheProvider = mock(CacheProvider.class);
170         var listener = mock(ThreadHandler.class);
171         var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
172         var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener);
173
174         var deployMsg = new AutomationCompositionDeploy();
175         assertDoesNotThrow(() -> ach.handleAutomationCompositionDeploy(deployMsg));
176
177         deployMsg.setParticipantId(CommonTestData.getParticipantId());
178         when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
179         var participantDeploy = new ParticipantDeploy();
180         participantDeploy.setParticipantId(CommonTestData.getParticipantId());
181         deployMsg.getParticipantUpdatesList().add(participantDeploy);
182
183         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
184         deployMsg.setAutomationCompositionId(automationComposition.getInstanceId());
185         when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
186                 .thenReturn(automationComposition);
187         Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
188         for (var element : automationComposition.getElements().values()) {
189             var acElementDeploy = new AcElementDeploy();
190             acElementDeploy.setProperties(Map.of());
191             acElementDeploy.setId(element.getId());
192             participantDeploy.getAcElementList().add(acElementDeploy);
193             map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
194         }
195         when(cacheProvider.getAcElementsDefinitions())
196             .thenReturn(Map.of(automationComposition.getCompositionId(), map));
197
198         ach.handleAutomationCompositionDeploy(deployMsg);
199         verify(listener, times(automationComposition.getElements().size())).deploy(any(), any(), any());
200     }
201
202     @Test
203     void handleMigrationNullTest() {
204         var ach = new AutomationCompositionHandler(
205                 mock(CacheProvider.class), mock(ParticipantMessagePublisher.class), mock(ThreadHandler.class));
206         var migrationMsg = new AutomationCompositionMigration();
207         migrationMsg.setStage(0);
208         assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg));
209         migrationMsg.setAutomationCompositionId(UUID.randomUUID());
210         migrationMsg.setCompositionTargetId(UUID.randomUUID());
211         assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg));
212     }
213
214     @Test
215     void handleAutomationCompositionMigrationTest() {
216         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
217         automationComposition.setCompositionId(UUID.randomUUID());
218         automationComposition.setInstanceId(UUID.randomUUID());
219         automationComposition.setCompositionTargetId(UUID.randomUUID());
220         var definitions =
221                 CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition);
222         var participantDeploy =
223                 CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition);
224
225         var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(),
226                 automationComposition.getInstanceId(), definitions,
227                 automationComposition.getCompositionTargetId(), definitions);
228
229         testMigration(cacheProvider, automationComposition, 0, automationComposition.getElements().size());
230     }
231
232     @Test
233     void handleMigrationAddRemoveTest() {
234         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
235         automationComposition.setCompositionId(UUID.randomUUID());
236         automationComposition.setInstanceId(UUID.randomUUID());
237
238         var acMigrate = new AutomationComposition(automationComposition);
239         acMigrate.setCompositionTargetId(UUID.randomUUID());
240
241         // replacing first element with new one
242         var element = acMigrate.getElements().values().iterator().next();
243         element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0"));
244         element.setId(UUID.randomUUID());
245
246         var migrateDefinitions =
247                 CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate);
248
249         var participantDeploy =
250                 CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition);
251         var definitions =
252                 CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition);
253         var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(),
254                 automationComposition.getInstanceId(), definitions,
255                 acMigrate.getCompositionTargetId(), migrateDefinitions);
256
257         testMigration(cacheProvider, acMigrate, 0, acMigrate.getElements().size() + 1);
258     }
259
260     @Test
261     void handleAcMigrationStageTest() {
262         var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
263         automationComposition.setCompositionId(UUID.randomUUID());
264         automationComposition.setInstanceId(UUID.randomUUID());
265
266         var acMigrate = new AutomationComposition(automationComposition);
267         acMigrate.setCompositionTargetId(UUID.randomUUID());
268
269         // replacing first element with new one
270         var element = acMigrate.getElements().values().iterator().next();
271         element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4"));
272         element.setId(UUID.randomUUID());
273
274         // replacing definition version
275         acMigrate.getElements().values().forEach(el -> el.setDefinition(
276                 new ToscaConceptIdentifier(el.getDefinition().getName(), "1.2.4")));
277
278         var migrateDefinitions =
279                 CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate);
280
281         migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate()
282                 .setProperties(Map.of("stage", List.of(0, 1))));
283
284         var participantDeploy =
285                 CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition);
286         var definitions =
287                 CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition);
288         var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(),
289                 automationComposition.getInstanceId(), definitions,
290                 acMigrate.getCompositionTargetId(), migrateDefinitions);
291
292         // scenario 1,2
293         migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate()
294                 .setProperties(Map.of("stage", List.of(1, 2))));
295
296         // expected the element deleted
297         testMigration(cacheProvider, acMigrate, 0, 1);
298
299         // expected 4 elements from stage 1
300         testMigration(cacheProvider, acMigrate, 1, 4);
301
302         // scenario 0,2
303         cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(),
304                 automationComposition.getInstanceId(), definitions,
305                 acMigrate.getCompositionTargetId(), migrateDefinitions);
306
307         migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate()
308                 .setProperties(Map.of("stage", List.of(0, 2))));
309
310         // expected the element deleted + 4 elements from stage 0
311         testMigration(cacheProvider, acMigrate, 0, 5);
312
313         // expected 0 elements
314         testMigration(cacheProvider, acMigrate, 1, 0);
315     }
316
317     private CacheProvider createCacheProvider(ParticipantDeploy participantDeploy,
318             UUID compositionId, UUID instanceId, List<AutomationCompositionElementDefinition> definitions,
319             UUID compositionTargetId, List<AutomationCompositionElementDefinition> migrateDefinitions) {
320         var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters());
321         cacheProvider.addElementDefinition(compositionId, definitions);
322         cacheProvider.initializeAutomationComposition(compositionId, instanceId, participantDeploy);
323         cacheProvider.addElementDefinition(compositionTargetId, migrateDefinitions);
324         return cacheProvider;
325     }
326
327     private void testMigration(CacheProvider cacheProvider, AutomationComposition acMigrate,
328             int stage, int expectedMigrated) {
329         var migrationMsg = new AutomationCompositionMigration();
330         migrationMsg.setStage(stage);
331         migrationMsg.setCompositionId(acMigrate.getCompositionId());
332         migrationMsg.setAutomationCompositionId(acMigrate.getInstanceId());
333         migrationMsg.setCompositionTargetId(acMigrate.getCompositionTargetId());
334         var participantMigrate = CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), acMigrate);
335         migrationMsg.setParticipantUpdatesList(List.of(participantMigrate));
336         var listener = mock(ThreadHandler.class);
337
338         clearInvocations();
339         var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener);
340         ach.handleAutomationCompositionMigration(migrationMsg);
341         verify(listener, times(expectedMigrated)).migrate(any(), any(), any(), any(), any(), anyInt());
342     }
343
344 }