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.controlloop.persistence.provider.ServiceTemplateProvider;
44 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
45 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
46 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
47 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
48 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
49 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
50 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher;
51 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpdatePublisher;
52 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
53 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
54 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
55 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
56 import org.onap.policy.models.base.PfModelException;
57 import org.onap.policy.models.provider.PolicyModelsProvider;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
62 * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
65 class ControlLoopInstantiationProviderTest {
67 private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
68 private static final String CL_INSTANTIATION_UPDATE_JSON =
69 "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
70 private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
71 "src/test/resources/rest/controlloops/PassiveCommand.json";
72 private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
73 "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
74 private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
75 "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
76 private static final String TOSCA_TEMPLATE_YAML =
77 "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
78 private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
79 private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
80 private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
81 private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
82 "\"ControlLoops\" INVALID, item has status INVALID\n"
83 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
84 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\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";
88 private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
89 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
90 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
91 + " Commissioned control loop definition not FOUND\n"
92 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
93 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
94 + " Commissioned control loop definition not FOUND\n";
96 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
98 private static SupervisionHandler supervisionHandler;
99 private static CommissioningProvider commissioningProvider;
100 private static ControlLoopProvider clProvider;
101 private static PolicyModelsProvider modelsProvider;
102 private static ParticipantProvider participantProvider;
105 public static void setUpBeforeClass() throws Exception {
106 serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
110 * setup Db Provider Parameters.
112 * @throws PfModelException if an error occurs
115 public static void setupDbProviderParameters() throws PfModelException {
116 ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
118 modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
119 clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
120 participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
122 var participantStatisticsProvider =
123 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
124 var clElementStatisticsProvider =
125 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
126 commissioningProvider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider), clProvider, null,
127 participantProvider);
128 var monitoringProvider =
129 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
130 var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
131 var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
132 var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
133 var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
134 var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
135 var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
136 supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
137 controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
138 participantDeregisterAckPublisher, participantUpdatePublisher);
142 public void populateDb() throws Exception {
147 public static void closeDbProvider() throws PfModelException {
149 modelsProvider.close();
153 public void cleanDatabase() throws Exception {
154 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
158 void testInstantiationCrud() throws Exception {
159 participantProvider.createParticipants(CommonTestData.createParticipants());
161 ControlLoops controlLoopsCreate =
162 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
163 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
164 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
165 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
166 supervisionHandler, participantProvider);
167 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
168 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
170 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
171 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
172 assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
174 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
175 ControlLoops controlLoopsGet =
176 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
177 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
178 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
181 ControlLoops controlLoopsUpdate =
182 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
183 assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
185 instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
186 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
188 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
189 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
190 assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
192 InstantiationCommand instantiationCommand =
193 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
194 instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
195 InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
197 for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
198 ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
199 toscaConceptIdentifier.getVersion());
200 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
201 assertThat(instantiationCommand.getOrderedState())
202 .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
205 // in order to delete a controlLoop the state must be UNINITIALISED
206 controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
207 instantiationProvider.updateControlLoops(controlLoopsCreate);
209 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
210 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
213 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
214 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
217 private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
219 ControlLoops controlLoopsDb = new ControlLoops();
220 controlLoopsDb.setControlLoopList(new ArrayList<>());
222 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
223 supervisionHandler, participantProvider);
225 for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
226 ControlLoops controlLoopsFromDb =
227 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
228 controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
230 return controlLoopsDb;
234 void testInstantiationDelete() throws Exception {
236 ControlLoops controlLoops =
237 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
238 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
240 ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
242 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
243 supervisionHandler, participantProvider);
246 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
247 .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
249 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
252 for (ControlLoopState state : ControlLoopState.values()) {
253 if (!ControlLoopState.UNINITIALISED.equals(state)) {
254 assertThatDeleteThrownBy(controlLoops, state);
258 controlLoop0.setState(ControlLoopState.UNINITIALISED);
259 instantiationProvider.updateControlLoops(controlLoops);
261 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
262 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
265 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
266 ControlLoops controlLoopsGet =
267 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
268 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
272 private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
273 ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
275 controlLoop.setState(state);
277 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
278 supervisionHandler, participantProvider);
280 instantiationProvider.updateControlLoops(controlLoops);
282 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
283 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
287 void testCreateControlLoops_NoDuplicates() throws Exception {
289 ControlLoops controlLoopsCreate =
290 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
292 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
293 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
295 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
296 supervisionHandler, participantProvider);
298 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
299 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
301 assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
302 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
304 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
305 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
310 void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
312 ControlLoops controlLoops = InstantiationUtils
313 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
315 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
316 participantProvider);
318 // to validate control Loop, it needs to define ToscaServiceTemplate
319 // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
321 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
323 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
324 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
328 void testCreateControlLoops_CommissionedClNotFound() throws Exception {
329 ControlLoops controlLoops = InstantiationUtils
330 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
332 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
334 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
335 participantProvider);
336 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
337 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
341 void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
342 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
343 supervisionHandler, participantProvider);
344 assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
345 .hasMessageMatching(ORDERED_STATE_INVALID);
349 void testInstantiationVersions() throws Exception {
350 // create controlLoops V1
351 ControlLoops controlLoopsV1 =
352 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
353 assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
355 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
356 supervisionHandler, participantProvider);
358 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
361 // create controlLoops V2
362 ControlLoops controlLoopsV2 =
363 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
364 assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
365 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
368 // GET controlLoops V2
369 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
370 ControlLoops controlLoopsGet =
371 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
372 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
373 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
376 // DELETE controlLoops V1
377 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
378 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
381 // GET controlLoops V1 is not available
382 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
383 ControlLoops controlLoopsGet =
384 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
385 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
388 // GET controlLoops V2 is still available
389 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
390 ControlLoops controlLoopsGet =
391 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
392 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
393 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
396 // DELETE controlLoops V2
397 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
398 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
401 // GET controlLoops V2 is not available
402 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
403 ControlLoops controlLoopsGet =
404 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
405 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
409 private synchronized void deleteEntryInDB(String name, String version) throws Exception {
410 if (!modelsProvider.getServiceTemplateList(null, null).isEmpty()) {
411 modelsProvider.deleteServiceTemplate(name, version);
415 private synchronized void createEntryInDB() throws Exception {
417 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
418 modelsProvider.createServiceTemplate(serviceTemplate);
419 } catch (Exception e) {