summaryrefslogtreecommitdiffstats
path: root/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java
diff options
context:
space:
mode:
authorDenes Nemeth <denes.nemeth@nokia.com>2018-02-12 20:55:54 +0100
committerDenes Nemeth <denes.nemeth@nokia.com>2018-02-23 11:44:45 +0100
commitb17042b955489d8a023d09abad5436ff9b900dc3 (patch)
tree1e4392ac04a2fb1ed8d17075d504cf6594acaf16 /nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java
parentd4982f7b1777e9cdae9a4cc7d0d104263889ac69 (diff)
Updating Nokia driver
Change-Id: I950afe6acbdb359cd67a448024f006a45e8fc293 Signed-off-by: Denes Nemeth <denes.nemeth@nokia.com> Issue-ID: VFC-728
Diffstat (limited to 'nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java')
-rw-r--r--nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java457
1 files changed, 457 insertions, 0 deletions
diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java
new file mode 100644
index 00000000..ed009b97
--- /dev/null
+++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java
@@ -0,0 +1,457 @@
+/*
+ * Copyright 2016-2017, Nokia Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification;
+
+import com.google.gson.*;
+import com.nokia.cbam.lcm.v32.ApiException;
+import com.nokia.cbam.lcm.v32.model.*;
+import org.joda.time.DateTime;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.ILifecycleChangeNotificationManager;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase;
+import org.threeten.bp.OffsetDateTime;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import static com.nokia.cbam.lcm.v32.model.OperationType.*;
+import static junit.framework.TestCase.*;
+import static org.mockito.Mockito.*;
+import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
+import static org.springframework.test.util.ReflectionTestUtils.setField;
+
+public class TestLifecycleChangeNotificationManager extends TestBase {
+
+ public static final String OPERATION_EXECUTION_ID = "myOperationExecutionId";
+
+ @InjectMocks
+ private LifecycleChangeNotificationManager lifecycleChangeNotificationManager;
+ private VnfLifecycleChangeNotification recievedLcn = new VnfLifecycleChangeNotification();
+ private List<OperationExecution> operationExecutions = new ArrayList<>();
+ private OperationExecution instantiationOperation = new OperationExecution();
+ private OperationExecution scaleOperation = new OperationExecution();
+ private OperationExecution healOperation = new OperationExecution();
+ private OperationExecution terminationOperation = new OperationExecution();
+
+ private ArgumentCaptor<OperationExecution> currentOperationExecution = ArgumentCaptor.forClass(OperationExecution.class);
+ private ArgumentCaptor<ReportedAffectedConnectionPoints> affectedConnectionPoints = ArgumentCaptor.forClass(ReportedAffectedConnectionPoints.class);
+
+ private List<VnfInfo> vnfs = new ArrayList<>();
+ private VnfInfo vnf = new VnfInfo();
+
+ @Before
+ public void initMocks() throws Exception {
+ setField(LifecycleChangeNotificationManager.class, "logger", logger);
+ instantiationOperation.setId("instantiationOperationExecutionId");
+ instantiationOperation.setStartTime(OffsetDateTime.now());
+ instantiationOperation.setOperationType(OperationType.INSTANTIATE);
+ scaleOperation.setId("scaleOperationExecutionId");
+ scaleOperation.setStartTime(OffsetDateTime.now().plusDays(1));
+ scaleOperation.setOperationType(OperationType.SCALE);
+ terminationOperation.setId("terminationExecutionId");
+ terminationOperation.setStartTime(OffsetDateTime.now().plusDays(1));
+ terminationOperation.setOperationType(OperationType.TERMINATE);
+ healOperation.setId("healOperaitonExecutionId");
+ healOperation.setOperationType(OperationType.HEAL);
+ recievedLcn.setLifecycleOperationOccurrenceId("instantiationOperationExecutionId");
+ healOperation.setStartTime(OffsetDateTime.now().plusDays(1));
+ recievedLcn.setVnfInstanceId(VNF_ID);
+ when(vnfApi.vnfsVnfInstanceIdOperationExecutionsGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenReturn(operationExecutions);
+ prepOperation(instantiationOperation);
+ prepOperation(scaleOperation);
+ prepOperation(healOperation);
+ prepOperation(terminationOperation);
+ doNothing().when(notificationSender).processNotification(eq(recievedLcn), currentOperationExecution.capture(), affectedConnectionPoints.capture(), eq(VIM_ID));
+ InstantiateVnfRequest instantiateVnfRequest = new InstantiateVnfRequest();
+ VimInfo vimInfo = new VimInfo();
+ vimInfo.setId(VIM_ID);
+ instantiateVnfRequest.getVims().add(vimInfo);
+ when(operationExecutionApi.operationExecutionsOperationExecutionIdOperationParamsGet(instantiationOperation.getId(), NOKIA_LCM_API_VERSION)).thenReturn(new Gson().toJsonTree(instantiateVnfRequest));
+ when(vnfApi.vnfsGet(NOKIA_LCM_API_VERSION)).thenReturn(vnfs);
+ vnfs.add(vnf);
+ vnf.setId(VNF_ID);
+ VnfProperty prop = new VnfProperty();
+ prop.setName(ILifecycleChangeNotificationManager.EXTERNAL_VNFM_ID);
+ prop.setValue(VNFM_ID);
+ vnf.setExtensions(new ArrayList<>());
+ vnf.getExtensions().add(prop);
+ when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenReturn(vnf);
+ }
+
+ private void prepOperation(OperationExecution operationExecution) throws ApiException {
+ addEmptyModifiedConnectionPoints(operationExecution);
+ JsonElement root = new JsonParser().parse("{ \"additionalParams\" : { \"jobId\" : \"" + JOB_ID + "\"}}");
+ operationExecution.setOperationParams(root);
+ switch (operationExecution.getOperationType()) {
+ case TERMINATE:
+ root.getAsJsonObject().addProperty("terminationType", "GRACEFULL");
+ }
+ when(operationExecutionApi.operationExecutionsOperationExecutionIdGet(operationExecution.getId(), NOKIA_LCM_API_VERSION)).thenReturn(operationExecution);
+ operationExecutions.add(operationExecution);
+ }
+
+ private void addEmptyModifiedConnectionPoints(OperationExecution operationExecution) {
+ OperationResult operationResult = new OperationResult();
+ operationResult.operationResult = new ReportedAffectedConnectionPoints();
+ JsonElement additionalData = new Gson().toJsonTree(operationResult);
+ operationExecution.setAdditionalData(additionalData);
+ }
+
+ /**
+ * The first instantiation before the current operation is selected
+ */
+ @Test
+ public void testLastInstantiationSelection() {
+ List<OperationExecution> operations = new ArrayList<>();
+
+ OperationExecution operation = buildOperation(OffsetDateTime.now(), TERMINATE);
+ OperationExecution operationScale = buildOperation(OffsetDateTime.now().minusDays(1), SCALE);
+ OperationExecution operationClosestInstantiate = buildOperation(OffsetDateTime.now().minusDays(2), INSTANTIATE);
+ OperationExecution operationFurthers = buildOperation(OffsetDateTime.now().minusDays(3), INSTANTIATE);
+
+ operations.add(operation);
+ operations.add(operationScale);
+ operations.add(operationClosestInstantiate);
+ operations.add(operationFurthers);
+ assertEquals(operationClosestInstantiate, LifecycleChangeNotificationManager.findLastInstantiationBefore(operations, operation));
+ }
+
+ /**
+ * The instantiation operation itself is valid as the last instantiation operation
+ */
+ @Test
+ public void testInstantiationSufficesTheLastInstantiation() {
+ DateTime baseTime = DateTime.now();
+ List<OperationExecution> operations = new ArrayList<>();
+
+ OperationExecution operation = buildOperation(OffsetDateTime.now(), INSTANTIATE);
+ OperationExecution operationScale = buildOperation(OffsetDateTime.now().minusDays(1), SCALE);
+ OperationExecution operationFurthers = buildOperation(OffsetDateTime.now().minusDays(2), INSTANTIATE);
+
+ operations.add(operation);
+ operations.add(operationScale);
+ operations.add(operationFurthers);
+ assertEquals(operation, LifecycleChangeNotificationManager.findLastInstantiationBefore(operations, operation));
+ }
+
+ /**
+ * If no instantiation operation is found for before the selected operation
+ */
+ @Test
+ public void testNoInstantiation() {
+ DateTime baseTime = DateTime.now();
+ List<OperationExecution> operations = new ArrayList<>();
+
+ OperationExecution operation = buildOperation(OffsetDateTime.now(), TERMINATE);
+ OperationExecution operationScale = buildOperation(OffsetDateTime.now().minusDays(1), SCALE);
+
+ operations.add(operation);
+ operations.add(operationScale);
+ try {
+ LifecycleChangeNotificationManager.findLastInstantiationBefore(operations, operation);
+ fail();
+ } catch (NoSuchElementException e) {
+
+ }
+ }
+
+ /**
+ * the operations are ordered from newest (first) to oldest (last)
+ */
+ @Test
+ public void testOperationOrdering() {
+ List<OperationExecution> operationExecutions = new ArrayList<>();
+ OperationExecution before = buildOperation(OffsetDateTime.now(), OperationType.INSTANTIATE);
+ operationExecutions.add(before);
+ OperationExecution after = buildOperation(OffsetDateTime.now().plusDays(1), OperationType.SCALE);
+ operationExecutions.add(after);
+ List<OperationExecution> sorted1 = LifecycleChangeNotificationManager.NEWEST_OPERATIONS_FIRST.sortedCopy(operationExecutions);
+ assertEquals(after, sorted1.get(0));
+ assertEquals(before, sorted1.get(1));
+ }
+
+ /**
+ * if VNF listing fails the processing of the notifications is aborted
+ */
+ @Test
+ public void testUnableToListVnfs() throws Exception {
+ ApiException expectedException = new ApiException();
+ when(vnfApi.vnfsGet(NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
+ //when
+ try {
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ fail();
+ } catch (Exception e) {
+ assertEquals(expectedException, e.getCause());
+ verify(logger).error("Unable to list VNFs / query VNF", expectedException);
+ }
+ }
+
+ /**
+ * if VNF query fails the processing of the notifications is aborted
+ */
+ @Test
+ public void testUnableToQueryVnf() throws Exception {
+ ApiException expectedException = new ApiException();
+ when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
+ //when
+ try {
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ fail();
+ } catch (Exception e) {
+ assertEquals(expectedException, e.getCause());
+ verify(logger).error("Unable to list VNFs / query VNF", expectedException);
+ }
+ }
+
+ /**
+ * if the VNF is not managed by this VNFM the LCN is dropped
+ */
+ @Test
+ public void testNonManagedVnf() throws Exception {
+ vnf.getExtensions().clear();
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ //verify
+ Mockito.verifyZeroInteractions(operationExecutionApi);
+ verify(logger).warn("The VNF with " + VNF_ID + " identifier is not a managed VNF");
+ }
+
+ /**
+ * if the VNF is not managed by this VNFM the LCN is dropped
+ */
+ @Test
+ public void testManagedByOtherVnf() throws Exception {
+ vnf.getExtensions().get(0).setValue("unknownVnfmId");
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ //verify
+ Mockito.verifyZeroInteractions(operationExecutionApi);
+ verify(logger).warn("The VNF with " + VNF_ID + " identifier is not a managed by the VNFM with id unknownVnfmId");
+ }
+
+ /**
+ * if the VNF disappeared before processing the LCN
+ */
+ @Test
+ public void testDisappearedVnf() throws Exception {
+ vnfs.clear();
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ //verify
+ Mockito.verifyZeroInteractions(operationExecutionApi);
+ verify(logger).warn("The VNF with " + VNF_ID + " disappeared before being able to process the LCN");
+ }
+
+ /**
+ * if the operation parameters of the last instantiation is non querieable error is propagated
+ */
+ @Test
+ public void testUnableToQueryOperationParams() throws Exception {
+ recievedLcn.setOperation(OperationType.TERMINATE);
+ recievedLcn.setStatus(OperationStatus.FINISHED);
+ RuntimeException expectedException = new RuntimeException();
+ when(operationExecutionApi.operationExecutionsOperationExecutionIdOperationParamsGet(instantiationOperation.getId(), NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
+ //when
+ try {
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ fail();
+ } catch (Exception e) {
+ //verify
+ Mockito.verifyZeroInteractions(nsLcmApi);
+ assertEquals(expectedException, e.getCause());
+ verify(logger).error("Unable to detect last instantiation operation", e.getCause());
+ }
+ }
+
+ /**
+ * if unable to send LCN to VF-C the error is propagated
+ */
+ @Test
+ public void testUnableToQueryCurrentOperation() throws Exception {
+ recievedLcn.setOperation(OperationType.TERMINATE);
+ recievedLcn.setStatus(OperationStatus.FINISHED);
+ ApiException expectedException = new ApiException();
+ when(vnfApi.vnfsVnfInstanceIdOperationExecutionsGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenThrow(expectedException);
+ //when
+ try {
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ fail();
+ } catch (Exception e) {
+ //verify
+ assertEquals(expectedException, e.getCause());
+ verify(logger).error("Unable to retrieve the current VNF myVnfId", e.getCause());
+ }
+ }
+
+ /**
+ * test that waitForTerminationToBeProcessed outwaits the successfull processing of the termination notification
+ */
+ @Test
+ public void testWaitForTermination() throws Exception {
+ //given
+ //add an non processed notification
+ VnfLifecycleChangeNotification nonProcessedEvent = new VnfLifecycleChangeNotification();
+ nonProcessedEvent.setStatus(OperationStatus.FINISHED);
+ nonProcessedEvent.setOperation(OperationType.TERMINATE);
+ OperationExecution secondTerminationOperationExecution = new OperationExecution();
+ secondTerminationOperationExecution.setOperationType(OperationType.TERMINATE);
+ secondTerminationOperationExecution.setId("secondId");
+ secondTerminationOperationExecution.setOperationParams(buildTerminationParams());
+ nonProcessedEvent.setLifecycleOperationOccurrenceId(secondTerminationOperationExecution.getId());
+ lifecycleChangeNotificationManager.handleLcn(nonProcessedEvent);
+ //add second termination
+ recievedLcn.setOperation(OperationType.TERMINATE);
+ recievedLcn.setStatus(OperationStatus.FINISHED);
+ recievedLcn.setLifecycleOperationOccurrenceId(terminationOperation.getId());
+ ExecutorService executorService = Executors.newCachedThreadPool();
+ Future<Boolean> waitExitedWithSuccess = executorService.submit(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ try {
+ lifecycleChangeNotificationManager.waitForTerminationToBeProcessed(terminationOperation.getId());
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ });
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ //verify
+ assertTrue(waitExitedWithSuccess.get());
+ }
+
+ /**
+ * Forceful termination results in an empty affected connection points
+ */
+ @Test
+ public void testMissingPreResultForForcefullTermination() {
+ //given
+ recievedLcn.setOperation(OperationType.INSTANTIATE);
+ recievedLcn.setStatus(OperationStatus.FINISHED);
+ recievedLcn.setLifecycleOperationOccurrenceId(terminationOperation.getId());
+ JsonObject additionalData = new JsonObject();
+ additionalData.add("operationResult", new JsonObject());
+ ((JsonObject) terminationOperation.getOperationParams()).addProperty("terminationType", "FORCEFUL");
+ terminationOperation.setAdditionalData(additionalData);
+ terminationOperation.setStatus(OperationStatus.FINISHED);
+ terminationOperation.setOperationType(OperationType.TERMINATE);
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ assertNull(affectedConnectionPoints.getValue());
+ verify(logger).warn("Unable to send information related to affected connection points during forceful termination");
+ }
+
+ /**
+ * test end notification scenario for failed scale-out
+ * - LCN is sent to VF-C, but the
+ */
+ @Test
+ public void testMissingPreResultForFailedOperation() {
+ //given
+ recievedLcn.setOperation(OperationType.SCALE);
+ recievedLcn.setStatus(OperationStatus.FAILED);
+ recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
+ ScaleVnfRequest request = new ScaleVnfRequest();
+ request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
+ request.setType(ScaleDirection.OUT);
+ scaleOperation.setOperationParams(request);
+ scaleOperation.setAdditionalData(null);
+ scaleOperation.setStatus(OperationStatus.FAILED);
+ scaleOperation.setOperationType(OperationType.SCALE);
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ assertEquals(0, affectedConnectionPoints.getValue().getPost().size());
+ assertEquals(0, affectedConnectionPoints.getValue().getPre().size());
+ verify(logger).warn("The operation failed and the affected connection points were not reported");
+ }
+
+ /**
+ * test end notification success scenario for scale-out
+ * - LCN is sent to VF-C
+ */
+ @Test
+ public void testMissingPreResult() {
+ //given
+ recievedLcn.setOperation(OperationType.SCALE);
+ recievedLcn.setStatus(OperationStatus.FINISHED);
+ recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
+ ScaleVnfRequest request = new ScaleVnfRequest();
+ request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
+ request.setType(ScaleDirection.OUT);
+ scaleOperation.setOperationParams(request);
+ JsonObject additionalData = new JsonObject();
+ additionalData.add("operationResult", new JsonObject());
+ scaleOperation.setAdditionalData(additionalData);
+ scaleOperation.setStatus(OperationStatus.FINISHED);
+ scaleOperation.setOperationType(OperationType.SCALE);
+ JsonElement root = new JsonParser().parse("{ \"additionalParams\" : { \"jobId\" : \"" + JOB_ID + "\"}}");
+ JsonObject operationParams = new JsonObject();
+ //when
+ try {
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ fail();
+ } catch (Exception e) {
+ assertEquals("All operations must return the { \"operationResult\" : { \"cbam_pre\" : [<fillMeOut>], \"cbam_post\" : [<fillMeOut>] } } structure", e.getMessage());
+ }
+ }
+
+ /**
+ * missing connection points are tolerated in case of failed operations
+ */
+ @Test
+ public void testMissingConnectionPoints() {
+ //given
+ recievedLcn.setOperation(OperationType.INSTANTIATE);
+ recievedLcn.setStatus(OperationStatus.FAILED);
+ recievedLcn.setLifecycleOperationOccurrenceId(instantiationOperation.getId());
+ instantiationOperation.setAdditionalData(null);
+ instantiationOperation.setStatus(OperationStatus.FAILED);
+ //when
+ lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+ assertEquals(0, affectedConnectionPoints.getValue().getPost().size());
+ assertEquals(0, affectedConnectionPoints.getValue().getPre().size());
+ verify(logger).warn("The operation failed and the affected connection points were not reported");
+ }
+
+ private JsonObject buildTerminationParams() {
+ JsonObject root = new JsonObject();
+ root.add("terminationType", new JsonPrimitive("GRACEFULL"));
+ return root;
+ }
+
+ private OperationExecution buildOperation(OffsetDateTime baseTime, OperationType operationType) {
+ OperationExecution operation = new OperationExecution();
+ operation.setStartTime(baseTime);
+ operation.setOperationType(operationType);
+ return operation;
+ }
+
+ class OperationResult {
+ ReportedAffectedConnectionPoints operationResult;
+ }
+
+}