b92f341ebf8b426bc339d66c7f9e61a705dfb7f2
[policy/clamp.git] /
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.controlloop.runtime.instantiation;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatThrownBy;
25
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import org.junit.jupiter.api.AfterAll;
29 import org.junit.jupiter.api.BeforeAll;
30 import org.junit.jupiter.api.Test;
31 import org.mockito.Mockito;
32 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
33 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
34 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
36 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
37 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
38 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
39 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
40 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
41 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
42 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
43 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
44 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
45 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
46 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantControlLoopStateChangePublisher;
47 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantControlLoopUpdatePublisher;
48 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
49 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
50 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
51 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
52 import org.onap.policy.models.base.PfModelException;
53 import org.onap.policy.models.provider.PolicyModelsProvider;
54 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
55
56 /**
57  * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
58  *
59  */
60 class ControlLoopInstantiationProviderTest {
61
62     private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
63     private static final String CL_INSTANTIATION_UPDATE_JSON =
64             "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
65     private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
66             "src/test/resources/rest/controlloops/PassiveCommand.json";
67     private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
68             "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
69     private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
70             "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
71     private static final String TOSCA_TEMPLATE_YAML =
72             "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
73     private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
74     private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
75     private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
76     private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
77             "\"ControlLoops\" INVALID, item has status INVALID\n"
78                     + "  \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
79                     + "    \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"
80                     + "  \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
81                     + "    \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
82
83     private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
84             + "  \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
85             + "    item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
86             + " Commissioned control loop definition not FOUND\n"
87             + "  \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
88             + "    item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
89             + " Commissioned control loop definition not FOUND\n";
90
91     private static SupervisionHandler supervisionHandler;
92     private static CommissioningProvider commissioningProvider;
93     private static ControlLoopProvider clProvider;
94     private static PolicyModelsProvider modelsProvider;
95
96     /**
97      * setup Db Provider Parameters.
98      *
99      * @throws PfModelException if an error occurs
100      */
101     @BeforeAll
102     public static void setupDbProviderParameters() throws PfModelException {
103         ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup(0, "instantproviderdb");
104
105         modelsProvider =
106                 CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
107         clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
108         var participantStatisticsProvider =
109                 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
110         var clElementStatisticsProvider =
111                 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
112         commissioningProvider = new CommissioningProvider(modelsProvider, clProvider);
113         var monitoringProvider =
114                 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
115         var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
116         var controlLoopUpdatePublisher = Mockito.mock(ParticipantControlLoopUpdatePublisher.class);
117         var controlLoopStateChangePublisher = Mockito.mock(ParticipantControlLoopStateChangePublisher.class);
118         var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
119         var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
120         var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
121         supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
122                         commissioningProvider, controlLoopUpdatePublisher, controlLoopStateChangePublisher,
123                         participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
124     }
125
126     @AfterAll
127     public static void closeDbProvider() throws PfModelException {
128         clProvider.close();
129         modelsProvider.close();
130     }
131
132     @Test
133     void testInstantiationCrud() throws Exception {
134         ControlLoops controlLoopsCreate =
135                 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
136         ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
137         assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
138         var instantiationProvider =
139                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
140
141         // to validate control Loop, it needs to define ToscaServiceTemplate
142         InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
143
144         InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
145         InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
146
147         controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
148         assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
149         assertThat(controlLoopsCreate).isEqualTo(controlLoopsDb);
150
151         for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
152             ControlLoops controlLoopsGet =
153                     instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
154             assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
155             assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
156         }
157
158         ControlLoops controlLoopsUpdate =
159                 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
160         assertThat(controlLoopsUpdate).isNotEqualTo(controlLoopsDb);
161
162         instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
163         InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
164
165         controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
166         assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
167         assertThat(controlLoopsUpdate).isEqualTo(controlLoopsDb);
168
169         InstantiationCommand instantiationCommand =
170                 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
171         instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
172         InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
173
174         for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
175             ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
176                     toscaConceptIdentifier.getVersion());
177             assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
178             assertThat(instantiationCommand.getOrderedState())
179                     .isEqualTo(controlLoopsGet.getControlLoopList().get(0).getOrderedState());
180         }
181
182         // in order to delete a controlLoop the state must be UNINITIALISED
183         controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
184         instantiationProvider.updateControlLoops(controlLoopsCreate);
185
186         for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
187             instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
188         }
189
190         controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
191         assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
192     }
193
194     private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
195         ControlLoops controlLoopsDb = new ControlLoops();
196         controlLoopsDb.setControlLoopList(new ArrayList<>());
197
198         var instantiationProvider =
199                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
200
201         for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
202             ControlLoops controlLoopsFromDb =
203                     instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
204             controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
205         }
206         return controlLoopsDb;
207     }
208
209     @Test
210     void testInstantiationDelete() throws Exception {
211         ControlLoops controlLoops =
212                 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
213         assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
214
215         ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
216
217         var instantiationProvider =
218                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
219
220         // to validate control Loop, it needs to define ToscaServiceTemplate
221         InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
222
223         assertThatThrownBy(
224                 () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
225                         .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
226
227         InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
228                 controlLoops);
229
230         for (ControlLoopState state : ControlLoopState.values()) {
231             if (!ControlLoopState.UNINITIALISED.equals(state)) {
232                 assertThatDeleteThrownBy(controlLoops, state);
233             }
234         }
235
236         controlLoop0.setState(ControlLoopState.UNINITIALISED);
237         instantiationProvider.updateControlLoops(controlLoops);
238
239         for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
240             instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
241         }
242
243         for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
244             ControlLoops controlLoopsGet =
245                     instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
246             assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
247         }
248     }
249
250     private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
251         ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
252
253         controlLoop.setState(state);
254
255         var instantiationProvider =
256                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
257
258         instantiationProvider.updateControlLoops(controlLoops);
259         assertThatThrownBy(
260                 () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
261                         .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
262     }
263
264     @Test
265     void testCreateControlLoops_NoDuplicates() throws Exception {
266         ControlLoops controlLoopsCreate =
267                 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
268
269         ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
270         assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
271
272         var instantiationProvider =
273                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
274
275         // to validate control Loop, it needs to define ToscaServiceTemplate
276         InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
277
278         InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
279         InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
280
281         assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
282                 controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
283
284         for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
285             instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
286         }
287     }
288
289     @Test
290     void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
291         ControlLoops controlLoops = InstantiationUtils
292                 .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
293
294         var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
295
296         // to validate control Loop, it needs to define ToscaServiceTemplate
297         InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
298
299         assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
300
301         assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
302                 .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
303     }
304
305     @Test
306     void testCreateControlLoops_CommissionedClNotFound() throws Exception {
307         ControlLoops controlLoops = InstantiationUtils
308                 .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
309
310         assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
311
312         var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
313         assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
314                 .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
315     }
316
317     @Test
318     void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
319         var instantiationProvider =
320                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
321         assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
322                 .hasMessageMatching(ORDERED_STATE_INVALID);
323     }
324
325     @Test
326     void testInstantiationVersions() throws Exception {
327
328         // create controlLoops V1
329         ControlLoops controlLoopsV1 =
330                 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
331         assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
332
333         var instantiationProvider =
334                 new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler);
335
336         // to validate control Loop, it needs to define ToscaServiceTemplate
337         InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
338
339         InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
340                 controlLoopsV1);
341
342         // create controlLoops V2
343         ControlLoops controlLoopsV2 =
344                 InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
345         assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
346         InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
347                 controlLoopsV2);
348
349         // GET controlLoops V2
350         for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
351             ControlLoops controlLoopsGet =
352                     instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
353             assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
354             assertThat(controlLoop).isEqualTo(controlLoopsGet.getControlLoopList().get(0));
355         }
356
357         // DELETE controlLoops V1
358         for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
359             instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
360         }
361
362         // GET controlLoops V1 is not available
363         for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
364             ControlLoops controlLoopsGet =
365                     instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
366             assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
367         }
368
369         // GET controlLoops V2 is still available
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));
375         }
376
377         // DELETE controlLoops V2
378         for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
379             instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
380         }
381
382         // GET controlLoops V2 is not available
383         for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
384             ControlLoops controlLoopsGet =
385                     instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
386             assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
387         }
388     }
389 }