5ed4a4fc01f8da9de064dd059b679ce3a76ca569
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 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.controlloop.runtime.supervision;
22
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyList;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Optional;
33 import java.util.UUID;
34 import org.junit.jupiter.api.Test;
35 import org.mockito.Mockito;
36 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
37 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
38 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
39 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
40 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus;
41 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
42 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
43 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
44 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
45 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
46 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
47 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister;
48 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
49 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
50 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
51 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
52 import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils;
53 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
54 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher;
55 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpdatePublisher;
56 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
57 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
58 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
59 import org.onap.policy.common.utils.coder.CoderException;
60 import org.onap.policy.models.base.PfModelException;
61 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
62
63 class SupervisionHandlerTest {
64     private static final String TOSCA_TEMPLATE_YAML =
65             "src/test/resources/rest/servicetemplates/tosca-for-smoke-testing.yaml";
66     private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
67     private static final ToscaConceptIdentifier identifier = new ToscaConceptIdentifier("PMSHInstance0Crud", "1.0.1");
68     private static final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("ParticipantId", "1.0.0");
69     private static final ToscaConceptIdentifier participantType =
70             new ToscaConceptIdentifier("ParticipantType", "1.0.0");
71
72     @Test
73     void testTriggerControlLoopSupervisionEmpty() throws ControlLoopException, PfModelException, CoderException {
74         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), mock(ParticipantProvider.class),
75                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
76                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
77                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
78
79         assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of()))
80                 .hasMessageMatching("The list of control loops for supervision is empty");
81     }
82
83     @Test
84     void testTriggerControlLoopSupervision() throws ControlLoopException, PfModelException, CoderException {
85         var controlLoopProvider = mock(ControlLoopProvider.class);
86         var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
87         var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
88                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
89                 mock(ParticipantDeregisterAckPublisher.class), controlLoopUpdatePublisher,
90                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
91
92         handler.triggerControlLoopSupervision(List.of(identifier));
93
94         verify(controlLoopUpdatePublisher).send(any(ControlLoop.class));
95         verify(controlLoopProvider).updateControlLoop(any(ControlLoop.class));
96     }
97
98     @Test
99     void testTriggerControlLoopUninitialised() throws ControlLoopException, PfModelException, CoderException {
100         var controlLoopProvider = mock(ControlLoopProvider.class);
101         var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
102         var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
103                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
104                 mock(ParticipantDeregisterAckPublisher.class), controlLoopUpdatePublisher,
105                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.UNINITIALISED);
106
107         assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of(identifier)))
108             .hasMessageMatching("Control loop is already in state UNINITIALISED");
109     }
110
111     @Test
112     void testTriggerControlLoopRunning() throws ControlLoopException, PfModelException, CoderException {
113         var controlLoopProvider = mock(ControlLoopProvider.class);
114         var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
115         var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
116                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
117                 mock(ParticipantDeregisterAckPublisher.class), controlLoopUpdatePublisher,
118                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.RUNNING);
119
120         assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of(identifier)))
121             .hasMessageMatching("Control loop can't transition from state UNINITIALISED to state RUNNING");
122     }
123
124     @Test
125     void testHandleControlLoopStateChangeAckMessage() throws PfModelException, CoderException {
126         var controlLoopProvider = mock(ControlLoopProvider.class);
127         var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
128                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
129                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
130                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
131         var controlLoopAckMessage = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK);
132         controlLoopAckMessage.setControlLoopResultMap(Map.of());
133         controlLoopAckMessage.setControlLoopId(identifier);
134
135         handler.handleControlLoopStateChangeAckMessage(controlLoopAckMessage);
136
137         verify(controlLoopProvider).updateControlLoop(any(ControlLoop.class));
138     }
139
140     @Test
141     void testHandleControlLoopUpdateAckMessage() throws PfModelException, CoderException {
142         var controlLoopAckMessage = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_UPDATE_ACK);
143         controlLoopAckMessage.setParticipantId(participantId);
144         controlLoopAckMessage.setParticipantType(participantType);
145         controlLoopAckMessage.setControlLoopResultMap(Map.of());
146         controlLoopAckMessage.setControlLoopId(identifier);
147         var controlLoopProvider = mock(ControlLoopProvider.class);
148         var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
149                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
150                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
151                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
152
153         handler.handleControlLoopUpdateAckMessage(controlLoopAckMessage);
154
155         verify(controlLoopProvider).updateControlLoop(any(ControlLoop.class));
156     }
157
158     @Test
159     void testHandleParticipantDeregister() throws PfModelException, CoderException {
160         var participant = new Participant();
161         participant.setName(participantId.getName());
162         participant.setVersion(participantId.getVersion());
163         participant.setParticipantType(participantType);
164
165         var participantProvider = mock(ParticipantProvider.class);
166         when(participantProvider.findParticipant(participantId.getName(), participantId.getVersion()))
167                 .thenReturn(Optional.of(participant));
168
169         var participantDeregisterMessage = new ParticipantDeregister();
170         participantDeregisterMessage.setMessageId(UUID.randomUUID());
171         participantDeregisterMessage.setParticipantId(participantId);
172         participantDeregisterMessage.setParticipantType(participantType);
173         var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class);
174         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider,
175                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
176                 participantDeregisterAckPublisher, mock(ControlLoopUpdatePublisher.class),
177                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
178
179         handler.handleParticipantMessage(participantDeregisterMessage);
180
181         verify(participantProvider).saveParticipant(any());
182         verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId());
183     }
184
185     @Test
186     void testHandleParticipantRegister() throws PfModelException, CoderException {
187         var participant = new Participant();
188         participant.setName(participantId.getName());
189         participant.setVersion(participantId.getVersion());
190         participant.setParticipantType(participantType);
191
192         var participantRegisterMessage = new ParticipantRegister();
193         participantRegisterMessage.setMessageId(UUID.randomUUID());
194         participantRegisterMessage.setParticipantId(participantId);
195         participantRegisterMessage.setParticipantType(participantType);
196         var participantProvider = mock(ParticipantProvider.class);
197         var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
198         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider,
199                 mock(MonitoringProvider.class), participantRegisterAckPublisher,
200                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
201                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
202
203         handler.handleParticipantMessage(participantRegisterMessage);
204
205         verify(participantProvider).saveParticipant(any());
206         verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), participantId,
207                 participantType);
208     }
209
210     @Test
211     void testParticipantUpdateAck() throws PfModelException, CoderException {
212         var participant = new Participant();
213         participant.setName(participantId.getName());
214         participant.setVersion(participantId.getVersion());
215         participant.setParticipantType(participantType);
216
217         var participantProvider = mock(ParticipantProvider.class);
218         when(participantProvider.findParticipant(participantId.getName(), participantId.getVersion()))
219                 .thenReturn(Optional.of(participant));
220
221         var participantUpdateAckMessage = new ParticipantUpdateAck();
222         participantUpdateAckMessage.setParticipantId(participantId);
223         participantUpdateAckMessage.setParticipantType(participantType);
224         participantUpdateAckMessage.setState(ParticipantState.PASSIVE);
225         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider,
226                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
227                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
228                 mock(ParticipantUpdatePublisher.class), ControlLoopOrderedState.PASSIVE);
229
230         handler.handleParticipantMessage(participantUpdateAckMessage);
231
232         verify(participantProvider).saveParticipant(any());
233     }
234
235     @Test
236     void testHandleParticipantStatus() throws PfModelException, CoderException {
237         var participantStatusMessage = new ParticipantStatus();
238         participantStatusMessage.setParticipantId(participantId);
239         participantStatusMessage.setParticipantType(participantType);
240         participantStatusMessage.setState(ParticipantState.PASSIVE);
241         participantStatusMessage.setHealthStatus(ParticipantHealthStatus.HEALTHY);
242         participantStatusMessage.setParticipantStatistics(new ParticipantStatistics());
243
244         var participantProvider = mock(ParticipantProvider.class);
245         var monitoringProvider = mock(MonitoringProvider.class);
246         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider, monitoringProvider,
247                 mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
248                 mock(ControlLoopUpdatePublisher.class), mock(ParticipantUpdatePublisher.class),
249                 ControlLoopOrderedState.PASSIVE);
250         handler.handleParticipantMessage(participantStatusMessage);
251
252         verify(participantProvider).saveParticipant(any());
253         verify(monitoringProvider).createParticipantStatistics(anyList());
254     }
255
256     @Test
257     void testHandleSendCommissionMessage() throws PfModelException, CoderException {
258         var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
259         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), mock(ParticipantProvider.class),
260                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
261                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
262                 participantUpdatePublisher, ControlLoopOrderedState.PASSIVE);
263         handler.handleSendCommissionMessage(participantId.getName(), participantId.getVersion());
264
265         verify(participantUpdatePublisher).sendComissioningBroadcast(participantId.getName(),
266                 participantId.getVersion());
267     }
268
269     @Test
270     void testHandleSendDeCommissionMessage() throws PfModelException, CoderException {
271         var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
272         var handler = createSupervisionHandler(mock(ControlLoopProvider.class), mock(ParticipantProvider.class),
273                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
274                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
275                 participantUpdatePublisher, ControlLoopOrderedState.PASSIVE);
276         handler.handleSendDeCommissionMessage();
277
278         verify(participantUpdatePublisher).sendDecomisioning();
279     }
280
281     private SupervisionHandler createSupervisionHandler(ControlLoopProvider controlLoopProvider,
282             ParticipantProvider participantProvider, MonitoringProvider monitoringProvider,
283             ParticipantRegisterAckPublisher participantRegisterAckPublisher,
284             ParticipantDeregisterAckPublisher participantDeregisterAckPublisher,
285             ControlLoopUpdatePublisher controlLoopUpdatePublisher,
286             ParticipantUpdatePublisher participantUpdatePublisher,
287             ControlLoopOrderedState orderedState) throws PfModelException, CoderException {
288         var controlLoopsCreate = InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
289
290         var controlLoop = controlLoopsCreate.getControlLoopList().get(0);
291         controlLoop.setOrderedState(orderedState);
292
293         var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
294
295         when(controlLoopProvider.getControlLoop(identifier)).thenReturn(controlLoop);
296
297         var serviceTemplateProvider = Mockito.mock(ServiceTemplateProvider.class);
298         when(serviceTemplateProvider.getServiceTemplateList(any(), any()))
299                 .thenReturn(List.of(InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)));
300
301         return new SupervisionHandler(controlLoopProvider, participantProvider, monitoringProvider,
302                 serviceTemplateProvider, controlLoopUpdatePublisher, controlLoopStateChangePublisher,
303                 participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
304
305     }
306 }