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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.clamp.acm.runtime.supervision;
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;
31 import java.util.List;
33 import java.util.Optional;
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;
67 class SupervisionParticipantHandlerTest {
69 private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
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);
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));
84 handler.handleParticipantMessage(participantDeregisterMessage);
85 verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId());
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());
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));
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);
113 verify(participantProvider).saveParticipant(any());
114 verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(),
115 CommonTestData.getParticipantId(), null);
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));
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));
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);
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);
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));
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);
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());
179 void testHandleParticipantStatusWithInstanceOutProperties() {
180 var participantStatusMessage = createParticipantStatus();
181 participantStatusMessage.setAutomationCompositionInfoList(List.of(new AutomationCompositionInfo()));
182 participantStatusMessage.setCompositionId(UUID.randomUUID());
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));
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);
202 verify(messageProvider).saveInstanceOutProperties(any(ParticipantStatus.class));
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));
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);
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());
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));
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());
261 void testHandleParticipantStatusNotRegisterd() {
262 var participantStatusMessage = createParticipantStatus();
263 participantStatusMessage.setAutomationCompositionInfoList(List.of());
264 participantStatusMessage.setCompositionId(UUID.randomUUID());
266 var participantProvider = mock(ParticipantProvider.class);
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);
274 verify(participantProvider).saveParticipant(any());
278 void testHandleParticipantStatusCheckOnline() {
279 var participantStatusMessage = createParticipantStatus();
280 participantStatusMessage.setCompositionId(UUID.randomUUID());
282 var acDefinitionProvider = mock(AcDefinitionProvider.class);
283 var acDefinition = new AutomationCompositionDefinition();
284 acDefinition.setCompositionId(participantStatusMessage.getCompositionId());
285 when(acDefinitionProvider.getAcDefinition(acDefinition.getCompositionId())).thenReturn(acDefinition);
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);
299 verify(participantProvider).saveParticipant(any());
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;
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);
319 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
320 var automationCompositionProvider = mock(AutomationCompositionProvider.class);
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());
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);
340 participantReqSync.setAutomationCompositionId(automationComposition.getInstanceId());
341 handler.handleParticipantReqSync(participantReqSync);
342 verify(participantSyncPublisher).sendRestartMsg(CommonTestData.getParticipantId(),
343 CommonTestData.getReplicaId(), acDefinition, List.of(automationComposition));
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);
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());
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);
386 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
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());
395 handler.handleParticipantReqSync(participantReqSync);
396 verify(participantSyncPublisher).sendSync(automationComposition);
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);
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;