66c471521f44358e0d5e10db9931e3154b3f767b
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 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.scanner;
22
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;
32
33 import java.util.Map;
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;
48
49 class AcDefinitionScannerTest {
50
51     private static final UUID COMPOSITION_ID = UUID.randomUUID();
52     private static final Map<String, Object> OUT_PROPERTIES = Map.of("key", "value");
53
54     @Test
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());
75
76     }
77
78     @Test
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());
92
93         // wrong MessageType
94         docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
95         var result = acDefinitionScanner.scanMessage(acDefinition, docMessage);
96         assertFalse(result.isUpdated());
97         assertFalse(result.isToBeSync());
98
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());
106
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());
113     }
114
115     @Test
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());
135     }
136
137     @Test
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());
156     }
157
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));
173         return acDefinition;
174     }
175
176     @Test
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());
187     }
188
189     @Test
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());
201
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());
207
208         acRuntimeParameterGroup.getParticipantParameters().setMaxOperationWaitMs(-1);
209         acDefinitionScanner = new AcDefinitionScanner(acDefinitionProvider, participantSyncPublisher,
210                 acRuntimeParameterGroup);
211         acDefinition = createAutomationCompositionDefinition(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
212         acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
213         // set Timeout
214         verify(acDefinitionProvider).updateAcDefinitionState(acDefinition);
215         verify(participantSyncPublisher).sendSync(any(AutomationCompositionDefinition.class), any());
216
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());
224
225         clearInvocations(acDefinitionProvider);
226         clearInvocations(participantSyncPublisher);
227         // retry by the user
228         acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
229         acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
230         // set Timeout
231         verify(acDefinitionProvider).updateAcDefinitionState(acDefinition);
232         verify(participantSyncPublisher).sendSync(any(AutomationCompositionDefinition.class), any());
233
234         clearInvocations(acDefinitionProvider);
235         for (var element : acDefinition.getElementStateMap().values()) {
236             element.setState(AcTypeState.PRIMED);
237         }
238         acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, new UpdateSync());
239         // completed
240         verify(acDefinitionProvider).updateAcDefinitionState(acDefinition);
241     }
242 }