2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation.
4 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.clamp.controlloop.runtime.instantiation;
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.assertj.core.api.Assertions.assertThatThrownBy;
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import org.junit.jupiter.api.AfterAll;
30 import org.junit.jupiter.api.AfterEach;
31 import org.junit.jupiter.api.BeforeAll;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34 import org.mockito.Mockito;
35 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
36 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
37 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
38 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
39 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
40 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
41 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
42 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
43 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
44 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
45 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
46 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
47 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
48 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
49 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher;
50 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpdatePublisher;
51 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
52 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
53 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
54 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
55 import org.onap.policy.models.base.PfModelException;
56 import org.onap.policy.models.provider.PolicyModelsProvider;
57 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
61 * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
64 class ControlLoopInstantiationProviderTest {
66 private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
67 private static final String CL_INSTANTIATION_UPDATE_JSON =
68 "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
69 private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
70 "src/test/resources/rest/controlloops/PassiveCommand.json";
71 private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
72 "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
73 private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
74 "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
75 private static final String TOSCA_TEMPLATE_YAML =
76 "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
77 private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
78 private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
79 private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
80 private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
81 "\"ControlLoops\" INVALID, item has status INVALID\n"
82 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
83 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"
84 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
85 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
87 private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
88 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
89 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
90 + " Commissioned control loop definition not FOUND\n"
91 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
92 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
93 + " Commissioned control loop definition not FOUND\n";
95 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
97 private static SupervisionHandler supervisionHandler;
98 private static CommissioningProvider commissioningProvider;
99 private static ControlLoopProvider clProvider;
100 private static PolicyModelsProvider modelsProvider;
101 private static ParticipantProvider participantProvider;
104 public static void setUpBeforeClass() throws Exception {
105 serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
109 * setup Db Provider Parameters.
111 * @throws PfModelException if an error occurs
114 public static void setupDbProviderParameters() throws PfModelException {
115 ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
117 modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
118 clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
119 participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
121 var participantStatisticsProvider =
122 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
123 var clElementStatisticsProvider =
124 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
125 commissioningProvider = new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
126 var monitoringProvider =
127 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
128 var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
129 var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
130 var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
131 var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
132 var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
133 var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
134 supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
135 controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
136 participantDeregisterAckPublisher, participantUpdatePublisher);
140 public void populateDb() throws Exception {
145 public static void closeDbProvider() throws PfModelException {
147 modelsProvider.close();
151 public void cleanDatabase() throws Exception {
152 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
156 void testInstantiationCrud() throws Exception {
157 participantProvider.createParticipants(CommonTestData.createParticipants());
159 ControlLoops controlLoopsCreate =
160 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
161 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
162 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
163 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
164 supervisionHandler, participantProvider);
165 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
166 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
168 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
169 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
170 assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
172 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
173 ControlLoops controlLoopsGet =
174 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
175 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
176 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
179 ControlLoops controlLoopsUpdate =
180 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
181 assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
183 instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
184 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
186 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
187 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
188 assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
190 InstantiationCommand instantiationCommand =
191 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
192 instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
193 InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
195 for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
196 ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
197 toscaConceptIdentifier.getVersion());
198 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
199 assertThat(instantiationCommand.getOrderedState())
200 .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
203 // in order to delete a controlLoop the state must be UNINITIALISED
204 controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
205 instantiationProvider.updateControlLoops(controlLoopsCreate);
207 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
208 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
211 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
212 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
215 private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
217 ControlLoops controlLoopsDb = new ControlLoops();
218 controlLoopsDb.setControlLoopList(new ArrayList<>());
220 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
221 supervisionHandler, participantProvider);
223 for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
224 ControlLoops controlLoopsFromDb =
225 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
226 controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
228 return controlLoopsDb;
232 void testInstantiationDelete() throws Exception {
234 ControlLoops controlLoops =
235 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
236 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
238 ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
240 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
241 supervisionHandler, participantProvider);
244 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
245 .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
247 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
250 for (ControlLoopState state : ControlLoopState.values()) {
251 if (!ControlLoopState.UNINITIALISED.equals(state)) {
252 assertThatDeleteThrownBy(controlLoops, state);
256 controlLoop0.setState(ControlLoopState.UNINITIALISED);
257 instantiationProvider.updateControlLoops(controlLoops);
259 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
260 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
263 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
264 ControlLoops controlLoopsGet =
265 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
266 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
270 private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
271 ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
273 controlLoop.setState(state);
275 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
276 supervisionHandler, participantProvider);
278 instantiationProvider.updateControlLoops(controlLoops);
280 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
281 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
285 void testCreateControlLoops_NoDuplicates() throws Exception {
287 ControlLoops controlLoopsCreate =
288 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
290 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
291 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
293 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
294 supervisionHandler, participantProvider);
296 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
297 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
299 assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
300 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
302 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
303 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
308 void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
310 ControlLoops controlLoops = InstantiationUtils
311 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
313 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
314 participantProvider);
316 // to validate control Loop, it needs to define ToscaServiceTemplate
317 // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
319 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
321 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
322 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
326 void testCreateControlLoops_CommissionedClNotFound() throws Exception {
327 ControlLoops controlLoops = InstantiationUtils
328 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
330 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
332 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
333 participantProvider);
334 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
335 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
339 void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
340 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
341 supervisionHandler, participantProvider);
342 assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
343 .hasMessageMatching(ORDERED_STATE_INVALID);
347 void testInstantiationVersions() throws Exception {
348 // create controlLoops V1
349 ControlLoops controlLoopsV1 =
350 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
351 assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
353 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
354 supervisionHandler, participantProvider);
356 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
359 // create controlLoops V2
360 ControlLoops controlLoopsV2 =
361 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
362 assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
363 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
366 // GET controlLoops V2
367 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
368 ControlLoops controlLoopsGet =
369 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
370 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
371 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
374 // DELETE controlLoops V1
375 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
376 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
379 // GET controlLoops V1 is not available
380 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
381 ControlLoops controlLoopsGet =
382 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
383 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
386 // GET controlLoops V2 is still available
387 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
388 ControlLoops controlLoopsGet =
389 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
390 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
391 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
394 // DELETE controlLoops V2
395 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
396 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
399 // GET controlLoops V2 is not available
400 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
401 ControlLoops controlLoopsGet =
402 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
403 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
407 private synchronized void deleteEntryInDB(String name, String version) throws Exception {
408 if (!modelsProvider.getServiceTemplateList(null, null).isEmpty()) {
409 modelsProvider.deleteServiceTemplate(name, version);
413 private synchronized void createEntryInDB() throws Exception {
415 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
416 modelsProvider.createServiceTemplate(serviceTemplate);
417 } catch (Exception e) {