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
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.acm.runtime.instantiation.rest;
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;
31 import jakarta.ws.rs.client.Entity;
32 import jakarta.ws.rs.core.MediaType;
33 import jakarta.ws.rs.core.Response;
34 import java.util.UUID;
35 import org.junit.jupiter.api.BeforeAll;
36 import org.junit.jupiter.api.BeforeEach;
37 import org.junit.jupiter.api.Test;
38 import org.junit.jupiter.api.extension.ExtendWith;
39 import org.onap.policy.clamp.acm.runtime.instantiation.AutomationCompositionInstantiationProvider;
40 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
41 import org.onap.policy.clamp.acm.runtime.main.rest.InstantiationController;
42 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
43 import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
44 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
45 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
46 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
47 import org.onap.policy.clamp.models.acm.concepts.DeployState;
48 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
49 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
50 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
51 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
52 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
53 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
54 import org.springframework.beans.factory.annotation.Autowired;
55 import org.springframework.boot.test.context.SpringBootTest;
56 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
57 import org.springframework.boot.test.web.server.LocalServerPort;
58 import org.springframework.data.domain.Pageable;
59 import org.springframework.test.context.ActiveProfiles;
60 import org.springframework.test.context.junit.jupiter.SpringExtension;
63 * Class to perform unit test of {@link InstantiationController}}.
66 @ExtendWith(SpringExtension.class)
67 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
68 @ActiveProfiles({ "test", "default" })
69 class InstantiationControllerTest extends CommonRestController {
71 private static final int NUMBER_ISTANCES = 10;
72 private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
73 private static final String AC_VERSIONING_YAML = "src/test/resources/rest/acm/AutomationCompositionVersioning.yaml";
75 private static final String AC_INSTANTIATION_UPDATE_JSON =
76 "src/test/resources/rest/acm/AutomationCompositionUpdate.json";
78 private static final String INSTANTIATION_ENDPOINT = "compositions/%s/instances";
80 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
82 private static final String NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition";
85 private AcDefinitionProvider acDefinitionProvider;
88 private ParticipantProvider participantProvider;
91 private AutomationCompositionInstantiationProvider instantiationProvider;
94 private int randomServerPort;
97 static void setUpBeforeClass() {
98 serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
103 super.setHttpPrefix(randomServerPort);
106 private String getInstanceEndPoint(UUID compositionId) {
107 return String.format(INSTANTIATION_ENDPOINT, compositionId.toString());
110 private String getInstanceEndPoint(UUID compositionId, UUID instanceId) {
111 return String.format(INSTANTIATION_ENDPOINT, compositionId.toString()) + "/" + instanceId;
116 super.testSwagger(String.format(INSTANTIATION_ENDPOINT, "{compositionId}"));
120 void testCreate_Unauthorized() {
121 var automationComposition =
122 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Unauthorized");
124 assertUnauthorizedPost(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
128 void testQuery_Unauthorized() {
129 assertUnauthorizedGet(getInstanceEndPoint(UUID.randomUUID()));
133 void testUpdate_Unauthorized() {
134 var automationComposition =
135 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Unauthorized");
137 assertUnauthorizedPut(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
141 void testDelete_Unauthorized() {
142 assertUnauthorizedDelete(getInstanceEndPoint(UUID.randomUUID()));
147 var compositionId = createAcDefinitionInDB("Create");
148 var automationCompositionFromRsc =
149 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Create");
150 automationCompositionFromRsc.setCompositionId(compositionId);
152 var instResponse = createAutomationComposition(compositionId, automationCompositionFromRsc,
153 Response.Status.CREATED);
154 InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
155 automationCompositionFromRsc.setInstanceId(instResponse.getInstanceId());
156 automationCompositionFromRsc.getElements().values()
157 .forEach(element -> element.setParticipantId(CommonTestData.getParticipantId()));
159 var automationCompositionFromDb =
160 instantiationProvider.getAutomationComposition(compositionId, instResponse.getInstanceId());
161 automationCompositionFromRsc.setLastMsg(automationCompositionFromDb.getLastMsg());
163 assertNotNull(automationCompositionFromDb);
164 assertEquals(automationCompositionFromRsc, automationCompositionFromDb);
167 private InstantiationResponse createAutomationComposition(UUID compositionId,
168 AutomationComposition automationComposition, Response.Status statusExpected) {
169 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
170 try (var resp = invocationBuilder.post(Entity.json(automationComposition))) {
171 assertEquals(statusExpected.getStatusCode(), resp.getStatus());
172 return resp.readEntity(InstantiationResponse.class);
177 void testCreateBadRequest() {
178 var compositionId = createAcDefinitionInDB("CreateBadRequest");
179 var automationCompositionFromRsc = InstantiationUtils
180 .getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "CreateBadRequest");
181 automationCompositionFromRsc.setCompositionId(compositionId);
183 createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
185 // testing Bad Request: AC already defined
186 var instResponse = createAutomationComposition(compositionId, automationCompositionFromRsc,
187 Response.Status.BAD_REQUEST);
188 assertNotNull(instResponse.getErrorDetails());
189 assertNull(instResponse.getAffectedAutomationComposition());
193 void testVersioning() {
194 var serviceTemplateVer = InstantiationUtils.getToscaServiceTemplate(TOSCA_VERSIONING);
195 var compositionId = createAcDefinitionInDB(serviceTemplateVer);
196 var automationCompositionFromRsc = InstantiationUtils
197 .getAutomationCompositionFromYaml(AC_VERSIONING_YAML, "Versioning");
198 automationCompositionFromRsc.setCompositionId(compositionId);
200 createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
201 InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
205 void testQuery_NoResultWithThisName() {
206 var invocationBuilder =
207 super.sendRequest(getInstanceEndPoint(UUID.randomUUID()) + "?name=noResultWithThisName");
208 try (var rawresp = invocationBuilder.buildGet().invoke()) {
209 assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
210 var resp = rawresp.readEntity(AutomationCompositions.class);
211 assertThat(resp.getAutomationCompositionList()).isEmpty();
217 var compositionId = createAcDefinitionInDB("Query");
218 var automationComposition =
219 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
220 automationComposition.setCompositionId(compositionId);
222 instantiationProvider.createAutomationComposition(compositionId, automationComposition);
224 var invocationBuilder = super.sendRequest(
225 getInstanceEndPoint(compositionId) + "?name=" + automationComposition.getKey().getName());
226 try (var rawresp = invocationBuilder.buildGet().invoke()) {
227 assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
228 var automationCompositionsQuery = rawresp.readEntity(AutomationCompositions.class);
229 assertNotNull(automationCompositionsQuery);
230 assertThat(automationCompositionsQuery.getAutomationCompositionList()).hasSize(1);
231 var automationCompositionRc = automationCompositionsQuery.getAutomationCompositionList().get(0);
232 automationComposition.setLastMsg(automationCompositionRc.getLastMsg());
233 assertEquals(automationComposition, automationCompositionRc);
238 void testQueryPageable() {
239 var compositionId = createAcDefinitionInDB("Query");
240 var automationComposition =
241 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
242 automationComposition.setCompositionId(compositionId);
243 for (var i = 0; i < NUMBER_ISTANCES; i++) {
244 automationComposition.setName("acm_" + i);
245 instantiationProvider.createAutomationComposition(compositionId, automationComposition);
247 var endpoint = getInstanceEndPoint(compositionId);
248 validateQueryPageable(endpoint + "?name=wrong_name", 0);
249 validateQueryPageable(endpoint + "?name=acm_1", 1);
250 validateQueryPageable(endpoint + "?page=1&size=4", 4);
252 validateQueryNotPageable(endpoint + "?page=0");
253 validateQueryNotPageable(endpoint + "?size=5");
254 validateQueryNotPageable(endpoint);
257 private void validateQueryNotPageable(String link) {
258 var invocationBuilder = super.sendRequest(link);
259 try (var response = invocationBuilder.buildGet().invoke()) {
260 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
261 var resultList = response.readEntity(AutomationCompositions.class);
262 assertNotNull(resultList);
263 assertThat(resultList.getAutomationCompositionList()).hasSizeGreaterThanOrEqualTo(NUMBER_ISTANCES);
267 private void validateQueryPageable(String link, int size) {
268 var invocationBuilder = super.sendRequest(link);
269 try (var response = invocationBuilder.buildGet().invoke()) {
270 assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
271 var resultList = response.readEntity(AutomationCompositions.class);
272 assertNotNull(resultList);
273 assertThat(resultList.getAutomationCompositionList()).hasSize(size);
279 var compositionId = createAcDefinitionInDB("Get");
280 var automationComposition =
281 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Get");
282 automationComposition.setCompositionId(compositionId);
284 instantiationProvider.createAutomationComposition(compositionId, automationComposition);
286 var invocationBuilder = super.sendRequest(
287 getInstanceEndPoint(compositionId, automationComposition.getInstanceId()));
288 var rawresp = invocationBuilder.buildGet().invoke();
289 assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
290 var automationCompositionGet = rawresp.readEntity(AutomationComposition.class);
292 assertNotNull(automationCompositionGet);
293 automationComposition.setLastMsg(automationCompositionGet.getLastMsg());
294 assertEquals(automationComposition, automationCompositionGet);
299 var compositionId = createAcDefinitionInDB("Update");
300 var automationCompositionCreate =
301 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Update");
302 automationCompositionCreate.setCompositionId(compositionId);
304 var response = instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate);
306 var automationComposition =
307 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Update");
308 automationComposition.setCompositionId(compositionId);
309 automationComposition.setInstanceId(response.getInstanceId());
310 automationComposition.getElements().values()
311 .forEach(element -> element.setParticipantId(CommonTestData.getParticipantId()));
313 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
314 try (var resp = invocationBuilder.post(Entity.json(automationComposition))) {
315 assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
317 var instResponse = resp.readEntity(InstantiationResponse.class);
318 InstantiationUtils.assertInstantiationResponse(instResponse, automationComposition);
320 var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
321 compositionId, automationComposition.getKey().getName(),
322 automationComposition.getKey().getVersion(), Pageable.unpaged());
324 assertNotNull(automationCompositionsFromDb);
325 assertThat(automationCompositionsFromDb.getAutomationCompositionList()).hasSize(1);
326 var acFromDb = automationCompositionsFromDb.getAutomationCompositionList().get(0);
327 automationComposition.setLastMsg(acFromDb.getLastMsg());
328 automationComposition.setRevisionId(acFromDb.getRevisionId());
329 assertEquals(automationComposition, acFromDb);
334 var compositionId = createAcDefinitionInDB("Delete");
335 var automationCompositionFromRsc =
336 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
337 automationCompositionFromRsc.setCompositionId(compositionId);
340 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
342 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
343 try (var resp = invocationBuilder.delete()) {
344 assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
345 instResponse = resp.readEntity(InstantiationResponse.class);
347 InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
349 var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(compositionId,
350 automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion(),
352 assertEquals(DeployState.DELETING,
353 automationCompositionsFromDb.getAutomationCompositionList().get(0).getDeployState());
357 void testDeleteNotFound() {
358 var compositionId = createAcDefinitionInDB("DeleteNotFound");
359 var automationCompositionFromRsc =
360 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "DelNotFound");
361 automationCompositionFromRsc.setCompositionId(compositionId);
363 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
365 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
366 try (var resp = invocationBuilder.delete()) {
367 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
372 void testRollbackNotValid() {
373 var compositionId = createAcDefinitionInDB("RollbackNotFound");
375 // instance not found
376 var url = getInstanceEndPoint(compositionId, UUID.randomUUID()) + "/rollback";
377 var invocationBuilder = super.sendRequest(url);
378 try (var resp = invocationBuilder.post(Entity.entity("", MediaType.APPLICATION_JSON))) {
379 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
382 // instance not valid state
383 var automationCompositionFromRsc =
384 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "NotValid");
385 automationCompositionFromRsc.setCompositionId(compositionId);
386 var instanceResponce =
387 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
388 url = getInstanceEndPoint(compositionId, instanceResponce.getInstanceId()) + "/rollback";
389 invocationBuilder = super.sendRequest(url);
390 try (var resp = invocationBuilder.post(Entity.entity("", MediaType.APPLICATION_JSON))) {
391 assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
396 void testDeploy_NotFound() {
397 var compositionId = createAcDefinitionInDB("Deploy_NotFound");
398 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
399 try (var resp = invocationBuilder.put(Entity.json(new AcInstanceStateUpdate()))) {
400 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
405 void testDeploy_BadRequest() {
406 var compositionId = createAcDefinitionInDB("Deploy_BadRequest");
408 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "BadRequest");
409 acFromRsc.setCompositionId(compositionId);
411 var instResponse = instantiationProvider.createAutomationComposition(compositionId, acFromRsc);
413 var command = new AcInstanceStateUpdate();
414 command.setDeployOrder(null);
415 command.setLockOrder(null);
417 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
418 try (var resp = invocationBuilder.put(Entity.json(command))) {
419 assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
425 var compositionId = createAcDefinitionInDB("Deploy");
426 var automationComposition =
427 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Command");
428 automationComposition.setCompositionId(compositionId);
429 var instResponse = instantiationProvider.createAutomationComposition(compositionId, automationComposition);
431 var instantiationUpdate = new AcInstanceStateUpdate();
432 instantiationUpdate.setDeployOrder(DeployOrder.DEPLOY);
433 instantiationUpdate.setLockOrder(null);
435 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
436 try (var resp = invocationBuilder.put(Entity.json(instantiationUpdate))) {
437 assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
441 private UUID createAcDefinitionInDB(String name) {
442 var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate);
443 serviceTemplateCreate.setName(name);
444 return createAcDefinitionInDB(serviceTemplateCreate);
447 private UUID createAcDefinitionInDB(ToscaServiceTemplate serviceTemplateCreate) {
448 var acmDefinition = CommonTestData.createAcDefinition(serviceTemplateCreate, AcTypeState.PRIMED);
449 acDefinitionProvider.updateAcDefinition(acmDefinition, NODE_TYPE);
450 saveDummyParticipantInDb();
451 return acmDefinition.getCompositionId();
454 private void saveDummyParticipantInDb() {
455 var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
456 var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId());
457 participant.getReplicas().put(replica.getReplicaId(), replica);
458 participantProvider.saveParticipant(participant);