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;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertNull;
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import org.junit.jupiter.api.AfterAll;
33 import org.junit.jupiter.api.AfterEach;
34 import org.junit.jupiter.api.BeforeAll;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37 import org.mockito.Mockito;
38 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
39 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
40 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
41 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
42 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
43 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
44 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
45 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
46 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
47 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
48 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
49 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
50 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
51 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
52 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
53 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
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.clamp.controlloop.runtime.util.CommonTestData;
60 import org.onap.policy.models.base.PfModelException;
61 import org.onap.policy.models.provider.PolicyModelsProvider;
62 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
66 * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
69 class ControlLoopInstantiationProviderTest {
70 private static final String ID_NAME = "PMSH_Instance1";
71 private static final String ID_VERSION = "1.2.3";
72 private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
73 private static final String CL_INSTANTIATION_UPDATE_JSON =
74 "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
75 private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
76 "src/test/resources/rest/controlloops/PassiveCommand.json";
77 private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
78 "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
79 private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
80 "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
81 private static final String TOSCA_TEMPLATE_YAML =
82 "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
83 private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
84 private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
85 private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
86 private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
87 "\"ControlLoops\" INVALID, item has status INVALID\n"
88 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
89 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"
90 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
91 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
93 private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
94 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
95 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
96 + " Commissioned control loop definition not FOUND\n"
97 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
98 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
99 + " Commissioned control loop definition not FOUND\n";
101 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
103 private static SupervisionHandler supervisionHandler;
104 private static CommissioningProvider commissioningProvider;
105 private static ControlLoopProvider clProvider;
106 private static PolicyModelsProvider modelsProvider;
107 private static ParticipantProvider participantProvider;
110 public static void setUpBeforeClass() throws Exception {
111 serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
115 * setup Db Provider Parameters.
117 * @throws PfModelException if an error occurs
120 public static void setupDbProviderParameters() throws PfModelException {
121 ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
123 modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
124 clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
125 participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
127 var participantStatisticsProvider =
128 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
129 var clElementStatisticsProvider =
130 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
131 commissioningProvider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider), clProvider, null,
132 participantProvider);
133 var monitoringProvider =
134 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
135 var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
136 var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
137 var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
138 var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
139 var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
140 var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
141 var modelsProvider = Mockito.mock(PolicyModelsProvider.class);
143 supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider, modelsProvider,
144 controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
145 participantDeregisterAckPublisher, participantUpdatePublisher);
149 public void populateDb() throws Exception {
154 public static void closeDbProvider() throws PfModelException {
156 modelsProvider.close();
160 public void cleanDatabase() throws Exception {
161 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
165 void testIntanceResponses() throws PfModelException {
166 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
167 supervisionHandler, participantProvider);
168 var instancePropertyList = instantiationProvider.createInstanceProperties(serviceTemplate);
169 assertNull(instancePropertyList.getErrorDetails());
170 var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION);
171 assertEquals(id, instancePropertyList.getAffectedInstanceProperties().get(0));
172 var instanceOrderState = instantiationProvider.getInstantiationOrderState(ID_NAME, ID_VERSION);
173 assertEquals(ControlLoopOrderedState.UNINITIALISED, instanceOrderState.getOrderedState());
174 assertEquals(ID_NAME, instanceOrderState.getControlLoopIdentifierList().get(0).getName());
176 assertNotNull(clProvider.getControlLoop(id));
177 var instanceResponse = instantiationProvider.deleteInstanceProperties(ID_NAME, ID_VERSION);
178 assertEquals(ID_NAME, instanceResponse.getAffectedControlLoops().get(0).getName());
179 assertNull(clProvider.getControlLoop(id));
183 void testInstantiationCrud() throws Exception {
184 participantProvider.createParticipants(CommonTestData.createParticipants());
186 ControlLoops controlLoopsCreate =
187 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
188 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
189 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
190 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
191 supervisionHandler, participantProvider);
192 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
193 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
195 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
196 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
197 assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
199 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
200 ControlLoops controlLoopsGet =
201 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
202 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
203 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
206 ControlLoops controlLoopsUpdate =
207 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
208 assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
210 instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
211 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
213 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
214 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
215 assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
217 InstantiationCommand instantiationCommand =
218 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
219 instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
220 InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
222 for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
223 ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
224 toscaConceptIdentifier.getVersion());
225 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
226 assertThat(instantiationCommand.getOrderedState())
227 .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
230 // in order to delete a controlLoop the state must be UNINITIALISED
231 controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
232 instantiationProvider.updateControlLoops(controlLoopsCreate);
234 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
235 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
238 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
239 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
242 private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
244 ControlLoops controlLoopsDb = new ControlLoops();
245 controlLoopsDb.setControlLoopList(new ArrayList<>());
247 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
248 supervisionHandler, participantProvider);
250 for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
251 ControlLoops controlLoopsFromDb =
252 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
253 controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
255 return controlLoopsDb;
259 void testInstantiationDelete() throws Exception {
261 ControlLoops controlLoops =
262 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
263 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
265 ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
267 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
268 supervisionHandler, participantProvider);
271 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
272 .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
274 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
277 for (ControlLoopState state : ControlLoopState.values()) {
278 if (!ControlLoopState.UNINITIALISED.equals(state)) {
279 assertThatDeleteThrownBy(controlLoops, state);
283 controlLoop0.setState(ControlLoopState.UNINITIALISED);
284 instantiationProvider.updateControlLoops(controlLoops);
286 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
287 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
290 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
291 ControlLoops controlLoopsGet =
292 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
293 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
297 private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
298 ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
300 controlLoop.setState(state);
302 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
303 supervisionHandler, participantProvider);
305 instantiationProvider.updateControlLoops(controlLoops);
307 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
308 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
312 void testCreateControlLoops_NoDuplicates() throws Exception {
314 ControlLoops controlLoopsCreate =
315 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
317 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
318 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
320 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
321 supervisionHandler, participantProvider);
323 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
324 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
326 assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
327 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
329 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
330 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
335 void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
337 ControlLoops controlLoops = InstantiationUtils
338 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
340 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
341 participantProvider);
343 // to validate control Loop, it needs to define ToscaServiceTemplate
344 // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
346 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
348 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
349 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
353 void testCreateControlLoops_CommissionedClNotFound() throws Exception {
354 ControlLoops controlLoops = InstantiationUtils
355 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
357 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
359 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
360 participantProvider);
361 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
362 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
366 void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
367 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
368 supervisionHandler, participantProvider);
369 assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
370 .hasMessageMatching(ORDERED_STATE_INVALID);
374 void testInstantiationVersions() throws Exception {
375 // create controlLoops V1
376 ControlLoops controlLoopsV1 =
377 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
378 assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
380 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
381 supervisionHandler, participantProvider);
383 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
386 // create controlLoops V2
387 ControlLoops controlLoopsV2 =
388 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
389 assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
390 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
393 // GET controlLoops V2
394 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
395 ControlLoops controlLoopsGet =
396 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
397 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
398 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
401 // DELETE controlLoops V1
402 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
403 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
406 // GET controlLoops V1 is not available
407 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
408 ControlLoops controlLoopsGet =
409 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
410 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
413 // GET controlLoops V2 is still available
414 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
415 ControlLoops controlLoopsGet =
416 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
417 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
418 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
421 // DELETE controlLoops V2
422 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
423 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
426 // GET controlLoops V2 is not available
427 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
428 ControlLoops controlLoopsGet =
429 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
430 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
434 private synchronized void deleteEntryInDB(String name, String version) throws Exception {
435 if (!modelsProvider.getServiceTemplateList(null, null).isEmpty()) {
436 modelsProvider.deleteServiceTemplate(name, version);
440 private synchronized void createEntryInDB() throws Exception {
442 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
443 modelsProvider.createServiceTemplate(serviceTemplate);
444 } catch (Exception e) {