Add ACM interceptor for DME
[nonrtric/plt/rappmanager.git] / rapp-manager-acm / src / test / java / com / oransc / rappmanager / acm / service / AcmDeployerTest.java
1 /*-
2  * ============LICENSE_START======================================================================
3  * Copyright (C) 2023 Nordix Foundation. All rights reserved.
4  * Copyright (C) 2023 OpenInfra Foundation Europe. 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  * ============LICENSE_END========================================================================
18  */
19
20 package com.oransc.rappmanager.acm.service;
21
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.Mockito.never;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
31 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
32 import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError;
33 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
34
35 import com.fasterxml.jackson.core.JsonProcessingException;
36 import com.fasterxml.jackson.databind.ObjectMapper;
37 import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
38 import com.oransc.rappmanager.dme.service.DmeAcmInterceptor;
39 import com.oransc.rappmanager.models.cache.RappCacheService;
40 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
41 import com.oransc.rappmanager.models.rapp.Rapp;
42 import com.oransc.rappmanager.models.rapp.RappEvent;
43 import com.oransc.rappmanager.models.rapp.RappResourceBuilder;
44 import com.oransc.rappmanager.models.rapp.RappResources;
45 import com.oransc.rappmanager.models.rapp.RappState;
46 import com.oransc.rappmanager.models.rappinstance.RappInstance;
47 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
48 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachineConfig;
49 import java.io.IOException;
50 import java.util.UUID;
51 import java.util.stream.Stream;
52 import org.junit.jupiter.api.BeforeAll;
53 import org.junit.jupiter.api.BeforeEach;
54 import org.junit.jupiter.api.Test;
55 import org.junit.jupiter.api.TestInstance;
56 import org.junit.jupiter.params.ParameterizedTest;
57 import org.junit.jupiter.params.provider.Arguments;
58 import org.junit.jupiter.params.provider.MethodSource;
59 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
60 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
61 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
62 import org.onap.policy.clamp.models.acm.concepts.DeployState;
63 import org.onap.policy.clamp.models.acm.concepts.LockState;
64 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
65 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
66 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
67 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
68 import org.springframework.beans.factory.annotation.Autowired;
69 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
70 import org.springframework.boot.test.context.SpringBootTest;
71 import org.springframework.boot.test.mock.mockito.SpyBean;
72 import org.springframework.http.HttpMethod;
73 import org.springframework.http.HttpStatus;
74 import org.springframework.http.MediaType;
75 import org.springframework.test.web.client.ExpectedCount;
76 import org.springframework.test.web.client.MockRestServiceServer;
77 import org.springframework.web.client.RestTemplate;
78
79 @SpringBootTest(
80         classes = {BeanTestConfiguration.class, ACMConfiguration.class, AcmDeployer.class, DmeAcmInterceptor.class,
81                 RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class,
82                 RappInstanceStateMachine.class})
83 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
84 @AutoConfigureMockMvc
85 class AcmDeployerTest {
86
87     MockRestServiceServer mockServer;
88     @SpyBean
89     AcmDeployer acmDeployer;
90     @Autowired
91     RestTemplate restTemplate;
92     @Autowired
93     ACMConfiguration acmConfiguration;
94     @SpyBean
95     RappInstanceStateMachine rappInstanceStateMachine;
96     @Autowired
97     RappCsarConfigurationHandler rappCsarConfigurationHandler;
98     @Autowired
99     ObjectMapper objectMapper;
100
101     RappResourceBuilder rappResourceBuilder = new RappResourceBuilder();
102     private final String validRappFile = "valid-rapp-package.csar";
103     String validCsarFileLocation = "src/test/resources/";
104     String URI_ACM_COMPOSITIONS, URI_ACM_COMPOSITION, URI_ACM_INSTANCES, URI_ACM_INSTANCE;
105
106     @BeforeAll
107     void initACMURI() {
108         URI_ACM_COMPOSITIONS = acmConfiguration.getBaseUrl() + "compositions";
109         URI_ACM_COMPOSITION = acmConfiguration.getBaseUrl() + "compositions/%s";
110         URI_ACM_INSTANCES = acmConfiguration.getBaseUrl() + "compositions/%s/instances";
111         URI_ACM_INSTANCE = acmConfiguration.getBaseUrl() + "compositions/%s/instances/%s";
112     }
113
114     @BeforeEach
115     public void init() {
116         mockServer = MockRestServiceServer.createServer(restTemplate);
117     }
118
119     @Test
120     void testCreateComposition() throws IOException {
121         RappResources rappResources = rappResourceBuilder.getResources();
122         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
123                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
124                             .rappResources(rappResources).build();
125
126         String compositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
127
128         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
129         commissioningResponseExpected.setCompositionId(UUID.randomUUID());
130         mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
131                 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
132                                     .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
133         CommissioningResponse commissioningResponseActual = acmDeployer.createComposition(compositionPayload);
134         mockServer.verify();
135         assertEquals(commissioningResponseActual.getCompositionId(), commissioningResponseExpected.getCompositionId());
136     }
137
138     @Test
139     void testCreateCompositionFailure() {
140         RappResources rappResources = rappResourceBuilder.getResources();
141         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
142                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
143                             .rappResources(rappResources).build();
144         String compositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
145         mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
146                 .andRespond(withStatus(HttpStatus.BAD_GATEWAY));
147         CommissioningResponse commissioningResponseActual = acmDeployer.createComposition(compositionPayload);
148         mockServer.verify();
149         assertNull(commissioningResponseActual);
150     }
151
152     @Test
153     void testCompositionPriming() {
154         UUID compositionId = UUID.randomUUID();
155         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
156                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
157
158         acmDeployer.primeACMComposition(compositionId, PrimeOrder.PRIME);
159         mockServer.verify();
160     }
161
162     @Test
163     void testDeployRappInstance() throws Exception {
164
165         UUID compositionId = UUID.randomUUID();
166         UUID rappId = UUID.randomUUID();
167         UUID instanceId = UUID.randomUUID();
168         Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
169                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
170         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
171         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
172         InstantiationResponse instantiationResponse = new InstantiationResponse();
173         instantiationResponse.setInstanceId(instanceId);
174         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
175                 .andExpect(method(HttpMethod.POST)).andRespond(
176                         withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
177                                 .body(objectMapper.writeValueAsString(instantiationResponse)));
178         mockServer.expect(ExpectedCount.once(),
179                         requestTo(acmConfiguration.getBaseUrl() + "compositions/" + compositionId + "/instances/" + instanceId))
180                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
181         boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance);
182         assertTrue(rappDeployStateActual);
183         mockServer.verify();
184     }
185
186     @Test
187     void testDeployRappInstanceFailureWithNoInstanceId() throws JsonProcessingException {
188         UUID compositionId = UUID.randomUUID();
189         UUID rappId = UUID.randomUUID();
190         Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
191                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
192         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
193         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
194         InstantiationResponse instantiationResponse = new InstantiationResponse();
195         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
196                 .andExpect(method(HttpMethod.POST)).andRespond(
197                         withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
198                                 .body(objectMapper.writeValueAsString(instantiationResponse)));
199
200         boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance);
201         mockServer.verify();
202         assertFalse(rappDeployStateActual);
203     }
204
205     @Test
206     void testDeployRappInstanceFailure() {
207         UUID compositionId = UUID.randomUUID();
208         UUID rappId = UUID.randomUUID();
209         Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
210                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
211         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
212         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
213         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
214                 .andExpect(method(HttpMethod.POST)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
215
216         boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance);
217         mockServer.verify();
218         assertFalse(rappDeployStateActual);
219     }
220
221     @Test
222     void testUndeployRappInstance() throws JsonProcessingException {
223         UUID compositionId = UUID.randomUUID();
224         UUID rappId = UUID.randomUUID();
225         UUID instanceId = UUID.randomUUID();
226         Rapp rapp = Rapp.builder().rappId(rappId).name("").packageName(validRappFile).compositionId(compositionId)
227                             .state(RappState.PRIMED).build();
228
229         expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
230                 ExpectedCount.once());
231
232         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
233                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
234
235         expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.UNDEPLOYED, LockState.UNLOCKED,
236                 ExpectedCount.once());
237
238         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
239                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
240
241         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
242         rappInstance.getAcm().setAcmInstanceId(instanceId);
243         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
244         boolean rappUndeployStateActual = acmDeployer.undeployRappInstance(rapp, rappInstance);
245         mockServer.verify();
246         assertTrue(rappUndeployStateActual);
247     }
248
249     @Test
250     void testUndeployRappInstanceFailure() throws JsonProcessingException {
251         UUID compositionId = UUID.randomUUID();
252         UUID rappId = UUID.randomUUID();
253         UUID instanceId = UUID.randomUUID();
254         Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
255                             .state(RappState.PRIMED).build();
256
257         expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
258                 ExpectedCount.once());
259
260         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
261                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
262
263         expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.UNDEPLOYING, LockState.UNLOCKING,
264                 ExpectedCount.manyTimes());
265
266         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
267         rappInstance.getAcm().setAcmInstanceId(instanceId);
268         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
269         boolean rappUndeployStateActual = acmDeployer.undeployRappInstance(rapp, rappInstance);
270         mockServer.verify();
271         assertFalse(rappUndeployStateActual);
272     }
273
274     @Test
275     void testUndeployRappInstanceACMErrorFailure() throws JsonProcessingException {
276         UUID compositionId = UUID.randomUUID();
277         UUID rappId = UUID.randomUUID();
278         UUID instanceId = UUID.randomUUID();
279         Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
280                             .state(RappState.PRIMED).build();
281         expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
282                 ExpectedCount.once());
283         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
284                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
285         mockServer.expect(ExpectedCount.manyTimes(),
286                         requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId))).andExpect(method(HttpMethod.GET))
287                 .andRespond(withServerError());
288         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
289         rappInstance.getAcm().setAcmInstanceId(instanceId);
290         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
291         boolean rappUndeployStateActual = acmDeployer.undeployRappInstance(rapp, rappInstance);
292         mockServer.verify();
293         assertFalse(rappUndeployStateActual);
294     }
295
296     @ParameterizedTest
297     @MethodSource("getAcmStatusEventMap")
298     void testSyncRappInstanceStatus(DeployState deployState, LockState lockState, RappEvent rappEvent)
299             throws JsonProcessingException {
300         UUID compositionId = UUID.randomUUID();
301         UUID instanceId = UUID.randomUUID();
302         expectAcmGetInstanceToReturnState(compositionId, instanceId, deployState, lockState, ExpectedCount.once());
303         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
304         rappInstance.getAcm().setAcmInstanceId(instanceId);
305         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
306         acmDeployer.syncRappInstanceStatus(compositionId, rappInstance);
307         mockServer.verify();
308         verify(rappInstanceStateMachine, times(1)).sendRappInstanceEvent(rappInstance, rappEvent);
309     }
310
311     private static Stream<Arguments> getAcmStatusEventMap() {
312         return Stream.of(Arguments.of(DeployState.UNDEPLOYING, LockState.UNLOCKING, RappEvent.UNDEPLOYING),
313                 Arguments.of(DeployState.DEPLOYED, LockState.LOCKED, RappEvent.ACMDEPLOYED),
314                 Arguments.of(DeployState.DEPLOYING, LockState.LOCKING, RappEvent.DEPLOYING),
315                 Arguments.of(DeployState.UNDEPLOYED, LockState.UNLOCKED, RappEvent.ACMUNDEPLOYED));
316     }
317
318     @Test
319     void testSyncRappStatusFailure() {
320         UUID compositionId = UUID.randomUUID();
321         UUID instanceId = UUID.randomUUID();
322
323         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
324                 .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
325
326         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
327         rappInstance.getAcm().setAcmInstanceId(instanceId);
328         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
329         acmDeployer.syncRappInstanceStatus(compositionId, rappInstance);
330         mockServer.verify();
331         verify(rappInstanceStateMachine, never()).sendRappInstanceEvent(any(), any());
332     }
333
334     @Test
335     void testPrimeRapp() throws JsonProcessingException {
336         UUID compositionId = UUID.randomUUID();
337         RappResources rappResources = rappResourceBuilder.getResources();
338         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
339                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
340                             .compositionId(compositionId).rappResources(rappResources).build();
341
342         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
343         commissioningResponseExpected.setCompositionId(compositionId);
344         mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
345                 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
346                                     .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
347         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
348                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
349         boolean primeRapp = acmDeployer.primeRapp(rapp);
350         mockServer.verify();
351         assertTrue(primeRapp);
352     }
353
354     @Test
355     void testPrimeRappFailure() throws JsonProcessingException {
356         UUID compositionId = UUID.randomUUID();
357         RappResources rappResources = rappResourceBuilder.getResources();
358         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
359                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
360                             .compositionId(compositionId).rappResources(rappResources).build();
361
362         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
363         commissioningResponseExpected.setCompositionId(compositionId);
364         mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
365                 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
366                                     .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
367         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
368                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
369         boolean primeRapp = acmDeployer.primeRapp(rapp);
370         mockServer.verify();
371         assertFalse(primeRapp);
372         assertEquals(RappState.COMMISSIONED, rapp.getState());
373     }
374
375     @Test
376     void testPrimeRappFailureWithoutCompositionId() throws JsonProcessingException {
377         UUID compositionId = UUID.randomUUID();
378         RappResources rappResources = rappResourceBuilder.getResources();
379         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
380                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
381                             .compositionId(compositionId).rappResources(rappResources).build();
382
383         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
384         mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
385                 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
386                                     .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
387         boolean primeRapp = acmDeployer.primeRapp(rapp);
388         mockServer.verify();
389         assertFalse(primeRapp);
390     }
391
392     @Test
393     void testDeprimeRapp() throws JsonProcessingException {
394         UUID compositionId = UUID.randomUUID();
395         RappResources rappResources = rappResourceBuilder.getResources();
396         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
397                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
398                             .compositionId(compositionId).rappResources(rappResources).build();
399
400         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
401         commissioningResponseExpected.setCompositionId(compositionId);
402         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
403                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
404         AutomationCompositionDefinition automationCompositionDefinition =
405                 getAutomationCompositionDefinition(compositionId, AcTypeState.COMMISSIONED);
406         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
407                 .andExpect(method(HttpMethod.GET)).andRespond(
408                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
409                                 .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
410         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
411                 .andExpect(method(HttpMethod.DELETE)).andRespond(
412                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
413                                 .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
414
415         boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
416         mockServer.verify();
417         assertTrue(deprimeRapp);
418     }
419
420     @Test
421     void testDeprimeRappClientRetry() throws JsonProcessingException {
422         UUID compositionId = UUID.randomUUID();
423         RappResources rappResources = rappResourceBuilder.getResources();
424         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
425                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
426                             .compositionId(compositionId).rappResources(rappResources).build();
427
428         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
429         commissioningResponseExpected.setCompositionId(compositionId);
430         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
431                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
432         AutomationCompositionDefinition automationCompositionDefinition =
433                 getAutomationCompositionDefinition(compositionId, AcTypeState.DEPRIMING);
434         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
435                 .andExpect(method(HttpMethod.GET)).andRespond(
436                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
437                                 .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
438         automationCompositionDefinition = getAutomationCompositionDefinition(compositionId, AcTypeState.COMMISSIONED);
439         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
440                 .andExpect(method(HttpMethod.GET)).andRespond(
441                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
442                                 .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
443         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
444                 .andExpect(method(HttpMethod.DELETE)).andRespond(
445                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
446                                 .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
447
448         boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
449         mockServer.verify();
450         assertTrue(deprimeRapp);
451     }
452
453     @Test
454     void testDeprimeFailureRapp() throws JsonProcessingException {
455         UUID compositionId = UUID.randomUUID();
456         RappResources rappResources = rappResourceBuilder.getResources();
457         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
458                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
459                             .compositionId(compositionId).rappResources(rappResources).build();
460
461         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
462                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
463         AutomationCompositionDefinition automationCompositionDefinition =
464                 getAutomationCompositionDefinition(compositionId, AcTypeState.COMMISSIONED);
465         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
466                 .andExpect(method(HttpMethod.GET)).andRespond(
467                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
468                                 .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
469         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
470                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
471
472         boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
473         mockServer.verify();
474         assertFalse(deprimeRapp);
475     }
476
477     @Test
478     void testDeprimeACMStatusFailureRapp() throws JsonProcessingException {
479         UUID compositionId = UUID.randomUUID();
480         RappResources rappResources = rappResourceBuilder.getResources();
481         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
482                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
483                             .compositionId(compositionId).rappResources(rappResources).build();
484
485         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
486                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
487         AutomationCompositionDefinition automationCompositionDefinition =
488                 getAutomationCompositionDefinition(compositionId, AcTypeState.DEPRIMING);
489         mockServer.expect(ExpectedCount.manyTimes(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
490                 .andExpect(method(HttpMethod.GET)).andRespond(
491                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
492                                 .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
493
494         boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
495         mockServer.verify();
496         assertFalse(deprimeRapp);
497     }
498
499     @Test
500     void testDeprimeACMStatusErrorRapp() {
501         UUID compositionId = UUID.randomUUID();
502         RappResources rappResources = rappResourceBuilder.getResources();
503         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
504                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
505                             .compositionId(compositionId).rappResources(rappResources).build();
506
507         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
508                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
509         mockServer.expect(ExpectedCount.manyTimes(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
510                 .andExpect(method(HttpMethod.GET)).andRespond(withServerError());
511         boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
512         mockServer.verify();
513         assertFalse(deprimeRapp);
514     }
515
516     @Test
517     void testDeprimeExceptionRapp() {
518         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
519                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
520         boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
521         assertFalse(deprimeRapp);
522     }
523
524     @Test
525     void testDeleteComposition() throws JsonProcessingException {
526         UUID compositionId = UUID.randomUUID();
527         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
528         commissioningResponseExpected.setCompositionId(compositionId);
529         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
530                 .andExpect(method(HttpMethod.DELETE)).andRespond(
531                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
532                                 .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
533         CommissioningResponse commissioningResponse = acmDeployer.deleteComposition(compositionId);
534         mockServer.verify();
535         assertEquals(commissioningResponse.getCompositionId(), compositionId);
536     }
537
538     @Test
539     void testDeleteCompositionFailure() {
540         UUID compositionId = UUID.randomUUID();
541         CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
542         commissioningResponseExpected.setCompositionId(compositionId);
543         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
544                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
545         CommissioningResponse commissioningResponse = acmDeployer.deleteComposition(compositionId);
546         mockServer.verify();
547         assertNull(commissioningResponse);
548     }
549
550     void expectAcmGetInstanceToReturnState(UUID compositionId, UUID instanceId, DeployState deployState,
551             LockState lockState, ExpectedCount expectedCount) throws JsonProcessingException {
552         AutomationComposition automationCompositionDeployed = new AutomationComposition();
553         automationCompositionDeployed.setCompositionId(compositionId);
554         automationCompositionDeployed.setInstanceId(instanceId);
555         automationCompositionDeployed.setDeployState(deployState);
556         automationCompositionDeployed.setLockState(lockState);
557
558         mockServer.expect(expectedCount, requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
559                 .andExpect(method(HttpMethod.GET)).andRespond(
560                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
561                                 .body(objectMapper.writeValueAsString(automationCompositionDeployed)));
562     }
563
564     AutomationCompositionDefinition getAutomationCompositionDefinition(UUID compositionId, AcTypeState acTypeState) {
565         AutomationCompositionDefinition automationCompositionDefinition = new AutomationCompositionDefinition();
566         automationCompositionDefinition.setCompositionId(compositionId);
567         automationCompositionDefinition.setState(acTypeState);
568         automationCompositionDefinition.setServiceTemplate(new ToscaServiceTemplate());
569         return automationCompositionDefinition;
570     }
571 }