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.instantiation;
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatThrownBy;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import org.junit.jupiter.api.AfterAll;
29 import org.junit.jupiter.api.AfterEach;
30 import org.junit.jupiter.api.BeforeAll;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.api.Test;
33 import org.mockito.Mockito;
34 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
36 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
37 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
38 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
39 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
40 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
41 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
42 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
43 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
44 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
45 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
46 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
47 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
48 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher;
49 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpdatePublisher;
50 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
51 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
52 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
53 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
54 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
55 import org.onap.policy.common.utils.resources.ResourceUtils;
56 import org.onap.policy.models.base.PfModelException;
57 import org.onap.policy.models.provider.PolicyModelsProvider;
58 import org.onap.policy.models.provider.PolicyModelsProviderFactory;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
60 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
61 import org.springframework.beans.factory.annotation.Autowired;
64 * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
67 class ControlLoopInstantiationProviderTest {
69 private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
70 private static final String CL_INSTANTIATION_UPDATE_JSON =
71 "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
72 private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
73 "src/test/resources/rest/controlloops/PassiveCommand.json";
74 private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
75 "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
76 private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
77 "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
78 private static final String TOSCA_TEMPLATE_YAML =
79 "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
80 private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
81 private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
82 private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
83 private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
84 "\"ControlLoops\" INVALID, item has status INVALID\n"
85 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
86 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"
87 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
88 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
90 private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\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"
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";
98 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
100 private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
102 private static SupervisionHandler supervisionHandler;
103 private static CommissioningProvider commissioningProvider;
104 private static ControlLoopProvider clProvider;
105 private static PolicyModelsProvider modelsProvider;
106 private static ParticipantProvider participantProvider;
109 public static void setUpBeforeClass() throws Exception {
110 serviceTemplate = yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(TOSCA_TEMPLATE_YAML),
111 ToscaServiceTemplate.class);
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");
124 CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
125 clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
126 participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
128 var participantStatisticsProvider =
129 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
130 var clElementStatisticsProvider =
131 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
132 commissioningProvider = new CommissioningProvider(modelsProvider, clProvider, null, 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 supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
142 controlLoopUpdatePublisher, controlLoopStateChangePublisher,
143 participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
147 public void populateDb() throws Exception {
152 public static void closeDbProvider() throws PfModelException {
154 modelsProvider.close();
158 public void cleanDatabase() throws Exception {
159 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
163 void testInstantiationCrud() throws Exception {
165 ControlLoops controlLoopsCreate =
166 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
167 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
168 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
169 var instantiationProvider =
170 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
171 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
172 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
174 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
175 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
176 assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
178 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
179 ControlLoops controlLoopsGet =
180 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
181 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
182 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
185 ControlLoops controlLoopsUpdate =
186 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
187 assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
189 instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
190 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
192 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
193 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
194 assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
196 InstantiationCommand instantiationCommand =
197 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
198 instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
199 InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
201 for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
202 ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
203 toscaConceptIdentifier.getVersion());
204 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
205 assertThat(instantiationCommand.getOrderedState())
206 .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
209 // in order to delete a controlLoop the state must be UNINITIALISED
210 controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
211 instantiationProvider.updateControlLoops(controlLoopsCreate);
213 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
214 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
217 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
218 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
221 private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
223 ControlLoops controlLoopsDb = new ControlLoops();
224 controlLoopsDb.setControlLoopList(new ArrayList<>());
226 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider,
227 commissioningProvider, supervisionHandler);
229 for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
230 ControlLoops controlLoopsFromDb =
231 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
232 controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
234 return controlLoopsDb;
238 void testInstantiationDelete() throws Exception {
240 ControlLoops controlLoops =
241 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
242 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
244 ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
246 var instantiationProvider =
247 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
250 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
251 .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
253 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
256 for (ControlLoopState state : ControlLoopState.values()) {
257 if (!ControlLoopState.UNINITIALISED.equals(state)) {
258 assertThatDeleteThrownBy(controlLoops, state);
262 controlLoop0.setState(ControlLoopState.UNINITIALISED);
263 instantiationProvider.updateControlLoops(controlLoops);
265 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
266 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
269 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
270 ControlLoops controlLoopsGet =
271 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
272 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
276 private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
277 ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
279 controlLoop.setState(state);
281 var instantiationProvider =
282 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
284 instantiationProvider.updateControlLoops(controlLoops);
286 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
287 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
291 void testCreateControlLoops_NoDuplicates() throws Exception {
293 ControlLoops controlLoopsCreate =
294 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
296 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
297 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
299 var instantiationProvider =
300 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
302 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
303 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
305 assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
306 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
308 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
309 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
314 void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
316 ControlLoops controlLoops = InstantiationUtils
317 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
319 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
321 // to validate control Loop, it needs to define ToscaServiceTemplate
322 // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
324 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
326 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
327 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
331 void testCreateControlLoops_CommissionedClNotFound() throws Exception {
332 ControlLoops controlLoops = InstantiationUtils
333 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
335 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
337 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
338 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
339 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
343 void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
344 var instantiationProvider =
345 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
346 assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
347 .hasMessageMatching(ORDERED_STATE_INVALID);
351 void testInstantiationVersions() throws Exception {
352 // create controlLoops V1
353 ControlLoops controlLoopsV1 =
354 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
355 assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
357 var instantiationProvider =
358 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
360 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
363 // create controlLoops V2
364 ControlLoops controlLoopsV2 =
365 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
366 assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
367 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
370 // GET controlLoops V2
371 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
372 ControlLoops controlLoopsGet =
373 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
374 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
375 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
378 // DELETE controlLoops V1
379 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
380 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
383 // GET controlLoops V1 is not available
384 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
385 ControlLoops controlLoopsGet =
386 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
387 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
390 // GET controlLoops V2 is still available
391 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
392 ControlLoops controlLoopsGet =
393 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
394 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
395 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
398 // DELETE controlLoops V2
399 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
400 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
403 // GET controlLoops V2 is not available
404 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
405 ControlLoops controlLoopsGet =
406 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
407 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
411 private synchronized void deleteEntryInDB(String name, String version) throws Exception {
412 if (!modelsProvider.getServiceTemplateList(null, null).isEmpty()) {
413 modelsProvider.deleteServiceTemplate(name, version);
417 private synchronized void createEntryInDB() throws Exception {
419 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
420 modelsProvider.createServiceTemplate(serviceTemplate);
421 } catch (Exception e) {