Adding missing tests
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / test / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / vnfm / notification / TestLifecycleChangeNotificationManager.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification;
17
18 import com.google.gson.*;
19 import com.nokia.cbam.lcm.v32.ApiException;
20 import com.nokia.cbam.lcm.v32.model.*;
21 import org.joda.time.DateTime;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.ArgumentCaptor;
25 import org.mockito.InjectMocks;
26 import org.mockito.Mockito;
27 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager;
28 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase;
29 import org.threeten.bp.OffsetDateTime;
30
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.NoSuchElementException;
34 import java.util.Optional;
35 import java.util.concurrent.*;
36
37 import static com.nokia.cbam.lcm.v32.model.OperationType.*;
38 import static junit.framework.TestCase.*;
39 import static org.mockito.Mockito.*;
40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
41 import static org.springframework.test.util.ReflectionTestUtils.setField;
42
43 public class TestLifecycleChangeNotificationManager extends TestBase {
44
45     public static final String OPERATION_EXECUTION_ID = "myOperationExecutionId";
46
47     @InjectMocks
48     private LifecycleChangeNotificationManager lifecycleChangeNotificationManager;
49     private VnfLifecycleChangeNotification recievedLcn = new VnfLifecycleChangeNotification();
50     private List<OperationExecution> operationExecutions = new ArrayList<>();
51     private OperationExecution instantiationOperation = new OperationExecution();
52     private OperationExecution scaleOperation = new OperationExecution();
53     private OperationExecution healOperation = new OperationExecution();
54     private OperationExecution terminationOperation = new OperationExecution();
55
56     private ArgumentCaptor<OperationExecution> currentOperationExecution = ArgumentCaptor.forClass(OperationExecution.class);
57     private ArgumentCaptor<Optional> affectedConnectionPoints = ArgumentCaptor.forClass(Optional.class);
58
59     private List<VnfInfo> vnfs = new ArrayList<>();
60     private VnfInfo vnf = new VnfInfo();
61
62     @Before
63     public void initMocks() throws Exception {
64         setField(LifecycleChangeNotificationManager.class, "logger", logger);
65         instantiationOperation.setId("instantiationOperationExecutionId");
66         instantiationOperation.setStartTime(OffsetDateTime.now());
67         instantiationOperation.setOperationType(OperationType.INSTANTIATE);
68         scaleOperation.setId("scaleOperationExecutionId");
69         scaleOperation.setStartTime(OffsetDateTime.now().plusDays(1));
70         scaleOperation.setOperationType(OperationType.SCALE);
71         terminationOperation.setId("terminationExecutionId");
72         terminationOperation.setStartTime(OffsetDateTime.now().plusDays(1));
73         terminationOperation.setOperationType(OperationType.TERMINATE);
74         healOperation.setId("healOperaitonExecutionId");
75         healOperation.setOperationType(OperationType.HEAL);
76         recievedLcn.setLifecycleOperationOccurrenceId("instantiationOperationExecutionId");
77         healOperation.setStartTime(OffsetDateTime.now().plusDays(1));
78         recievedLcn.setVnfInstanceId(VNF_ID);
79         when(vnfApi.vnfsVnfInstanceIdOperationExecutionsGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenReturn(operationExecutions);
80         prepOperation(instantiationOperation);
81         prepOperation(scaleOperation);
82         prepOperation(healOperation);
83         prepOperation(terminationOperation);
84         doNothing().when(notificationSender).processNotification(eq(recievedLcn), currentOperationExecution.capture(), affectedConnectionPoints.capture(), eq(VIM_ID));
85         InstantiateVnfRequest instantiateVnfRequest = new InstantiateVnfRequest();
86         VimInfo vimInfo = new VimInfo();
87         vimInfo.setId(VIM_ID);
88         instantiateVnfRequest.getVims().add(vimInfo);
89         when(operationExecutionApi.operationExecutionsOperationExecutionIdOperationParamsGet(instantiationOperation.getId(), NOKIA_LCM_API_VERSION)).thenReturn(new Gson().toJsonTree(instantiateVnfRequest));
90         when(vnfApi.vnfsGet(NOKIA_LCM_API_VERSION)).thenReturn(vnfs);
91         vnfs.add(vnf);
92         vnf.setId(VNF_ID);
93         VnfProperty prop = new VnfProperty();
94         prop.setName(LifecycleManager.EXTERNAL_VNFM_ID);
95         prop.setValue(VNFM_ID);
96         vnf.setExtensions(new ArrayList<>());
97         vnf.getExtensions().add(prop);
98         when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenReturn(vnf);
99     }
100
101     private void prepOperation(OperationExecution operationExecution) throws ApiException {
102         addEmptyModifiedConnectionPoints(operationExecution);
103         JsonElement root = new JsonParser().parse("{ \"additionalParams\" : { \"jobId\" : \"" + JOB_ID + "\"}}");
104         operationExecution.setOperationParams(root);
105         switch (operationExecution.getOperationType()) {
106             case TERMINATE:
107                 root.getAsJsonObject().addProperty("terminationType", "GRACEFULL");
108         }
109         when(operationExecutionApi.operationExecutionsOperationExecutionIdGet(operationExecution.getId(), NOKIA_LCM_API_VERSION)).thenReturn(operationExecution);
110         operationExecutions.add(operationExecution);
111     }
112
113     private void addEmptyModifiedConnectionPoints(OperationExecution operationExecution) {
114         OperationResult operationResult = new OperationResult();
115         operationResult.operationResult = new ReportedAffectedConnectionPoints();
116         JsonElement additionalData = new Gson().toJsonTree(operationResult);
117         operationExecution.setAdditionalData(additionalData);
118     }
119
120     /**
121      * The first instantiation before the current operation is selected
122      */
123     @Test
124     public void testLastInstantiationSelection() {
125         List<OperationExecution> operations = new ArrayList<>();
126
127         OperationExecution operation = buildOperation(OffsetDateTime.now(), TERMINATE);
128         OperationExecution operationScale = buildOperation(OffsetDateTime.now().minusDays(1), SCALE);
129         OperationExecution operationClosestInstantiate = buildOperation(OffsetDateTime.now().minusDays(2), INSTANTIATE);
130         OperationExecution operationFurthers = buildOperation(OffsetDateTime.now().minusDays(3), INSTANTIATE);
131
132         operations.add(operation);
133         operations.add(operationScale);
134         operations.add(operationClosestInstantiate);
135         operations.add(operationFurthers);
136         assertEquals(operationClosestInstantiate, LifecycleChangeNotificationManager.findLastInstantiationBefore(operations, operation));
137     }
138
139     /**
140      * The instantiation operation itself is valid as the last instantiation operation
141      */
142     @Test
143     public void testInstantiationSufficesTheLastInstantiation() {
144         DateTime baseTime = DateTime.now();
145         List<OperationExecution> operations = new ArrayList<>();
146
147         OperationExecution operation = buildOperation(OffsetDateTime.now(), INSTANTIATE);
148         OperationExecution operationScale = buildOperation(OffsetDateTime.now().minusDays(1), SCALE);
149         OperationExecution operationFurthers = buildOperation(OffsetDateTime.now().minusDays(2), INSTANTIATE);
150
151         operations.add(operation);
152         operations.add(operationScale);
153         operations.add(operationFurthers);
154         assertEquals(operation, LifecycleChangeNotificationManager.findLastInstantiationBefore(operations, operation));
155     }
156
157     /**
158      * If no instantiation operation is found for before the selected operation
159      */
160     @Test
161     public void testNoInstantiation() {
162         DateTime baseTime = DateTime.now();
163         List<OperationExecution> operations = new ArrayList<>();
164
165         OperationExecution operation = buildOperation(OffsetDateTime.now(), TERMINATE);
166         OperationExecution operationScale = buildOperation(OffsetDateTime.now().minusDays(1), SCALE);
167
168         operations.add(operation);
169         operations.add(operationScale);
170         try {
171             LifecycleChangeNotificationManager.findLastInstantiationBefore(operations, operation);
172             fail();
173         } catch (NoSuchElementException e) {
174
175         }
176     }
177
178     /**
179      * the operations are ordered from newest (first) to oldest (last)
180      */
181     @Test
182     public void testOperationOrdering() {
183         List<OperationExecution> operationExecutions = new ArrayList<>();
184         OperationExecution before = buildOperation(OffsetDateTime.now(), OperationType.INSTANTIATE);
185         operationExecutions.add(before);
186         OperationExecution after = buildOperation(OffsetDateTime.now().plusDays(1), OperationType.SCALE);
187         operationExecutions.add(after);
188         List<OperationExecution> sorted1 = LifecycleChangeNotificationManager.NEWEST_OPERATIONS_FIRST.sortedCopy(operationExecutions);
189         assertEquals(after, sorted1.get(0));
190         assertEquals(before, sorted1.get(1));
191     }
192
193     /**
194      * if VNF listing fails the processing of the notifications is aborted
195      */
196     @Test
197     public void testUnableToListVnfs() throws Exception {
198         ApiException expectedException = new ApiException();
199         when(vnfApi.vnfsGet(NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
200         //when
201         try {
202             lifecycleChangeNotificationManager.handleLcn(recievedLcn);
203             fail();
204         } catch (Exception e) {
205             assertEquals(expectedException, e.getCause());
206             verify(logger).error("Unable to list VNFs / query VNF", expectedException);
207         }
208     }
209
210     /**
211      * if VNF query fails the processing of the notifications is aborted
212      */
213     @Test
214     public void testUnableToQueryVnf() throws Exception {
215         ApiException expectedException = new ApiException();
216         when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
217         //when
218         try {
219             lifecycleChangeNotificationManager.handleLcn(recievedLcn);
220             fail();
221         } catch (Exception e) {
222             assertEquals(expectedException, e.getCause());
223             verify(logger).error("Unable to list VNFs / query VNF", expectedException);
224         }
225     }
226
227     /**
228      * if the VNF is not managed by this VNFM the LCN is dropped
229      */
230     @Test
231     public void testNonManagedVnf() throws Exception {
232         vnf.getExtensions().clear();
233         //when
234         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
235         //verify
236         Mockito.verifyZeroInteractions(operationExecutionApi);
237         verify(logger).warn("The VNF with " + VNF_ID + " identifier is not a managed VNF");
238     }
239
240     /**
241      * LCN is not logged in case of non info log level
242      */
243     @Test
244     public void testNoLogging() throws Exception {
245         vnf.getExtensions().clear();
246         when(logger.isInfoEnabled()).thenReturn(false);
247         //when
248         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
249         //verify
250         verify(logger, never()).info(eq("Received LCN: {}"), anyString());
251     }
252
253     /**
254      * if the VNF is not managed by this VNFM the LCN is dropped
255      */
256     @Test
257     public void testManagedByOtherVnf() throws Exception {
258         vnf.getExtensions().get(0).setValue("unknownVnfmId");
259         //when
260         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
261         //verify
262         Mockito.verifyZeroInteractions(operationExecutionApi);
263         verify(logger).warn("The VNF with " + VNF_ID + " identifier is not a managed by the VNFM with id unknownVnfmId");
264     }
265
266     /**
267      * if the VNF disappeared before processing the LCN
268      */
269     @Test
270     public void testDisappearedVnf() throws Exception {
271         vnfs.clear();
272         //when
273         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
274         //verify
275         Mockito.verifyZeroInteractions(operationExecutionApi);
276         verify(logger).warn("The VNF with " + VNF_ID + " identifier disappeared before being able to process the LCN");
277     }
278
279     /**
280      * if the operation parameters of the last instantiation is non querieable error is propagated
281      */
282     @Test
283     public void testUnableToQueryOperationParams() throws Exception {
284         recievedLcn.setOperation(OperationType.TERMINATE);
285         recievedLcn.setStatus(OperationStatus.FINISHED);
286         RuntimeException expectedException = new RuntimeException();
287         when(operationExecutionApi.operationExecutionsOperationExecutionIdOperationParamsGet(instantiationOperation.getId(), NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
288         //when
289         try {
290             lifecycleChangeNotificationManager.handleLcn(recievedLcn);
291             fail();
292         } catch (Exception e) {
293             //verify
294             Mockito.verifyZeroInteractions(nsLcmApi);
295             assertEquals(expectedException, e.getCause());
296             verify(logger).error("Unable to detect last instantiation operation", e.getCause());
297         }
298     }
299
300     /**
301      * if unable to send LCN to VF-C the error is propagated
302      */
303     @Test
304     public void testUnableToQueryCurrentOperation() throws Exception {
305         recievedLcn.setOperation(OperationType.TERMINATE);
306         recievedLcn.setStatus(OperationStatus.FINISHED);
307         ApiException expectedException = new ApiException();
308         when(vnfApi.vnfsVnfInstanceIdOperationExecutionsGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
309         //when
310         try {
311             lifecycleChangeNotificationManager.handleLcn(recievedLcn);
312             fail();
313         } catch (Exception e) {
314             //verify
315             assertEquals(expectedException, e.getCause());
316             verify(logger).error("Unable to retrieve the current VNF myVnfId", e.getCause());
317         }
318     }
319
320     /**
321      * test that waitForTerminationToBeProcessed outwaits the successfull processing of the termination notification
322      */
323     @Test
324     public void testWaitForTermination() throws Exception {
325         //given
326         //add an non processed notification
327         VnfLifecycleChangeNotification nonProcessedEvent = new VnfLifecycleChangeNotification();
328         nonProcessedEvent.setStatus(OperationStatus.FINISHED);
329         nonProcessedEvent.setOperation(OperationType.TERMINATE);
330         OperationExecution secondTerminationOperationExecution = new OperationExecution();
331         secondTerminationOperationExecution.setOperationType(OperationType.TERMINATE);
332         secondTerminationOperationExecution.setId("secondId");
333         secondTerminationOperationExecution.setOperationParams(buildTerminationParams());
334         nonProcessedEvent.setLifecycleOperationOccurrenceId(secondTerminationOperationExecution.getId());
335         lifecycleChangeNotificationManager.handleLcn(nonProcessedEvent);
336         //add second termination
337         recievedLcn.setOperation(OperationType.TERMINATE);
338         recievedLcn.setStatus(OperationStatus.FINISHED);
339         recievedLcn.setLifecycleOperationOccurrenceId(terminationOperation.getId());
340         ExecutorService executorService = Executors.newCachedThreadPool();
341         Future<Boolean> waitExitedWithSuccess = executorService.submit(new Callable<Boolean>() {
342             @Override
343             public Boolean call() throws Exception {
344                 try {
345                     lifecycleChangeNotificationManager.waitForTerminationToBeProcessed(terminationOperation.getId());
346                     return true;
347                 } catch (Exception e) {
348                     return false;
349                 }
350             }
351         });
352         //when
353         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
354         //verify
355         assertTrue(waitExitedWithSuccess.get());
356     }
357
358     /**
359      * the processing of the start notification does not trigger the deletion of the VNF
360      */
361     @Test
362     public void testStartLcnForTerminate() throws Exception {
363         recievedLcn.setOperation(OperationType.TERMINATE);
364         recievedLcn.setStatus(OperationStatus.STARTED);
365         recievedLcn.setLifecycleOperationOccurrenceId(terminationOperation.getId());
366         ExecutorService executorService = Executors.newCachedThreadPool();
367         Future<Boolean> waitExitedWithSuccess = executorService.submit(() -> {
368             try {
369                 lifecycleChangeNotificationManager.waitForTerminationToBeProcessed(terminationOperation.getId());
370                 return true;
371             } catch (Exception e) {
372                 return false;
373             }
374         });
375         //processing the start notification
376         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
377         //verify
378         try {
379             waitExitedWithSuccess.get(10, TimeUnit.MILLISECONDS);
380             fail();
381         } catch (Exception e) {
382         }
383         recievedLcn.setStatus(OperationStatus.FINISHED);
384         //when
385         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
386         //verify
387         assertTrue(waitExitedWithSuccess.get());
388     }
389
390     /**
391      * Forceful termination results in an empty affected connection points
392      */
393     @Test
394     public void testMissingPreResultForForcefullTermination() {
395         //given
396         recievedLcn.setOperation(OperationType.INSTANTIATE);
397         recievedLcn.setStatus(OperationStatus.FINISHED);
398         recievedLcn.setLifecycleOperationOccurrenceId(terminationOperation.getId());
399         JsonObject additionalData = new JsonObject();
400         additionalData.add("operationResult", new JsonObject());
401         ((JsonObject) terminationOperation.getOperationParams()).addProperty("terminationType", "FORCEFUL");
402         terminationOperation.setAdditionalData(additionalData);
403         terminationOperation.setStatus(OperationStatus.FINISHED);
404         terminationOperation.setOperationType(OperationType.TERMINATE);
405         //when
406         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
407         assertFalse(affectedConnectionPoints.getValue().isPresent());
408         verify(logger).warn("Unable to send information related to affected connection points during forceful termination");
409     }
410
411     /**
412      * Failures in affected connection point processing are tolerated for failed operation
413      * (because the POST script was not able to run)
414      */
415     @Test
416     public void testFailedOperations() throws Exception {
417         //given
418         recievedLcn.setOperation(OperationType.INSTANTIATE);
419         recievedLcn.setStatus(OperationStatus.FAILED);
420         recievedLcn.setLifecycleOperationOccurrenceId(instantiationOperation.getId());
421         instantiationOperation.setAdditionalData(null);
422         instantiationOperation.setStatus(OperationStatus.FAILED);
423         //when
424         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
425         //verify
426         assertFalse(affectedConnectionPoints.getValue().isPresent());
427         verify(logger).warn("The operation failed and the affected connection points were not reported");
428     }
429
430     /**
431      * Failures in affected connection point processing are tolerated for failed operation
432      * (because the POST script was not able to run)
433      */
434     @Test
435     public void testMissingOperationResult() throws Exception {
436         //given
437         recievedLcn.setOperation(OperationType.INSTANTIATE);
438         recievedLcn.setStatus(OperationStatus.FAILED);
439         recievedLcn.setLifecycleOperationOccurrenceId(instantiationOperation.getId());
440         instantiationOperation.setStatus(OperationStatus.FAILED);
441         JsonObject additionalData = (JsonObject) instantiationOperation.getAdditionalData();
442         additionalData.remove("operationResult");
443         //when
444         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
445         //verify
446         assertFalse(affectedConnectionPoints.getValue().isPresent());
447         verify(logger).warn("The operation failed and the affected connection points were not reported");
448     }
449
450     /**
451      * test end notification scenario for failed scale-out
452      * - LCN is sent to VF-C, but the
453      */
454     @Test
455     public void testMissingPreResultForFailedOperation() {
456         //given
457         recievedLcn.setOperation(OperationType.SCALE);
458         recievedLcn.setStatus(OperationStatus.FAILED);
459         recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
460         ScaleVnfRequest request = new ScaleVnfRequest();
461         request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
462         request.setType(ScaleDirection.OUT);
463         scaleOperation.setOperationParams(request);
464         scaleOperation.setAdditionalData(null);
465         scaleOperation.setStatus(OperationStatus.FAILED);
466         scaleOperation.setOperationType(OperationType.SCALE);
467         //when
468         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
469         assertFalse(affectedConnectionPoints.getValue().isPresent());
470         verify(logger).warn("The operation failed and the affected connection points were not reported");
471     }
472
473     /**
474      * if the cbam_post is missing error handling should be applied
475      */
476     @Test
477     public void testMissingPostResultForFailedOperation() {
478         //given
479         recievedLcn.setOperation(OperationType.SCALE);
480         recievedLcn.setStatus(OperationStatus.FAILED);
481         recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
482         ScaleVnfRequest request = new ScaleVnfRequest();
483         request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
484         request.setType(ScaleDirection.OUT);
485         scaleOperation.setOperationParams(request);
486         scaleOperation.setStatus(OperationStatus.FAILED);
487         ((JsonObject) scaleOperation.getAdditionalData()).get("operationResult").getAsJsonObject().remove("cbam_post");
488         scaleOperation.setOperationType(OperationType.SCALE);
489         //when
490         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
491         assertFalse(affectedConnectionPoints.getValue().isPresent());
492         verify(logger).warn("The operation failed and the affected connection points were not reported");
493     }
494
495     /**
496      * if invalid type is specified for cbam_post error handling should be applied
497      */
498     @Test
499     public void testInvalidPost() {
500         //given
501         recievedLcn.setOperation(OperationType.SCALE);
502         recievedLcn.setStatus(OperationStatus.FAILED);
503         recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
504         ScaleVnfRequest request = new ScaleVnfRequest();
505         request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
506         request.setType(ScaleDirection.OUT);
507         scaleOperation.setOperationParams(request);
508         scaleOperation.setStatus(OperationStatus.FAILED);
509         JsonObject operationResult = ((JsonObject) scaleOperation.getAdditionalData()).get("operationResult").getAsJsonObject();
510         operationResult.remove("cbam_post");
511         operationResult.addProperty("cbam_post", "");
512         scaleOperation.setOperationType(OperationType.SCALE);
513         //when
514         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
515         assertFalse(affectedConnectionPoints.getValue().isPresent());
516         verify(logger).warn("The operation failed and the affected connection points were not reported");
517     }
518
519
520     /**
521      * test end notification success scenario for scale-out
522      * - LCN is sent to VF-C
523      */
524     @Test
525     public void testMissingPreResult() {
526         //given
527         recievedLcn.setOperation(OperationType.SCALE);
528         recievedLcn.setStatus(OperationStatus.FINISHED);
529         recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
530         ScaleVnfRequest request = new ScaleVnfRequest();
531         request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
532         request.setType(ScaleDirection.OUT);
533         scaleOperation.setOperationParams(request);
534         JsonObject additionalData = new JsonObject();
535         additionalData.add("operationResult", new JsonObject());
536         scaleOperation.setAdditionalData(additionalData);
537         scaleOperation.setStatus(OperationStatus.FINISHED);
538         scaleOperation.setOperationType(OperationType.SCALE);
539         JsonElement root = new JsonParser().parse("{ \"additionalParams\" : { \"jobId\" : \"" + JOB_ID + "\"}}");
540         JsonObject operationParams = new JsonObject();
541         //when
542         try {
543             lifecycleChangeNotificationManager.handleLcn(recievedLcn);
544             fail();
545         } catch (Exception e) {
546             assertEquals("All operations must return the { \"operationResult\" : { \"cbam_pre\" : [<fillMeOut>], \"cbam_post\" : [<fillMeOut>] } } structure", e.getMessage());
547         }
548     }
549
550     private JsonObject buildTerminationParams() {
551         JsonObject root = new JsonObject();
552         root.add("terminationType", new JsonPrimitive("GRACEFULL"));
553         return root;
554     }
555
556     private OperationExecution buildOperation(OffsetDateTime baseTime, OperationType operationType) {
557         OperationExecution operation = new OperationExecution();
558         operation.setStartTime(baseTime);
559         operation.setOperationType(operationType);
560         return operation;
561     }
562
563     class OperationResult {
564         ReportedAffectedConnectionPoints operationResult;
565     }
566
567 }