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.common.utils.coder.YamlJsonTranslator;
56 import org.onap.policy.common.utils.resources.ResourceUtils;
57 import org.onap.policy.models.base.PfModelException;
58 import org.onap.policy.models.provider.PolicyModelsProvider;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
60 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
63 * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
66 class ControlLoopInstantiationProviderTest {
68 private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
69 private static final String CL_INSTANTIATION_UPDATE_JSON =
70 "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
71 private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
72 "src/test/resources/rest/controlloops/PassiveCommand.json";
73 private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
74 "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
75 private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
76 "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
77 private static final String TOSCA_TEMPLATE_YAML =
78 "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
79 private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
80 private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
81 private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
82 private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
83 "\"ControlLoops\" INVALID, item has status INVALID\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"
86 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
87 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
89 private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
90 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
91 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
92 + " Commissioned control loop definition not FOUND\n"
93 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
94 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
95 + " Commissioned control loop definition not FOUND\n";
97 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
99 private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
101 private static SupervisionHandler supervisionHandler;
102 private static CommissioningProvider commissioningProvider;
103 private static ControlLoopProvider clProvider;
104 private static PolicyModelsProvider modelsProvider;
105 private static ParticipantProvider participantProvider;
108 public static void setUpBeforeClass() throws Exception {
109 serviceTemplate = yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(TOSCA_TEMPLATE_YAML),
110 ToscaServiceTemplate.class);
114 * setup Db Provider Parameters.
116 * @throws PfModelException if an error occurs
119 public static void setupDbProviderParameters() throws PfModelException {
120 ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
123 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(modelsProvider, clProvider, null, participantProvider);
132 var monitoringProvider =
133 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
134 var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
135 var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
136 var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
137 var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
138 var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
139 var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
140 supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
141 controlLoopUpdatePublisher, controlLoopStateChangePublisher,
142 participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
146 public void populateDb() throws Exception {
151 public static void closeDbProvider() throws PfModelException {
153 modelsProvider.close();
157 public void cleanDatabase() throws Exception {
158 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
162 void testInstantiationCrud() throws Exception {
164 ControlLoops controlLoopsCreate =
165 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
166 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
167 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
168 var instantiationProvider =
169 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
170 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
171 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
173 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
174 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
175 assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
177 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
178 ControlLoops controlLoopsGet =
179 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
180 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
181 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
184 ControlLoops controlLoopsUpdate =
185 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
186 assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
188 instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
189 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
191 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
192 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
193 assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
195 InstantiationCommand instantiationCommand =
196 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
197 instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
198 InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
200 for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
201 ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
202 toscaConceptIdentifier.getVersion());
203 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
204 assertThat(instantiationCommand.getOrderedState())
205 .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
208 // in order to delete a controlLoop the state must be UNINITIALISED
209 controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
210 instantiationProvider.updateControlLoops(controlLoopsCreate);
212 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
213 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
216 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
217 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
220 private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
222 ControlLoops controlLoopsDb = new ControlLoops();
223 controlLoopsDb.setControlLoopList(new ArrayList<>());
225 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider,
226 commissioningProvider, supervisionHandler);
228 for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
229 ControlLoops controlLoopsFromDb =
230 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
231 controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
233 return controlLoopsDb;
237 void testInstantiationDelete() throws Exception {
239 ControlLoops controlLoops =
240 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
241 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
243 ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
245 var instantiationProvider =
246 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
249 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
250 .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
252 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
255 for (ControlLoopState state : ControlLoopState.values()) {
256 if (!ControlLoopState.UNINITIALISED.equals(state)) {
257 assertThatDeleteThrownBy(controlLoops, state);
261 controlLoop0.setState(ControlLoopState.UNINITIALISED);
262 instantiationProvider.updateControlLoops(controlLoops);
264 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
265 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
268 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
269 ControlLoops controlLoopsGet =
270 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
271 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
275 private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
276 ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
278 controlLoop.setState(state);
280 var instantiationProvider =
281 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
283 instantiationProvider.updateControlLoops(controlLoops);
285 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
286 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
290 void testCreateControlLoops_NoDuplicates() throws Exception {
292 ControlLoops controlLoopsCreate =
293 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
295 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
296 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
298 var instantiationProvider =
299 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
301 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
302 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
304 assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
305 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
307 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
308 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
313 void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
315 ControlLoops controlLoops = InstantiationUtils
316 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
318 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
320 // to validate control Loop, it needs to define ToscaServiceTemplate
321 // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
323 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
325 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
326 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
330 void testCreateControlLoops_CommissionedClNotFound() throws Exception {
331 ControlLoops controlLoops = InstantiationUtils
332 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
334 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
336 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
337 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
338 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
342 void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
343 var instantiationProvider =
344 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
345 assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
346 .hasMessageMatching(ORDERED_STATE_INVALID);
350 void testInstantiationVersions() throws Exception {
351 // create controlLoops V1
352 ControlLoops controlLoopsV1 =
353 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
354 assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
356 var instantiationProvider =
357 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
359 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
362 // create controlLoops V2
363 ControlLoops controlLoopsV2 =
364 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
365 assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
366 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
369 // GET controlLoops V2
370 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
371 ControlLoops controlLoopsGet =
372 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
373 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
374 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
377 // DELETE controlLoops V1
378 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
379 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
382 // GET controlLoops V1 is not available
383 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
384 ControlLoops controlLoopsGet =
385 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
386 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
389 // GET controlLoops V2 is still available
390 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
391 ControlLoops controlLoopsGet =
392 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
393 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
394 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
397 // DELETE controlLoops V2
398 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
399 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
402 // GET controlLoops V2 is not available
403 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
404 ControlLoops controlLoopsGet =
405 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
406 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
410 private synchronized void deleteEntryInDB(String name, String version) throws Exception {
411 if (!modelsProvider.getServiceTemplateList(null, null).isEmpty()) {
412 modelsProvider.deleteServiceTemplate(name, version);
416 private synchronized void createEntryInDB() throws Exception {
418 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
419 modelsProvider.createServiceTemplate(serviceTemplate);
420 } catch (Exception e) {