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