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.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;
62 * Class to perform unit test of {@link InstantiationController}}.
65 @ExtendWith(SpringExtension.class)
66 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
67 @ActiveProfiles({ "test", "default" })
68 class InstantiationControllerTest extends CommonRestController {
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";
74 private static final String AC_INSTANTIATION_UPDATE_JSON =
75 "src/test/resources/rest/acm/AutomationCompositionUpdate.json";
77 private static final String INSTANTIATION_ENDPOINT = "compositions/%s/instances";
79 private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
81 private static final String NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition";
84 private AcDefinitionProvider acDefinitionProvider;
87 private ParticipantProvider participantProvider;
90 private AutomationCompositionInstantiationProvider instantiationProvider;
93 private int randomServerPort;
96 public static void setUpBeforeClass() {
97 serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
101 public void setUpPort() {
102 super.setHttpPrefix(randomServerPort);
105 private String getInstanceEndPoint(UUID compositionId) {
106 return String.format(INSTANTIATION_ENDPOINT, compositionId.toString());
109 private String getInstanceEndPoint(UUID compositionId, UUID instanceId) {
110 return String.format(INSTANTIATION_ENDPOINT, compositionId.toString()) + "/" + instanceId;
115 super.testSwagger(String.format(INSTANTIATION_ENDPOINT, "{compositionId}"));
119 void testCreate_Unauthorized() {
120 var automationComposition =
121 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Unauthorized");
123 assertUnauthorizedPost(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
127 void testQuery_Unauthorized() {
128 assertUnauthorizedGet(getInstanceEndPoint(UUID.randomUUID()));
132 void testUpdate_Unauthorized() {
133 var automationComposition =
134 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Unauthorized");
136 assertUnauthorizedPut(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
140 void testDelete_Unauthorized() {
141 assertUnauthorizedDelete(getInstanceEndPoint(UUID.randomUUID()));
146 var compositionId = createAcDefinitionInDB("Create");
147 var automationCompositionFromRsc =
148 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Create");
149 automationCompositionFromRsc.setCompositionId(compositionId);
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()));
158 var automationCompositionFromDb =
159 instantiationProvider.getAutomationComposition(compositionId, instResponse.getInstanceId());
160 automationCompositionFromRsc.setLastMsg(automationCompositionFromDb.getLastMsg());
162 assertNotNull(automationCompositionFromDb);
163 assertEquals(automationCompositionFromRsc, automationCompositionFromDb);
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);
176 void testCreateBadRequest() {
177 var compositionId = createAcDefinitionInDB("CreateBadRequest");
178 var automationCompositionFromRsc = InstantiationUtils
179 .getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "CreateBadRequest");
180 automationCompositionFromRsc.setCompositionId(compositionId);
182 createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
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());
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);
199 createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
200 InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
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();
216 var compositionId = createAcDefinitionInDB("Query");
217 var automationComposition =
218 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
219 automationComposition.setCompositionId(compositionId);
221 instantiationProvider.createAutomationComposition(compositionId, automationComposition);
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);
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);
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);
251 validateQueryNotPageable(endpoint + "?page=0");
252 validateQueryNotPageable(endpoint + "?size=5");
253 validateQueryNotPageable(endpoint);
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);
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);
278 var compositionId = createAcDefinitionInDB("Get");
279 var automationComposition =
280 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Get");
281 automationComposition.setCompositionId(compositionId);
283 instantiationProvider.createAutomationComposition(compositionId, automationComposition);
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);
297 var compositionId = createAcDefinitionInDB("Update");
298 var automationCompositionCreate =
299 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Update");
300 automationCompositionCreate.setCompositionId(compositionId);
302 var response = instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate);
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()));
311 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
312 var resp = invocationBuilder.post(Entity.json(automationComposition));
313 assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
315 var instResponse = resp.readEntity(InstantiationResponse.class);
316 InstantiationUtils.assertInstantiationResponse(instResponse, automationComposition);
318 var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
319 compositionId, automationComposition.getKey().getName(),
320 automationComposition.getKey().getVersion(), Pageable.unpaged());
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);
331 var compositionId = createAcDefinitionInDB("Delete");
332 var automationCompositionFromRsc =
333 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
334 automationCompositionFromRsc.setCompositionId(compositionId);
337 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
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);
345 var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(compositionId,
346 automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion(),
348 assertEquals(DeployState.DELETING,
349 automationCompositionsFromDb.getAutomationCompositionList().get(0).getDeployState());
353 void testDeleteNotFound() {
354 var compositionId = createAcDefinitionInDB("DeleteNotFound");
355 var automationCompositionFromRsc =
356 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "DelNotFound");
357 automationCompositionFromRsc.setCompositionId(compositionId);
359 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
361 var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
362 var resp = invocationBuilder.delete();
363 assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
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());
375 void testDeploy_BadRequest() {
376 var compositionId = createAcDefinitionInDB("Deploy_BadRequest");
378 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "BadRequest");
379 acFromRsc.setCompositionId(compositionId);
381 var instResponse = instantiationProvider.createAutomationComposition(compositionId, acFromRsc);
383 var command = new AcInstanceStateUpdate();
384 command.setDeployOrder(null);
385 command.setLockOrder(null);
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());
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);
400 var instantiationUpdate = new AcInstanceStateUpdate();
401 instantiationUpdate.setDeployOrder(DeployOrder.DEPLOY);
402 instantiationUpdate.setLockOrder(null);
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());
409 private UUID createAcDefinitionInDB(String name) {
410 var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate);
411 serviceTemplateCreate.setName(name);
412 return createAcDefinitionInDB(serviceTemplateCreate);
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();
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);