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
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.controlloop.runtime.supervision;
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;
30 import java.util.List;
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;
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");
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);
79 assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of()))
80 .hasMessageMatching("The list of control loops for supervision is empty");
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);
92 handler.triggerControlLoopSupervision(List.of(identifier));
94 verify(controlLoopUpdatePublisher).send(any(ControlLoop.class));
95 verify(controlLoopProvider).saveControlLoop(any(ControlLoop.class));
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);
107 assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of(identifier)))
108 .hasMessageMatching("Control loop is already in state UNINITIALISED");
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);
120 assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of(identifier)))
121 .hasMessageMatching("Control loop can't transition from state UNINITIALISED to state RUNNING");
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);
135 handler.handleControlLoopStateChangeAckMessage(controlLoopAckMessage);
137 verify(controlLoopProvider).saveControlLoop(any(ControlLoop.class));
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);
153 handler.handleControlLoopUpdateAckMessage(controlLoopAckMessage);
155 verify(controlLoopProvider).saveControlLoop(any(ControlLoop.class));
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);
165 var participantProvider = mock(ParticipantProvider.class);
166 when(participantProvider.findParticipant(participantId.getName(), participantId.getVersion()))
167 .thenReturn(Optional.of(participant));
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);
179 handler.handleParticipantMessage(participantDeregisterMessage);
181 verify(participantProvider).saveParticipant(any());
182 verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId());
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);
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);
203 handler.handleParticipantMessage(participantRegisterMessage);
205 verify(participantProvider).saveParticipant(any());
206 verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), participantId,
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);
217 var participantProvider = mock(ParticipantProvider.class);
218 when(participantProvider.findParticipant(participantId.getName(), participantId.getVersion()))
219 .thenReturn(Optional.of(participant));
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);
230 handler.handleParticipantMessage(participantUpdateAckMessage);
232 verify(participantProvider).saveParticipant(any());
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());
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);
252 verify(participantProvider).saveParticipant(any());
253 verify(monitoringProvider).createParticipantStatistics(anyList());
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());
265 verify(participantUpdatePublisher).sendComissioningBroadcast(participantId.getName(),
266 participantId.getVersion());
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();
278 verify(participantUpdatePublisher).sendDecomisioning();
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");
290 var controlLoop = controlLoopsCreate.getControlLoopList().get(0);
291 controlLoop.setOrderedState(orderedState);
293 when(controlLoopProvider.findControlLoop(identifier)).thenReturn(Optional.of(controlLoop));
294 when(controlLoopProvider.getControlLoop(identifier)).thenReturn(controlLoop);
296 var serviceTemplateProvider = Mockito.mock(ServiceTemplateProvider.class);
297 when(serviceTemplateProvider.getServiceTemplateList(any(), any()))
298 .thenReturn(List.of(InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)));
300 var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
302 return new SupervisionHandler(controlLoopProvider, participantProvider, monitoringProvider,
303 serviceTemplateProvider, controlLoopUpdatePublisher, controlLoopStateChangePublisher,
304 participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);