67ac0774391c6aae6756dd277b798a930b0f3c88
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
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.runtime.supervision;
22
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.clearInvocations;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.when;
30
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Optional;
34 import java.util.Set;
35 import java.util.UUID;
36 import org.junit.jupiter.api.Test;
37 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
38 import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
39 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
40 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRegisterAckPublisher;
41 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
42 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
43 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
44 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
45 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
46 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
47 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
48 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionRollback;
49 import org.onap.policy.clamp.models.acm.concepts.DeployState;
50 import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
51 import org.onap.policy.clamp.models.acm.concepts.Participant;
52 import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
53 import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica;
54 import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
55 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantDeregister;
56 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegister;
57 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantReqSync;
58 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus;
59 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
60 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
61 import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider;
62 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
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.authorative.concepts.ToscaTopologyTemplate;
66
67 class SupervisionParticipantHandlerTest {
68
69     private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
70
71     @Test
72     void testHandleParticipantDeregister() {
73         var participantDeregisterMessage = new ParticipantDeregister();
74         participantDeregisterMessage.setMessageId(UUID.randomUUID());
75         participantDeregisterMessage.setParticipantId(CommonTestData.getParticipantId());
76         var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class);
77         var participantProvider = mock(ParticipantProvider.class);
78         var handler =
79                 new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class),
80                         participantDeregisterAckPublisher, mock(AutomationCompositionProvider.class),
81                         mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class),
82                         mock(MessageProvider.class), mock(EncryptionUtils.class));
83
84         handler.handleParticipantMessage(participantDeregisterMessage);
85         verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId());
86
87         clearInvocations(participantDeregisterAckPublisher);
88         var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId());
89         participantDeregisterMessage.setReplicaId(replica.getReplicaId());
90         when(participantProvider.findParticipantReplica(replica.getReplicaId()))
91                 .thenReturn(Optional.of(replica));
92         handler.handleParticipantMessage(participantDeregisterMessage);
93         verify(participantProvider).deleteParticipantReplica(CommonTestData.getReplicaId());
94         verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId());
95     }
96
97     @Test
98     void testHandleParticipantRegister() {
99         var participantRegisterMessage = new ParticipantRegister();
100         participantRegisterMessage.setMessageId(UUID.randomUUID());
101         participantRegisterMessage.setParticipantId(CommonTestData.getParticipantId());
102         var supportedElementType = CommonTestData.createParticipantSupportedElementType();
103         participantRegisterMessage.setParticipantSupportedElementType(List.of(supportedElementType));
104
105         var participantProvider = mock(ParticipantProvider.class);
106         var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
107         var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher,
108                 mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionProvider.class),
109                 mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class),
110                 mock(MessageProvider.class), mock(EncryptionUtils.class));
111         handler.handleParticipantMessage(participantRegisterMessage);
112
113         verify(participantProvider).saveParticipant(any());
114         verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(),
115                 CommonTestData.getParticipantId(), null);
116     }
117
118     @Test
119     void testHandleParticipantSyncRestart() {
120         var participantRegisterMessage = new ParticipantRegister();
121         participantRegisterMessage.setMessageId(UUID.randomUUID());
122         var participantId = CommonTestData.getParticipantId();
123         participantRegisterMessage.setParticipantId(participantId);
124         var replicaId = CommonTestData.getReplicaId();
125         participantRegisterMessage.setReplicaId(replicaId);
126         var supportedElementType = CommonTestData.createParticipantSupportedElementType();
127         participantRegisterMessage.setParticipantSupportedElementType(List.of(supportedElementType));
128
129         var participant = new Participant();
130         var replica = new ParticipantReplica();
131         replica.setReplicaId(replicaId);
132         replica.setParticipantState(ParticipantState.OFF_LINE);
133         participant.setParticipantId(participantId);
134         participant.getReplicas().put(replica.getReplicaId(), replica);
135         var participantProvider = mock(ParticipantProvider.class);
136         when(participantProvider.findParticipant(participantId)).thenReturn(Optional.of(participant));
137         when(participantProvider.findParticipantReplica(replicaId)).thenReturn(Optional.of(replica));
138         var compositionId = UUID.randomUUID();
139         var composition2Id = UUID.randomUUID();
140         when(participantProvider.getCompositionIds(participantId)).thenReturn(Set.of(compositionId, composition2Id));
141
142         var acDefinitionProvider = mock(AcDefinitionProvider.class);
143         var acDefinition = new AutomationCompositionDefinition();
144         acDefinition.setState(AcTypeState.COMMISSIONED);
145         acDefinition.setCompositionId(composition2Id);
146         when(acDefinitionProvider.getAcDefinition(composition2Id)).thenReturn(acDefinition);
147
148         acDefinition = new AutomationCompositionDefinition();
149         acDefinition.setCompositionId(compositionId);
150         acDefinition.setState(AcTypeState.PRIMED);
151         var nodeTemplateState = new NodeTemplateState();
152         nodeTemplateState.setParticipantId(participantId);
153         acDefinition.setElementStateMap(Map.of("code", nodeTemplateState));
154         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
155
156         var automationComposition =
157                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
158         automationComposition.getElements().values().iterator().next().setParticipantId(participantId);
159         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
160         when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
161                 .thenReturn(List.of(automationComposition));
162
163         var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
164         var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
165         var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher,
166                 mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider, acDefinitionProvider,
167                 participantSyncPublisher, mock(MessageProvider.class), mock(EncryptionUtils.class));
168         handler.handleParticipantMessage(participantRegisterMessage);
169
170         verify(participantRegisterAckPublisher)
171                 .send(participantRegisterMessage.getMessageId(), participantId, replicaId);
172         verify(acDefinitionProvider, times(0)).updateAcDefinition(any(AutomationCompositionDefinition.class),
173                 eq(CommonTestData.TOSCA_COMP_NAME));
174         verify(participantSyncPublisher)
175                 .sendRestartMsg(any(), any(), any(AutomationCompositionDefinition.class), any());
176     }
177
178     @Test
179     void testHandleParticipantStatusWithInstanceOutProperties() {
180         var participantStatusMessage = createParticipantStatus();
181         participantStatusMessage.setAutomationCompositionInfoList(List.of(new AutomationCompositionInfo()));
182         participantStatusMessage.setCompositionId(UUID.randomUUID());
183
184         var participantProvider = mock(ParticipantProvider.class);
185         var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
186         when(participantProvider.findParticipant(CommonTestData.getParticipantId()))
187                 .thenReturn(Optional.of(participant));
188         var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId());
189         participantStatusMessage.setReplicaId(replica.getReplicaId());
190         when(participantProvider.findParticipantReplica(replica.getReplicaId()))
191                 .thenReturn(Optional.of(replica));
192
193         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
194         var messageProvider = mock(MessageProvider.class);
195         var acDefinitionProvider = mock(AcDefinitionProvider.class);
196         var handler = new SupervisionParticipantHandler(participantProvider,
197                 mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
198                 automationCompositionProvider, acDefinitionProvider, mock(ParticipantSyncPublisher.class),
199                 messageProvider, mock(EncryptionUtils.class));
200         handler.handleParticipantMessage(participantStatusMessage);
201
202         verify(messageProvider).saveInstanceOutProperties(any(ParticipantStatus.class));
203     }
204
205     @Test
206     void testHandleParticipantStatusWithCompositionOutProperties() {
207         var participantStatusMessage = createParticipantStatus();
208         var participantDefinition = new ParticipantDefinition();
209         participantStatusMessage.setParticipantDefinitionUpdates(List.of(participantDefinition));
210         participantDefinition.setParticipantId(participantStatusMessage.getParticipantId());
211         var acElementDefinition = new AutomationCompositionElementDefinition();
212         acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("code", "1.0.0"));
213         participantDefinition.setAutomationCompositionElementDefinitionList(List.of(acElementDefinition));
214
215         var compositionId = UUID.randomUUID();
216         participantStatusMessage.setCompositionId(compositionId);
217         var acDefinition = new AutomationCompositionDefinition();
218         acDefinition.setState(AcTypeState.COMMISSIONED);
219         acDefinition.setCompositionId(compositionId);
220         var nodeTemplateState = new NodeTemplateState();
221         acDefinition.setElementStateMap(
222                 Map.of(acElementDefinition.getAcElementDefinitionId().getName(), nodeTemplateState));
223         var acDefinitionProvider = mock(AcDefinitionProvider.class);
224         var messageProvider = mock(MessageProvider.class);
225         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
226         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
227
228         var participantProvider = mock(ParticipantProvider.class);
229         var handler = new SupervisionParticipantHandler(participantProvider,
230                 mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
231                 mock(AutomationCompositionProvider.class), acDefinitionProvider, mock(ParticipantSyncPublisher.class),
232                 messageProvider, mock(EncryptionUtils.class));
233         handler.handleParticipantMessage(participantStatusMessage);
234         verify(messageProvider).saveCompositionOutProperties(any(), any());
235     }
236
237     @Test
238     void testAcOutPropertiesNotValid() {
239         var participantStatusMessage = createParticipantStatus();
240         var participantDefinition = new ParticipantDefinition();
241         participantStatusMessage.setParticipantDefinitionUpdates(List.of(participantDefinition));
242         participantDefinition.setParticipantId(participantStatusMessage.getParticipantId());
243         var acElementDefinition = new AutomationCompositionElementDefinition();
244         acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("code", "1.0.0"));
245         participantDefinition.setAutomationCompositionElementDefinitionList(List.of(acElementDefinition));
246
247         var compositionId = UUID.randomUUID();
248         participantStatusMessage.setCompositionId(compositionId);
249         var acDefinitionProvider = mock(AcDefinitionProvider.class);
250         var messageProvider = mock(MessageProvider.class);
251         var participantProvider = mock(ParticipantProvider.class);
252         var handler = new SupervisionParticipantHandler(participantProvider,
253                 mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
254                 mock(AutomationCompositionProvider.class), acDefinitionProvider, mock(ParticipantSyncPublisher.class),
255                 messageProvider, mock(EncryptionUtils.class));
256         handler.handleParticipantMessage(participantStatusMessage);
257         verify(messageProvider, times(0)).saveCompositionOutProperties(any(), any());
258     }
259
260     @Test
261     void testHandleParticipantStatusNotRegisterd() {
262         var participantStatusMessage = createParticipantStatus();
263         participantStatusMessage.setAutomationCompositionInfoList(List.of());
264         participantStatusMessage.setCompositionId(UUID.randomUUID());
265
266         var participantProvider = mock(ParticipantProvider.class);
267         var handler =
268                 new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class),
269                         mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionProvider.class),
270                         mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class),
271                         mock(MessageProvider.class), mock(EncryptionUtils.class));
272         handler.handleParticipantMessage(participantStatusMessage);
273
274         verify(participantProvider).saveParticipant(any());
275     }
276
277     @Test
278     void testHandleParticipantStatusCheckOnline() {
279         var participantStatusMessage = createParticipantStatus();
280         participantStatusMessage.setCompositionId(UUID.randomUUID());
281
282         var acDefinitionProvider = mock(AcDefinitionProvider.class);
283         var acDefinition = new AutomationCompositionDefinition();
284         acDefinition.setCompositionId(participantStatusMessage.getCompositionId());
285         when(acDefinitionProvider.getAcDefinition(acDefinition.getCompositionId())).thenReturn(acDefinition);
286
287         var participantProvider = mock(ParticipantProvider.class);
288         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
289         var messageProvider = mock(MessageProvider.class);
290         var handler = new SupervisionParticipantHandler(participantProvider,
291                 mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
292                 automationCompositionProvider, acDefinitionProvider, mock(ParticipantSyncPublisher.class),
293                 messageProvider, mock(EncryptionUtils.class));
294         var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
295         when(participantProvider.findParticipant(CommonTestData.getParticipantId()))
296                 .thenReturn(Optional.of(participant));
297         handler.handleParticipantMessage(participantStatusMessage);
298
299         verify(participantProvider).saveParticipant(any());
300     }
301
302     private ParticipantStatus createParticipantStatus() {
303         var statusMessage = new ParticipantStatus();
304         statusMessage.setParticipantId(CommonTestData.getParticipantId());
305         statusMessage.setState(ParticipantState.ON_LINE);
306         var supportedElementType = CommonTestData.createParticipantSupportedElementType();
307         statusMessage.setParticipantSupportedElementType(List.of(supportedElementType));
308         return statusMessage;
309     }
310
311     @Test
312     void testHandleParticipantReqSyncComposition() {
313         var acDefinitionProvider = mock(AcDefinitionProvider.class);
314         var acDefinition = new AutomationCompositionDefinition();
315         var compositionId = UUID.randomUUID();
316         acDefinition.setCompositionId(compositionId);
317         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
318
319         var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
320         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
321         var handler =
322                 new SupervisionParticipantHandler(mock(ParticipantProvider.class),
323                         mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
324                         automationCompositionProvider, acDefinitionProvider, participantSyncPublisher,
325                         mock(MessageProvider.class), mock(EncryptionUtils.class));
326         var participantReqSync = createParticipantReqSync(compositionId);
327         handler.handleParticipantReqSync(participantReqSync);
328         verify(participantSyncPublisher).sendRestartMsg(CommonTestData.getParticipantId(),
329                 CommonTestData.getReplicaId(), acDefinition, List.of());
330
331         clearInvocations(participantSyncPublisher);
332         var automationComposition =
333                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
334         automationComposition.setCompositionId(compositionId);
335         automationComposition.setInstanceId(UUID.randomUUID());
336         automationComposition.setDeployState(DeployState.DEPLOYED);
337         when(automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId()))
338                 .thenReturn(automationComposition);
339
340         participantReqSync.setAutomationCompositionId(automationComposition.getInstanceId());
341         handler.handleParticipantReqSync(participantReqSync);
342         verify(participantSyncPublisher).sendRestartMsg(CommonTestData.getParticipantId(),
343                 CommonTestData.getReplicaId(), acDefinition, List.of(automationComposition));
344     }
345
346     @Test
347     void testHandleParticipantReqSyncCompositionTarget() {
348         var acDefinitionProvider = mock(AcDefinitionProvider.class);
349         var acDefinition = new AutomationCompositionDefinition();
350         var compositionId = UUID.randomUUID();
351         acDefinition.setCompositionId(compositionId);
352         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
353
354         var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
355         var handler = new SupervisionParticipantHandler(mock(ParticipantProvider.class),
356                 mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
357                 mock(AutomationCompositionProvider.class), acDefinitionProvider,
358                 participantSyncPublisher, mock(MessageProvider.class), mock(EncryptionUtils.class));
359         var participantReqSync = createParticipantReqSync(null);
360         participantReqSync.setCompositionTargetId(compositionId);
361         handler.handleParticipantReqSync(participantReqSync);
362         verify(participantSyncPublisher).sendRestartMsg(CommonTestData.getParticipantId(),
363                 CommonTestData.getReplicaId(), acDefinition, List.of());
364     }
365
366
367     @Test
368     void testHandleParticipantReqSyncAutomationComposition() {
369         var acDefinition = new AutomationCompositionDefinition();
370         acDefinition.setServiceTemplate(new ToscaServiceTemplate());
371         acDefinition.getServiceTemplate().setToscaTopologyTemplate(new ToscaTopologyTemplate());
372         var compositionId = UUID.randomUUID();
373         acDefinition.setCompositionId(compositionId);
374         var acDefinitionProvider = mock(AcDefinitionProvider.class);
375         when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
376         var automationComposition = new AutomationComposition();
377         automationComposition.setElements(Map.of());
378         automationComposition.setPhase(1);
379         automationComposition.setCompositionTargetId(compositionId);
380         automationComposition.setInstanceId(UUID.randomUUID());
381         automationComposition.setDeployState(DeployState.MIGRATING);
382         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
383         when(automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId()))
384                 .thenReturn(automationComposition);
385
386         var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
387         var handler =
388                 new SupervisionParticipantHandler(mock(ParticipantProvider.class),
389                         mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
390                         automationCompositionProvider, acDefinitionProvider, participantSyncPublisher,
391                         mock(MessageProvider.class), mock(EncryptionUtils.class));
392         var participantReqSync = createParticipantReqSync(null);
393         participantReqSync.setAutomationCompositionId(automationComposition.getInstanceId());
394
395         handler.handleParticipantReqSync(participantReqSync);
396         verify(participantSyncPublisher).sendSync(automationComposition);
397
398         clearInvocations(participantSyncPublisher);
399         automationComposition.setPhase(0);
400         when(automationCompositionProvider.getAutomationCompositionRollback(automationComposition.getInstanceId()))
401                 .thenReturn(new AutomationCompositionRollback());
402         handler.handleParticipantReqSync(participantReqSync);
403         verify(participantSyncPublisher).sendSync(automationComposition);
404     }
405
406     private ParticipantReqSync createParticipantReqSync(UUID compositionId) {
407         var participantReqSync = new ParticipantReqSync();
408         participantReqSync.setCompositionId(compositionId);
409         participantReqSync.setParticipantId(CommonTestData.getParticipantId());
410         participantReqSync.setReplicaId(CommonTestData.getReplicaId());
411         return participantReqSync;
412     }
413 }