Add APPC-LCM actor
[policy/models.git] / models-interactions / model-actors / actor.appclcm / src / test / java / org / onap / policy / controlloop / actor / appclcm / AppcLcmActorServiceProviderTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * AppcServiceProviderTest
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.controlloop.actor.appclcm;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27
28 import java.time.Instant;
29 import java.util.AbstractMap;
30 import java.util.Arrays;
31 import java.util.HashMap;
32 import java.util.UUID;
33 import java.util.stream.Collectors;
34 import org.junit.AfterClass;
35 import org.junit.BeforeClass;
36 import org.junit.Test;
37 import org.onap.policy.appclcm.AppcLcmBody;
38 import org.onap.policy.appclcm.AppcLcmCommonHeader;
39 import org.onap.policy.appclcm.AppcLcmDmaapWrapper;
40 import org.onap.policy.appclcm.AppcLcmInput;
41 import org.onap.policy.appclcm.AppcLcmOutput;
42 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
43 import org.onap.policy.controlloop.ControlLoopEventStatus;
44 import org.onap.policy.controlloop.ControlLoopOperation;
45 import org.onap.policy.controlloop.ControlLoopTargetType;
46 import org.onap.policy.controlloop.VirtualControlLoopEvent;
47 import org.onap.policy.controlloop.policy.Policy;
48 import org.onap.policy.controlloop.policy.PolicyResult;
49 import org.onap.policy.controlloop.policy.Target;
50 import org.onap.policy.controlloop.policy.TargetType;
51 import org.onap.policy.simulators.Util;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 public class AppcLcmActorServiceProviderTest {
56
57     private static final String VNF01 = "vnf01";
58
59     private static final String VNF_ID_KEY = "vnf-id";
60
61     private static final String REJECT = "REJECT";
62
63     private static final String PARTIAL_FAILURE = "PARTIAL FAILURE";
64
65     private static final String FAILURE = "FAILURE";
66
67     private static final Logger logger = LoggerFactory.getLogger(AppcLcmActorServiceProviderTest.class);
68
69     private static final VirtualControlLoopEvent onsetEvent;
70     private static final ControlLoopOperation operation;
71     private static final Policy policy;
72     private static final AppcLcmDmaapWrapper dmaapResponse;
73
74     private static final String RECIPE_RESTART = "Restart";
75     private static final String RECIPE_REBUILD = "Rebuild";
76     private static final String RECIPE_MIGRATE = "Migrate";
77
78     static {
79         /*
80          * Construct an onset with an AAI subtag containing generic-vnf.vnf-id and a target type of VM.
81          */
82         onsetEvent = new VirtualControlLoopEvent();
83         onsetEvent.setClosedLoopControlName("closedLoopControlName-Test");
84         onsetEvent.setRequestId(UUID.randomUUID());
85         onsetEvent.setClosedLoopEventClient("tca.instance00001");
86         onsetEvent.setTargetType(ControlLoopTargetType.VM);
87         onsetEvent.setTarget("generic-vnf.vnf-name");
88         onsetEvent.setFrom("DCAE");
89         onsetEvent.setClosedLoopAlarmStart(Instant.now());
90         onsetEvent.setAai(new HashMap<>());
91         onsetEvent.getAai().put("generic-vnf.vnf-name", "fw0001vm001fw001");
92         onsetEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
93
94         /* Construct an operation with an APPC actor and restart operation. */
95         operation = new ControlLoopOperation();
96         operation.setActor("APPC");
97         operation.setOperation(RECIPE_RESTART);
98         operation.setTarget("VM");
99         operation.setEnd(Instant.now());
100         operation.setSubRequestId("1");
101
102         /* Construct a policy specifying to restart vm. */
103         policy = new Policy();
104         policy.setName("Restart the VM");
105         policy.setDescription("Upon getting the trigger event, restart the VM");
106         policy.setActor("APPC");
107         policy.setTarget(new Target(TargetType.VNF));
108         policy.setRecipe(RECIPE_RESTART);
109         policy.setPayload(null);
110         policy.setRetry(2);
111         policy.setTimeout(300);
112
113         /* A sample DMAAP request wrapper. */
114         AppcLcmDmaapWrapper dmaapRequest = new AppcLcmDmaapWrapper();
115         dmaapRequest.setCorrelationId(onsetEvent.getRequestId().toString() + "-" + "1");
116         dmaapRequest.setRpcName(policy.getRecipe().toLowerCase());
117         dmaapRequest.setType("request");
118
119         /* A sample DMAAP response wrapper */
120         dmaapResponse = new AppcLcmDmaapWrapper();
121         dmaapResponse.setCorrelationId(onsetEvent.getRequestId().toString() + "-" + "1");
122         dmaapResponse.setRpcName(policy.getRecipe().toLowerCase());
123         dmaapResponse.setType("response");
124
125         /* A sample APPC LCM request. */
126         AppcLcmInput appcRequest = new AppcLcmInput();
127
128         /* The following code constructs a sample APPC LCM Request */
129         appcRequest.setAction("restart");
130
131         HashMap<String, String> actionIdentifiers = new HashMap<>();
132         actionIdentifiers.put(VNF_ID_KEY, "trial-vnf-003");
133
134         appcRequest.setActionIdentifiers(actionIdentifiers);
135
136         AppcLcmCommonHeader commonHeader = new AppcLcmCommonHeader();
137         commonHeader.setRequestId(onsetEvent.getRequestId());
138         commonHeader.setSubRequestId("1");
139         commonHeader.setOriginatorId(onsetEvent.getRequestId().toString());
140
141         appcRequest.setCommonHeader(commonHeader);
142
143         appcRequest.setPayload(null);
144
145         AppcLcmBody appcBody = new AppcLcmBody();
146         appcBody.setInput(appcRequest);
147
148         dmaapRequest.setBody(appcBody);
149
150         /* The following code constructs a sample APPC LCM Response */
151         AppcLcmOutput appcResponse = new AppcLcmOutput(appcRequest);
152         appcResponse.getStatus().setCode(400);
153         appcResponse.getStatus().setMessage("Restart Successful");
154
155         appcBody.setOutput(appcResponse);
156
157         dmaapResponse.setBody(appcBody);
158     }
159
160     /**
161      * Set up before test class.
162      *
163      * @throws Exception if an error occurs
164      */
165     @BeforeClass
166     public static void setUpSimulator() throws Exception {
167         Util.buildAaiSim();
168     }
169
170     /**
171      * Tear down after test class.
172      */
173     @AfterClass
174     public static void tearDownSimulator() {
175         HttpServletServerFactoryInstance.getServerFactory().destroy();
176     }
177
178     @Test
179     public void testConstructor() {
180         AppcLcmActorServiceProvider prov = new AppcLcmActorServiceProvider();
181         assertEquals(-1, prov.getSequenceNumber());
182
183         // verify that it has the operators we expect
184         var expected = Arrays.asList(ConfigModifyOperation.NAME).stream().sorted().collect(Collectors.toList());
185         var actual = prov.getOperationNames().stream().sorted().collect(Collectors.toList());
186
187         assertEquals(expected.toString(), actual.toString());
188     }
189
190     /**
191      * A test to construct an APPC LCM restart request.
192      */
193     @Test
194     public void constructRestartRequestTest() {
195
196         AppcLcmDmaapWrapper dmaapRequest =
197                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, policy, VNF01);
198
199         /* The service provider must return a non null DMAAP request wrapper */
200         assertNotNull(dmaapRequest);
201
202         /* The DMAAP wrapper's type field must be request */
203         assertEquals("request", dmaapRequest.getType());
204
205         /* The DMAAP wrapper's body field cannot be null */
206         assertNotNull(dmaapRequest.getBody());
207
208         AppcLcmInput appcRequest = dmaapRequest.getBody().getInput();
209
210         /* A common header is required and cannot be null */
211         assertNotNull(appcRequest.getCommonHeader());
212         assertEquals(appcRequest.getCommonHeader().getRequestId(), onsetEvent.getRequestId());
213
214         /* An action is required and cannot be null */
215         assertNotNull(appcRequest.getAction());
216         assertEquals(RECIPE_RESTART, appcRequest.getAction());
217
218         /* Action Identifiers are required and cannot be null */
219         assertNotNull(appcRequest.getActionIdentifiers());
220         assertNotNull(appcRequest.getActionIdentifiers().get(VNF_ID_KEY));
221         assertEquals(VNF01, appcRequest.getActionIdentifiers().get(VNF_ID_KEY));
222
223         logger.debug("APPC Request: \n" + appcRequest.toString());
224     }
225
226     /**
227      * A test to process a successful APPC restart response.
228      */
229     @Test
230     public void processRestartResponseSuccessTest() {
231         AbstractMap.SimpleEntry<PolicyResult, String> result =
232                 AppcLcmActorServiceProvider.processResponse(dmaapResponse);
233         assertEquals(PolicyResult.SUCCESS, result.getKey());
234         assertEquals("Restart Successful", result.getValue());
235     }
236
237     /**
238      * A test to assert that a null pointer exception is thrown if the APPC response body is null.
239      */
240     @Test(expected = NullPointerException.class)
241     public void processNullBodyResponseTest() {
242         AppcLcmActorServiceProvider.processResponse(new AppcLcmDmaapWrapper());
243     }
244
245     /**
246      * A test to assert that a null pointer exception is thrown if the APPC response output is null.
247      */
248     @Test(expected = NullPointerException.class)
249     public void processNullOutputResponseTest() {
250         AppcLcmDmaapWrapper dmaapWrapper = new AppcLcmDmaapWrapper();
251         dmaapWrapper.setBody(new AppcLcmBody());
252         AppcLcmActorServiceProvider.processResponse(dmaapWrapper);
253     }
254
255     /**
256      * A test to map APPC response results to corresponding Policy results.
257      */
258     @Test
259     public void appcToPolicyResultTest() {
260
261         AbstractMap.SimpleEntry<PolicyResult, String> result;
262
263         /* If APPC accepts, PolicyResult is null */
264         dmaapResponse.getBody().getOutput().getStatus().setCode(100);
265         dmaapResponse.getBody().getOutput().getStatus().setMessage("ACCEPTED");
266         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
267         assertNull(result.getKey());
268
269         /* If APPC is successful, PolicyResult is success */
270         dmaapResponse.getBody().getOutput().getStatus().setCode(400);
271         dmaapResponse.getBody().getOutput().getStatus().setMessage("SUCCESS");
272         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
273         assertEquals(PolicyResult.SUCCESS, result.getKey());
274
275         /* If APPC returns an error, PolicyResult is failure exception */
276         dmaapResponse.getBody().getOutput().getStatus().setCode(200);
277         dmaapResponse.getBody().getOutput().getStatus().setMessage("ERROR");
278         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
279         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
280
281         /* If APPC rejects, PolicyResult is failure exception */
282         dmaapResponse.getBody().getOutput().getStatus().setCode(300);
283         dmaapResponse.getBody().getOutput().getStatus().setMessage(REJECT);
284         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
285         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
286
287         /* Test multiple reject codes */
288         dmaapResponse.getBody().getOutput().getStatus().setCode(306);
289         dmaapResponse.getBody().getOutput().getStatus().setMessage(REJECT);
290         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
291         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
292
293         dmaapResponse.getBody().getOutput().getStatus().setCode(313);
294         dmaapResponse.getBody().getOutput().getStatus().setMessage(REJECT);
295         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
296         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
297
298         /* If APPC returns failure, PolicyResult is failure */
299         dmaapResponse.getBody().getOutput().getStatus().setCode(401);
300         dmaapResponse.getBody().getOutput().getStatus().setMessage(FAILURE);
301         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
302         assertEquals(PolicyResult.FAILURE, result.getKey());
303
304         /* Test multiple failure codes */
305         dmaapResponse.getBody().getOutput().getStatus().setCode(406);
306         dmaapResponse.getBody().getOutput().getStatus().setMessage(FAILURE);
307         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
308         assertEquals(PolicyResult.FAILURE, result.getKey());
309
310         dmaapResponse.getBody().getOutput().getStatus().setCode(450);
311         dmaapResponse.getBody().getOutput().getStatus().setMessage(FAILURE);
312         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
313         assertEquals(PolicyResult.FAILURE, result.getKey());
314
315         /* If APPC returns partial success, PolicyResult is failure exception */
316         dmaapResponse.getBody().getOutput().getStatus().setCode(500);
317         dmaapResponse.getBody().getOutput().getStatus().setMessage("PARTIAL SUCCESS");
318         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
319         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
320
321         /* If APPC returns partial failure, PolicyResult is failure exception */
322         dmaapResponse.getBody().getOutput().getStatus().setCode(501);
323         dmaapResponse.getBody().getOutput().getStatus().setMessage(PARTIAL_FAILURE);
324         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
325         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
326
327         /* Test multiple partial failure codes */
328         dmaapResponse.getBody().getOutput().getStatus().setCode(599);
329         dmaapResponse.getBody().getOutput().getStatus().setMessage(PARTIAL_FAILURE);
330         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
331         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
332
333         dmaapResponse.getBody().getOutput().getStatus().setCode(550);
334         dmaapResponse.getBody().getOutput().getStatus().setMessage(PARTIAL_FAILURE);
335         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
336         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
337
338         /* If APPC code is unknown to Policy, PolicyResult is failure exception */
339         dmaapResponse.getBody().getOutput().getStatus().setCode(700);
340         dmaapResponse.getBody().getOutput().getStatus().setMessage("UNKNOWN");
341         result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
342         assertEquals(PolicyResult.FAILURE_EXCEPTION, result.getKey());
343     }
344
345     /*
346      * This test exercises getters not exercised in other tests.
347      */
348     @Test
349     public void testMethods() {
350         AppcLcmActorServiceProvider sp = new AppcLcmActorServiceProvider();
351
352         assertEquals("APPC", sp.actor());
353         assertEquals(4, sp.recipes().size());
354         assertEquals("VM", sp.recipeTargets(RECIPE_RESTART).get(0));
355         assertEquals("vm-id", sp.recipePayloads(RECIPE_RESTART).get(0));
356     }
357
358     @Test
359     public void testPayloadNotPassedWhenNotSupportedByRecipe() {
360         // given
361         Policy migratePolicy = constructPolicyWithRecipe(RECIPE_MIGRATE);
362         Policy rebuildPolicy = constructPolicyWithRecipe(RECIPE_REBUILD);
363         Policy restartPolicy = constructPolicyWithRecipe(RECIPE_RESTART);
364
365         // when
366         AppcLcmDmaapWrapper migrateRequest =
367                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, migratePolicy, VNF01);
368         AppcLcmDmaapWrapper rebuildRequest =
369                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, rebuildPolicy, VNF01);
370         AppcLcmDmaapWrapper restartRequest =
371                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, restartPolicy, VNF01);
372
373         // then
374         assertNull(migrateRequest.getBody().getInput().getPayload());
375         assertNull(rebuildRequest.getBody().getInput().getPayload());
376         assertNull(restartRequest.getBody().getInput().getPayload());
377     }
378
379     @Test
380     public void testPayloadNotPassedWhenNotSuppliedOrEmpty() {
381         // given
382         Policy noPayloadPolicy = constructHealthCheckPolicyWithPayload(null);
383         Policy emptyPayloadPolicy = constructHealthCheckPolicyWithPayload(new HashMap<>());
384
385         // when
386         AppcLcmDmaapWrapper noPayloadRequest =
387                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, noPayloadPolicy, VNF01);
388         AppcLcmDmaapWrapper emptyPayloadRequest =
389                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, emptyPayloadPolicy, VNF01);
390
391         // then
392         assertNull(noPayloadRequest.getBody().getInput().getPayload());
393         assertNull(emptyPayloadRequest.getBody().getInput().getPayload());
394     }
395
396     @Test
397     public void testPayloadParsedProperlyForSinglePayloadParameter() {
398         // given
399         HashMap<String, String> payload = new HashMap<>();
400         payload.put("requestParameters", "{\"host-ip-address\":\"10.183.37.25\"}");
401         Policy otherPolicy = constructHealthCheckPolicyWithPayload(payload);
402
403         // when
404         AppcLcmDmaapWrapper dmaapRequest =
405                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, otherPolicy, VNF01);
406
407         // then
408         assertEquals("{\"requestParameters\": {\"host-ip-address\":\"10.183.37.25\"}}",
409                 dmaapRequest.getBody().getInput().getPayload());
410     }
411
412     @Test
413     public void testPayloadParsedProperlyForMultiplePayloadParameters() {
414         // given
415         HashMap<String, String> payload = new HashMap<>();
416         payload.put("requestParameters", "{\"host-ip-address\":\"10.183.37.25\"}");
417         payload.put("configurationParameters",
418                 "[{\"ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[9]\","
419                         + "\"oam-ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[16]\","
420                         + "\"enabled\":\"$.vf-module-topology.vf-module-parameters.param[23]\"}]");
421         Policy otherPolicy = constructHealthCheckPolicyWithPayload(payload);
422
423         // when
424         AppcLcmDmaapWrapper dmaapRequest =
425                 AppcLcmActorServiceProvider.constructRequest(onsetEvent, operation, otherPolicy, VNF01);
426
427         // then
428         assertEquals(dmaapRequest.getBody().getInput().getPayload(),
429                 "{\"requestParameters\": " + "{\"host-ip-address\":\"10.183.37.25\"}," + "\"configurationParameters\": "
430                         + "[{\"ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[9]\","
431                         + "\"oam-ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[16]\","
432                         + "\"enabled\":\"$.vf-module-topology.vf-module-parameters.param[23]\"}]" + "}");
433     }
434
435     private Policy constructHealthCheckPolicyWithPayload(HashMap<String, String> payload) {
436         return constructHealthCheckPolicyWithPayloadAndRecipe(payload, "Health-Check");
437     }
438
439     private Policy constructPolicyWithRecipe(String recipe) {
440         return constructHealthCheckPolicyWithPayloadAndRecipe(null, recipe);
441     }
442
443     private Policy constructHealthCheckPolicyWithPayloadAndRecipe(HashMap<String, String> payload, String recipe) {
444         Policy otherPolicy = new Policy();
445         otherPolicy.setName("Perform health check");
446         otherPolicy.setDescription("Upon getting the trigger event, perform health check");
447         otherPolicy.setActor("APPC");
448         otherPolicy.setTarget(new Target(TargetType.VNF));
449         otherPolicy.setRecipe(recipe);
450         otherPolicy.setPayload(payload);
451         otherPolicy.setRetry(2);
452         otherPolicy.setTimeout(300);
453         return otherPolicy;
454     }
455 }