30286db60a9d8a41aca6f6775a89544a285079ae
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved.
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.clamp.acm.runtime.instantiation.rest;
23
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertNotNull;
27 import static org.junit.jupiter.api.Assertions.assertNull;
28 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
29 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_VERSIONING;
30
31 import jakarta.ws.rs.client.Entity;
32 import jakarta.ws.rs.core.Response;
33 import java.util.UUID;
34 import org.junit.jupiter.api.BeforeAll;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.extension.ExtendWith;
38 import org.onap.policy.clamp.acm.runtime.instantiation.AutomationCompositionInstantiationProvider;
39 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
40 import org.onap.policy.clamp.acm.runtime.main.rest.InstantiationController;
41 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
42 import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
43 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
44 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
45 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
46 import org.onap.policy.clamp.models.acm.concepts.DeployState;
47 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
48 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
49 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
50 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
51 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.boot.test.context.SpringBootTest;
55 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
56 import org.springframework.boot.test.web.server.LocalServerPort;
57 import org.springframework.data.domain.Pageable;
58 import org.springframework.test.context.ActiveProfiles;
59 import org.springframework.test.context.junit.jupiter.SpringExtension;
60
61 /**
62  * Class to perform unit test of {@link InstantiationController}}.
63  *
64  */
65 @ExtendWith(SpringExtension.class)
66 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
67 @ActiveProfiles({ "test", "default" })
68 class InstantiationControllerTest extends CommonRestController {
69
70     private static final int NUMBER_ISTANCES = 10;
71     private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
72     private static final String AC_VERSIONING_YAML = "src/test/resources/rest/acm/AutomationCompositionVersioning.yaml";
73
74     private static final String AC_INSTANTIATION_UPDATE_JSON =
75             "src/test/resources/rest/acm/AutomationCompositionUpdate.json";
76
77     private static final String INSTANTIATION_ENDPOINT = "compositions/%s/instances";
78
79     private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
80
81     private static final String NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition";
82
83     @Autowired
84     private AcDefinitionProvider acDefinitionProvider;
85
86     @Autowired
87     private ParticipantProvider participantProvider;
88
89     @Autowired
90     private AutomationCompositionInstantiationProvider instantiationProvider;
91
92     @LocalServerPort
93     private int randomServerPort;
94
95     @BeforeAll
96     public static void setUpBeforeClass() {
97         serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
98     }
99
100     @BeforeEach
101     public void setUpPort() {
102         super.setHttpPrefix(randomServerPort);
103     }
104
105     private String getInstanceEndPoint(UUID compositionId) {
106         return String.format(INSTANTIATION_ENDPOINT, compositionId.toString());
107     }
108
109     private String getInstanceEndPoint(UUID compositionId, UUID instanceId) {
110         return String.format(INSTANTIATION_ENDPOINT, compositionId.toString()) + "/" + instanceId;
111     }
112
113     @Test
114     void testSwagger() {
115         super.testSwagger(String.format(INSTANTIATION_ENDPOINT, "{compositionId}"));
116     }
117
118     @Test
119     void testCreate_Unauthorized() {
120         var automationComposition =
121                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Unauthorized");
122
123         assertUnauthorizedPost(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
124     }
125
126     @Test
127     void testQuery_Unauthorized() {
128         assertUnauthorizedGet(getInstanceEndPoint(UUID.randomUUID()));
129     }
130
131     @Test
132     void testUpdate_Unauthorized() {
133         var automationComposition =
134                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Unauthorized");
135
136         assertUnauthorizedPut(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
137     }
138
139     @Test
140     void testDelete_Unauthorized() {
141         assertUnauthorizedDelete(getInstanceEndPoint(UUID.randomUUID()));
142     }
143
144     @Test
145     void testCreate() {
146         var compositionId = createAcDefinitionInDB("Create");
147         var automationCompositionFromRsc =
148                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Create");
149         automationCompositionFromRsc.setCompositionId(compositionId);
150
151         var instResponse = createAutomationComposition(compositionId, automationCompositionFromRsc,
152             Response.Status.CREATED);
153         InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
154         automationCompositionFromRsc.setInstanceId(instResponse.getInstanceId());
155         automationCompositionFromRsc.getElements().values()
156                 .forEach(element -> element.setParticipantId(CommonTestData.getParticipantId()));
157
158         var automationCompositionFromDb =
159                 instantiationProvider.getAutomationComposition(compositionId, instResponse.getInstanceId());
160         automationCompositionFromRsc.setLastMsg(automationCompositionFromDb.getLastMsg());
161
162         assertNotNull(automationCompositionFromDb);
163         assertEquals(automationCompositionFromRsc, automationCompositionFromDb);
164     }
165
166     private InstantiationResponse createAutomationComposition(UUID compositionId,
167         AutomationComposition automationComposition, Response.Status statusExpected) {
168         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
169         try (var resp = invocationBuilder.post(Entity.json(automationComposition))) {
170             assertEquals(statusExpected.getStatusCode(), resp.getStatus());
171             return resp.readEntity(InstantiationResponse.class);
172         }
173     }
174
175     @Test
176     void testCreateBadRequest() {
177         var compositionId = createAcDefinitionInDB("CreateBadRequest");
178         var automationCompositionFromRsc = InstantiationUtils
179                 .getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "CreateBadRequest");
180         automationCompositionFromRsc.setCompositionId(compositionId);
181
182         createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
183
184         // testing Bad Request: AC already defined
185         var instResponse = createAutomationComposition(compositionId, automationCompositionFromRsc,
186             Response.Status.BAD_REQUEST);
187         assertNotNull(instResponse.getErrorDetails());
188         assertNull(instResponse.getAffectedAutomationComposition());
189     }
190
191     @Test
192     void testVersioning() {
193         var serviceTemplateVer = InstantiationUtils.getToscaServiceTemplate(TOSCA_VERSIONING);
194         var compositionId = createAcDefinitionInDB(serviceTemplateVer);
195         var automationCompositionFromRsc = InstantiationUtils
196             .getAutomationCompositionFromYaml(AC_VERSIONING_YAML, "Versioning");
197         automationCompositionFromRsc.setCompositionId(compositionId);
198         var instResponse =
199             createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
200         InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
201     }
202
203     @Test
204     void testQuery_NoResultWithThisName() {
205         var invocationBuilder =
206                 super.sendRequest(getInstanceEndPoint(UUID.randomUUID()) + "?name=noResultWithThisName");
207         try (var rawresp = invocationBuilder.buildGet().invoke()) {
208             assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
209             var resp = rawresp.readEntity(AutomationCompositions.class);
210             assertThat(resp.getAutomationCompositionList()).isEmpty();
211         }
212     }
213
214     @Test
215     void testQuery() {
216         var compositionId = createAcDefinitionInDB("Query");
217         var automationComposition =
218                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
219         automationComposition.setCompositionId(compositionId);
220
221         instantiationProvider.createAutomationComposition(compositionId, automationComposition);
222
223         var invocationBuilder = super.sendRequest(
224                 getInstanceEndPoint(compositionId) + "?name=" + automationComposition.getKey().getName());
225         try (var rawresp = invocationBuilder.buildGet().invoke()) {
226             assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
227             var automationCompositionsQuery = rawresp.readEntity(AutomationCompositions.class);
228             assertNotNull(automationCompositionsQuery);
229             assertThat(automationCompositionsQuery.getAutomationCompositionList()).hasSize(1);
230             var automationCompositionRc = automationCompositionsQuery.getAutomationCompositionList().get(0);
231             automationComposition.setLastMsg(automationCompositionRc.getLastMsg());
232             assertEquals(automationComposition, automationCompositionRc);
233         }
234     }
235
236     @Test
237     void testQueryPageable() {
238         var compositionId = createAcDefinitionInDB("Query");
239         var automationComposition =
240             InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
241         automationComposition.setCompositionId(compositionId);
242         for (var i = 0; i < NUMBER_ISTANCES; i++) {
243             automationComposition.setName("acm_" + i);
244             instantiationProvider.createAutomationComposition(compositionId, automationComposition);
245         }
246         var endpoint = getInstanceEndPoint(compositionId);
247         validateQueryPageable(endpoint + "?name=wrong_name", 0);
248         validateQueryPageable(endpoint + "?name=acm_1", 1);
249         validateQueryPageable(endpoint + "?page=1&size=4", 4);
250
251         validateQueryNotPageable(endpoint + "?page=0");
252         validateQueryNotPageable(endpoint + "?size=5");
253         validateQueryNotPageable(endpoint);
254     }
255
256     private void validateQueryNotPageable(String link) {
257         var invocationBuilder = super.sendRequest(link);
258         try (var response = invocationBuilder.buildGet().invoke()) {
259             assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
260             var resultList = response.readEntity(AutomationCompositions.class);
261             assertNotNull(resultList);
262             assertThat(resultList.getAutomationCompositionList()).hasSizeGreaterThanOrEqualTo(NUMBER_ISTANCES);
263         }
264     }
265
266     private void validateQueryPageable(String link, int size) {
267         var invocationBuilder = super.sendRequest(link);
268         try (var response = invocationBuilder.buildGet().invoke()) {
269             assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
270             var resultList = response.readEntity(AutomationCompositions.class);
271             assertNotNull(resultList);
272             assertThat(resultList.getAutomationCompositionList()).hasSize(size);
273         }
274     }
275
276     @Test
277     void testGet() {
278         var compositionId = createAcDefinitionInDB("Get");
279         var automationComposition =
280                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Get");
281         automationComposition.setCompositionId(compositionId);
282
283         instantiationProvider.createAutomationComposition(compositionId, automationComposition);
284
285         var invocationBuilder = super.sendRequest(
286                 getInstanceEndPoint(compositionId, automationComposition.getInstanceId()));
287         var rawresp = invocationBuilder.buildGet().invoke();
288         assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
289         var automationCompositionGet = rawresp.readEntity(AutomationComposition.class);
290         assertNotNull(automationCompositionGet);
291         automationComposition.setLastMsg(automationCompositionGet.getLastMsg());
292         assertEquals(automationComposition, automationCompositionGet);
293     }
294
295     @Test
296     void testUpdate() {
297         var compositionId = createAcDefinitionInDB("Update");
298         var automationCompositionCreate =
299                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Update");
300         automationCompositionCreate.setCompositionId(compositionId);
301
302         var response = instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate);
303
304         var automationComposition =
305                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Update");
306         automationComposition.setCompositionId(compositionId);
307         automationComposition.setInstanceId(response.getInstanceId());
308         automationComposition.getElements().values()
309                 .forEach(element -> element.setParticipantId(CommonTestData.getParticipantId()));
310
311         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
312         var resp = invocationBuilder.post(Entity.json(automationComposition));
313         assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
314
315         var instResponse = resp.readEntity(InstantiationResponse.class);
316         InstantiationUtils.assertInstantiationResponse(instResponse, automationComposition);
317
318         var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
319                 compositionId, automationComposition.getKey().getName(),
320                 automationComposition.getKey().getVersion(), Pageable.unpaged());
321
322         assertNotNull(automationCompositionsFromDb);
323         assertThat(automationCompositionsFromDb.getAutomationCompositionList()).hasSize(1);
324         var acFromDb = automationCompositionsFromDb.getAutomationCompositionList().get(0);
325         automationComposition.setLastMsg(acFromDb.getLastMsg());
326         assertEquals(automationComposition, acFromDb);
327     }
328
329     @Test
330     void testDelete() {
331         var compositionId = createAcDefinitionInDB("Delete");
332         var automationCompositionFromRsc =
333                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
334         automationCompositionFromRsc.setCompositionId(compositionId);
335
336         var instResponse =
337                 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
338
339         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
340         var resp = invocationBuilder.delete();
341         assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
342         instResponse = resp.readEntity(InstantiationResponse.class);
343         InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
344
345         var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(compositionId,
346                 automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion(),
347                 Pageable.unpaged());
348         assertEquals(DeployState.DELETING,
349                 automationCompositionsFromDb.getAutomationCompositionList().get(0).getDeployState());
350     }
351
352     @Test
353     void testDeleteNotFound() {
354         var compositionId = createAcDefinitionInDB("DeleteNotFound");
355         var automationCompositionFromRsc =
356                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "DelNotFound");
357         automationCompositionFromRsc.setCompositionId(compositionId);
358
359         instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
360
361         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
362         var resp = invocationBuilder.delete();
363         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
364     }
365
366     @Test
367     void testDeploy_NotFound() {
368         var compositionId = createAcDefinitionInDB("Deploy_NotFound");
369         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
370         var resp = invocationBuilder.put(Entity.json(new AcInstanceStateUpdate()));
371         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
372     }
373
374     @Test
375     void testDeploy_BadRequest() {
376         var compositionId = createAcDefinitionInDB("Deploy_BadRequest");
377         var acFromRsc =
378                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "BadRequest");
379         acFromRsc.setCompositionId(compositionId);
380
381         var instResponse = instantiationProvider.createAutomationComposition(compositionId, acFromRsc);
382
383         var command = new AcInstanceStateUpdate();
384         command.setDeployOrder(null);
385         command.setLockOrder(null);
386
387         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
388         var resp = invocationBuilder.put(Entity.json(command));
389         assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
390     }
391
392     @Test
393     void testDeploy() {
394         var compositionId = createAcDefinitionInDB("Deploy");
395         var automationComposition =
396                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Command");
397         automationComposition.setCompositionId(compositionId);
398         var instResponse = instantiationProvider.createAutomationComposition(compositionId, automationComposition);
399
400         var instantiationUpdate = new AcInstanceStateUpdate();
401         instantiationUpdate.setDeployOrder(DeployOrder.DEPLOY);
402         instantiationUpdate.setLockOrder(null);
403
404         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
405         var resp = invocationBuilder.put(Entity.json(instantiationUpdate));
406         assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
407     }
408
409     private UUID createAcDefinitionInDB(String name) {
410         var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate);
411         serviceTemplateCreate.setName(name);
412         return createAcDefinitionInDB(serviceTemplateCreate);
413     }
414
415     private UUID createAcDefinitionInDB(ToscaServiceTemplate serviceTemplateCreate) {
416         var acmDefinition = CommonTestData.createAcDefinition(serviceTemplateCreate, AcTypeState.PRIMED);
417         acDefinitionProvider.updateAcDefinition(acmDefinition, NODE_TYPE);
418         saveDummyParticipantInDb();
419         return acmDefinition.getCompositionId();
420     }
421
422     private void saveDummyParticipantInDb() {
423         var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
424         var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId());
425         participant.getReplicas().put(replica.getReplicaId(), replica);
426         participantProvider.saveParticipant(participant);
427     }
428 }