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