2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2025 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
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.scanner;
23 import static org.junit.jupiter.api.Assertions.assertEquals;
24 import static org.junit.jupiter.api.Assertions.assertFalse;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.mockito.ArgumentMatchers.any;
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.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
34 import java.util.UUID;
35 import org.junit.jupiter.api.Test;
36 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
37 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
38 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
39 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
40 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
41 import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
42 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
43 import org.onap.policy.clamp.models.acm.document.concepts.DocMessage;
44 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType;
45 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
46 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
49 class AcDefinitionScannerTest {
51 private static final UUID COMPOSITION_ID = UUID.randomUUID();
52 private static final Map<String, Object> OUT_PROPERTIES = Map.of("key", "value");
55 void testFailScenario() {
56 var acDefinitionProvider = mock(AcDefinitionProvider.class);
57 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
58 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
59 var acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider,
60 participantSyncPublisher, acRuntimeParameterGroup);
61 var acDefinition = createAutomationCompositionDefinition(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
62 var element = acDefinition.getElementStateMap().values().iterator().next();
63 var docMessage = new DocMessage();
64 docMessage.setCompositionId(COMPOSITION_ID);
65 docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_PRIME_ACK);
66 docMessage.setStateChangeResult(StateChangeResult.FAILED);
67 docMessage.setCompositionState(AcTypeState.COMMISSIONED);
68 docMessage.setParticipantId(element.getParticipantId());
69 var result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
70 assertTrue(result.isUpdated());
71 assertTrue(result.isToBeSync());
72 assertEquals(docMessage.getCompositionState(),
73 acDefinition.getElementStateMap().get(element.getNodeTemplateStateId().toString()).getState());
74 assertEquals(docMessage.getStateChangeResult(), acDefinition.getStateChangeResult());
79 void testWithWrongData() {
80 var acDefinitionProvider = mock(AcDefinitionProvider.class);
81 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
82 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
83 var acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider,
84 participantSyncPublisher, acRuntimeParameterGroup);
85 var acDefinition = createAutomationCompositionDefinition(AcTypeState.DEPRIMING, StateChangeResult.NO_ERROR);
86 var element = acDefinition.getElementStateMap().values().iterator().next();
87 var docMessage = new DocMessage();
88 docMessage.setCompositionId(COMPOSITION_ID);
89 docMessage.setStateChangeResult(StateChangeResult.NO_ERROR);
90 docMessage.setCompositionState(AcTypeState.COMMISSIONED);
91 docMessage.setParticipantId(element.getParticipantId());
94 docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
95 var result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
96 assertFalse(result.isUpdated());
97 assertFalse(result.isToBeSync());
99 // wrong elementId in outProperties
100 docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_STATUS);
101 docMessage.setOutProperties(OUT_PROPERTIES);
102 docMessage.setAcElementDefinitionId(new ToscaConceptIdentifier("wrong", "1.0.1"));
103 result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
104 assertFalse(result.isUpdated());
105 assertFalse(result.isToBeSync());
107 // wrong participantId in StateChange
108 docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_PRIME_ACK);
109 docMessage.setParticipantId(UUID.randomUUID());
110 result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
111 assertFalse(result.isUpdated());
112 assertFalse(result.isToBeSync());
116 void testScanMessageStateChange() {
117 var acDefinitionProvider = mock(AcDefinitionProvider.class);
118 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
119 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
120 var acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider,
121 participantSyncPublisher, acRuntimeParameterGroup);
122 var acDefinition = createAutomationCompositionDefinition(AcTypeState.DEPRIMING, StateChangeResult.NO_ERROR);
123 var element = acDefinition.getElementStateMap().values().iterator().next();
124 var docMessage = new DocMessage();
125 docMessage.setCompositionId(COMPOSITION_ID);
126 docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_PRIME_ACK);
127 docMessage.setStateChangeResult(StateChangeResult.NO_ERROR);
128 docMessage.setCompositionState(AcTypeState.COMMISSIONED);
129 docMessage.setParticipantId(element.getParticipantId());
130 var result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
131 assertTrue(result.isUpdated());
132 assertFalse(result.isToBeSync());
133 assertEquals(docMessage.getCompositionState(),
134 acDefinition.getElementStateMap().get(element.getNodeTemplateStateId().toString()).getState());
138 void testScanMessageOutProperties() {
139 var acDefinitionProvider = mock(AcDefinitionProvider.class);
140 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
141 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
142 var acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider,
143 participantSyncPublisher, acRuntimeParameterGroup);
144 var acDefinition = createAutomationCompositionDefinition(AcTypeState.DEPRIMING, StateChangeResult.NO_ERROR);
145 var element = acDefinition.getElementStateMap().values().iterator().next();
146 var docMessage = new DocMessage();
147 docMessage.setCompositionId(COMPOSITION_ID);
148 docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_STATUS);
149 docMessage.setOutProperties(OUT_PROPERTIES);
150 docMessage.setAcElementDefinitionId(element.getNodeTemplateId());
151 var result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
152 assertTrue(result.isUpdated());
153 assertTrue(result.isToBeSync());
154 assertEquals(docMessage.getOutProperties(),
155 acDefinition.getElementStateMap().get(element.getNodeTemplateStateId().toString()).getOutProperties());
158 private AutomationCompositionDefinition createAutomationCompositionDefinition(AcTypeState acTypeState,
159 StateChangeResult stateChangeResult) {
160 var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
161 var acDefinition = new AutomationCompositionDefinition();
162 acDefinition.setState(acTypeState);
163 acDefinition.setStateChangeResult(stateChangeResult);
164 acDefinition.setCompositionId(COMPOSITION_ID);
165 acDefinition.setLastMsg(TimestampHelper.now());
166 acDefinition.setServiceTemplate(serviceTemplate);
167 var node = new NodeTemplateState();
168 node.setState(acTypeState);
169 node.setNodeTemplateStateId(UUID.randomUUID());
170 node.setParticipantId(UUID.randomUUID());
171 node.setNodeTemplateId(new ToscaConceptIdentifier("name", "1.0.0"));
172 acDefinition.setElementStateMap(Map.of(node.getNodeTemplateStateId().toString(), node));
177 void testAcDefinitionPrimeFailed() {
178 var acDefinitionProvider = mock(AcDefinitionProvider.class);
179 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
180 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
181 var acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider,
182 participantSyncPublisher, acRuntimeParameterGroup);
183 var acDefinition = createAutomationCompositionDefinition(AcTypeState.PRIMING, StateChangeResult.FAILED);
184 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
185 verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any());
186 verify(participantSyncPublisher, times(0)).sendSync(any(), any());
190 void testAcDefinitionPrimeTimeout() {
191 var acDefinitionProvider = mock(AcDefinitionProvider.class);
192 var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
193 var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
194 var acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider, participantSyncPublisher,
195 acRuntimeParameterGroup);
196 var acDefinition = createAutomationCompositionDefinition(AcTypeState.DEPRIMING, StateChangeResult.NO_ERROR);
197 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
198 // Ac Definition in Depriming state
199 verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any());
200 verify(participantSyncPublisher, times(0)).sendSync(any(), any());
202 acDefinition.setState(AcTypeState.PRIMING);
203 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
204 // Ac Definition in Priming state
205 verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any());
206 verify(participantSyncPublisher, times(0)).sendSync(any(), any());
208 acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1);
209 acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider, participantSyncPublisher,
210 acRuntimeParameterGroup);
211 acDefinition = createAutomationCompositionDefinition(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
212 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
214 verify(acDefinitionProvider).updateAcDefinitionState(acDefinition);
215 verify(participantSyncPublisher).sendSync(any(AutomationCompositionDefinition.class), any());
217 clearInvocations(acDefinitionProvider);
218 clearInvocations(participantSyncPublisher);
219 acDefinition = createAutomationCompositionDefinition(AcTypeState.PRIMING, StateChangeResult.TIMEOUT);
220 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
221 // already in Timeout
222 verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any());
223 verify(participantSyncPublisher, times(0)).sendSync(any(), any());
225 clearInvocations(acDefinitionProvider);
226 clearInvocations(participantSyncPublisher);
228 acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
229 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
231 verify(acDefinitionProvider).updateAcDefinitionState(acDefinition);
232 verify(participantSyncPublisher).sendSync(any(AutomationCompositionDefinition.class), any());
234 clearInvocations(acDefinitionProvider);
235 for (var element : acDefinition.getElementStateMap().values()) {
236 element.setState(AcTypeState.PRIMED);
238 acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
240 verify(acDefinitionProvider).updateAcDefinitionState(acDefinition);