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;
29 import static org.mockito.Mockito.mock;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import org.junit.jupiter.api.AfterAll;
34 import org.junit.jupiter.api.AfterEach;
35 import org.junit.jupiter.api.BeforeAll;
36 import org.junit.jupiter.api.BeforeEach;
37 import org.junit.jupiter.api.Test;
38 import org.mockito.Mockito;
39 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
40 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
41 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
42 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
43 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
44 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
45 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
46 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
47 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
48 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
49 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
50 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
51 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
52 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
53 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
54 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
55 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher;
56 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpdatePublisher;
57 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
58 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
59 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
60 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
61 import org.onap.policy.models.base.PfModelException;
62 import org.onap.policy.models.provider.PolicyModelsProvider;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
64 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
67 * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
70 class ControlLoopInstantiationProviderTest {
71 private static final String ID_NAME = "PMSH_Instance1";
72 private static final String ID_VERSION = "1.2.3";
73 private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
74 private static final String CL_INSTANTIATION_UPDATE_JSON =
75 "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
76 private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
77 "src/test/resources/rest/controlloops/PassiveCommand.json";
78 private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
79 "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
80 private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
81 "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
82 private static final String TOSCA_TEMPLATE_YAML =
83 "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
84 private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
85 private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
86 private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
87 private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
88 "\"ControlLoops\" INVALID, item has status INVALID\n"
89 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
90 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"
91 + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
92 + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
94 private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
95 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
96 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
97 + " Commissioned control loop definition not FOUND\n"
98 + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
99 + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
100 + " Commissioned control loop definition not FOUND\n";
102 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
104 private static SupervisionHandler supervisionHandler;
105 private static CommissioningProvider commissioningProvider;
106 private static ControlLoopProvider clProvider;
107 private static PolicyModelsProvider modelsProvider;
108 private static ParticipantProvider participantProvider;
111 public static void setUpBeforeClass() throws Exception {
112 serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
116 * setup Db Provider Parameters.
118 * @throws PfModelException if an error occurs
121 public static void setupDbProviderParameters() throws PfModelException {
122 ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
124 modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
125 clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
126 participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
128 var participantStatisticsProvider = Mockito.mock(ParticipantStatisticsProvider.class);
129 var clElementStatisticsProvider = mock(ClElementStatisticsProvider.class);
130 commissioningProvider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider), clProvider, null,
131 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 var serviceTemplateProvider = Mockito.mock(ServiceTemplateProvider.class);
142 supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
143 serviceTemplateProvider, controlLoopUpdatePublisher, controlLoopStateChangePublisher,
144 participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
148 public void populateDb() throws Exception {
153 public static void closeDbProvider() throws PfModelException {
155 modelsProvider.close();
159 public void cleanDatabase() throws Exception {
160 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
164 void testIntanceResponses() throws PfModelException {
165 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
166 supervisionHandler, participantProvider);
167 var instancePropertyList = instantiationProvider.createInstanceProperties(serviceTemplate);
168 assertNull(instancePropertyList.getErrorDetails());
169 var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION);
170 assertEquals(id, instancePropertyList.getAffectedInstanceProperties().get(0));
171 var instanceOrderState = instantiationProvider.getInstantiationOrderState(ID_NAME, ID_VERSION);
172 assertEquals(ControlLoopOrderedState.UNINITIALISED, instanceOrderState.getOrderedState());
173 assertEquals(ID_NAME, instanceOrderState.getControlLoopIdentifierList().get(0).getName());
175 assertNotNull(clProvider.getControlLoop(id));
176 var instanceResponse = instantiationProvider.deleteInstanceProperties(ID_NAME, ID_VERSION);
177 assertEquals(ID_NAME, instanceResponse.getAffectedControlLoops().get(0).getName());
178 assertNull(clProvider.getControlLoop(id));
182 void testInstantiationCrud() throws Exception {
183 participantProvider.createParticipants(CommonTestData.createParticipants());
185 ControlLoops controlLoopsCreate =
186 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
187 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
188 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
189 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
190 supervisionHandler, participantProvider);
191 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
192 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
194 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
195 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
196 assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
198 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
199 ControlLoops controlLoopsGet =
200 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
201 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
202 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
205 ControlLoops controlLoopsUpdate =
206 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
207 assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
209 instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
210 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
212 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
213 assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
214 assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
216 InstantiationCommand instantiationCommand =
217 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
218 instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
219 InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
221 for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
222 ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
223 toscaConceptIdentifier.getVersion());
224 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
225 assertThat(instantiationCommand.getOrderedState())
226 .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
229 // in order to delete a controlLoop the state must be UNINITIALISED
230 controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
231 instantiationProvider.updateControlLoops(controlLoopsCreate);
233 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
234 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
237 controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
238 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
241 private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
243 ControlLoops controlLoopsDb = new ControlLoops();
244 controlLoopsDb.setControlLoopList(new ArrayList<>());
246 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
247 supervisionHandler, participantProvider);
249 for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
250 ControlLoops controlLoopsFromDb =
251 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
252 controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
254 return controlLoopsDb;
258 void testInstantiationDelete() throws Exception {
260 ControlLoops controlLoops =
261 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
262 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
264 ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
266 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
267 supervisionHandler, participantProvider);
270 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
271 .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
273 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
276 for (ControlLoopState state : ControlLoopState.values()) {
277 if (!ControlLoopState.UNINITIALISED.equals(state)) {
278 assertThatDeleteThrownBy(controlLoops, state);
282 controlLoop0.setState(ControlLoopState.UNINITIALISED);
283 instantiationProvider.updateControlLoops(controlLoops);
285 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
286 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
289 for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
290 ControlLoops controlLoopsGet =
291 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
292 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
296 private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
297 ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
299 controlLoop.setState(state);
301 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
302 supervisionHandler, participantProvider);
304 instantiationProvider.updateControlLoops(controlLoops);
306 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
307 .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
311 void testCreateControlLoops_NoDuplicates() throws Exception {
313 ControlLoops controlLoopsCreate =
314 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
316 ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
317 assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
319 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
320 supervisionHandler, participantProvider);
322 InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
323 InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
325 assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
326 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
328 for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
329 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
334 void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
336 ControlLoops controlLoops = InstantiationUtils
337 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
339 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
340 participantProvider);
342 // to validate control Loop, it needs to define ToscaServiceTemplate
343 // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
345 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
347 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
348 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
352 void testCreateControlLoops_CommissionedClNotFound() throws Exception {
353 ControlLoops controlLoops = InstantiationUtils
354 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
356 assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
358 var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler,
359 participantProvider);
360 assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
361 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
365 void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
366 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
367 supervisionHandler, participantProvider);
368 assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
369 .hasMessageMatching(ORDERED_STATE_INVALID);
373 void testInstantiationVersions() throws Exception {
374 // create controlLoops V1
375 ControlLoops controlLoopsV1 =
376 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
377 assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
379 var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider,
380 supervisionHandler, participantProvider);
382 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
385 // create controlLoops V2
386 ControlLoops controlLoopsV2 =
387 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
388 assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
389 InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
392 // GET controlLoops V2
393 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
394 ControlLoops controlLoopsGet =
395 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
396 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
397 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
400 // DELETE controlLoops V1
401 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
402 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
405 // GET controlLoops V1 is not available
406 for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
407 ControlLoops controlLoopsGet =
408 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
409 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
412 // GET controlLoops V2 is still available
413 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
414 ControlLoops controlLoopsGet =
415 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
416 assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
417 assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
420 // DELETE controlLoops V2
421 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
422 instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
425 // GET controlLoops V2 is not available
426 for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
427 ControlLoops controlLoopsGet =
428 instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
429 assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
433 private synchronized void deleteEntryInDB(String name, String version) throws Exception {
434 if (!modelsProvider.getServiceTemplateList(null, null).isEmpty()) {
435 modelsProvider.deleteServiceTemplate(name, version);
439 private synchronized void createEntryInDB() throws Exception {
441 deleteEntryInDB(serviceTemplate.getName(), serviceTemplate.getVersion());
442 modelsProvider.createServiceTemplate(serviceTemplate);
443 } catch (Exception e) {