Change-management: provide and use scheduler's fields through vm.scheduleWorkflow() 26/96126/3
authorIttay Stern <ittay.stern@att.com>
Sun, 22 Sep 2019 17:04:28 +0000 (20:04 +0300)
committerIttay Stern <ittay.stern@att.com>
Mon, 23 Sep 2019 09:48:51 +0000 (12:48 +0300)
In addition, show error message when no Portal-frame. Use the dumped
data to revive ChangeManagementTest tests by capturing the error's
payload.

Issue-ID: VID-397

Change-Id: I978bf537c43b0e3933e82c761c60cd067ab2cf27
Signed-off-by: Ittay Stern <ittay.stern@att.com>
vid-app-common/src/main/java/org/onap/vid/model/SOWorkflows.kt
vid-app-common/src/main/java/org/onap/vid/services/LocalWorkflowsServiceImpl.java
vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.test.js
vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html
vid-automation/src/main/java/vid/automation/test/test/ChangeManagementTest.java

index ea13a76..0930c89 100644 (file)
@@ -72,6 +72,7 @@ data class SOWorkflowParameterDefinitions constructor(
 data class LocalWorkflowParameterDefinition @JvmOverloads constructor(
         val id: Long,
         val name: String,
+        val displayName: String,
         val required: Boolean,
         val type: LocalWorkflowType,
         val pattern: String? = null,
index 39d433d..71d577c 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.onap.vid.services;
 
+import static java.util.Collections.emptyList;
+
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.util.Map;
@@ -33,26 +35,31 @@ public class LocalWorkflowsServiceImpl implements LocalWorkflowsService {
     Map<String, LocalWorkflowParameterDefinitions> WORKFLOWS_WITH_PARAMETERS = ImmutableMap.<String, LocalWorkflowParameterDefinitions>builder()
         .put("VNF Scale Out", new LocalWorkflowParameterDefinitions(
             ImmutableList.of(
-                new LocalWorkflowParameterDefinition(1, "Configuration Parameters", true, LocalWorkflowType.text,".*")
+                new LocalWorkflowParameterDefinition(1, "configurationParameters", "Configuration Parameters", true, LocalWorkflowType.text,".*")
             )
         ))
         .put("VNF In Place Software Update", new LocalWorkflowParameterDefinitions(
             ImmutableList.of(
-                new LocalWorkflowParameterDefinition(2, "Operations timeout",true, LocalWorkflowType.text,"[0-9]+"),
-                new LocalWorkflowParameterDefinition(3, "Existing software version", true, LocalWorkflowType.text, "[-a-zA-Z0-9.]+"),
-                new LocalWorkflowParameterDefinition(4, "New software version", true, LocalWorkflowType.text, "[-a-zA-Z0-9.]+")
+                new LocalWorkflowParameterDefinition(2, "operationTimeout", "Operations timeout", true, LocalWorkflowType.text,"[0-9]+"),
+                new LocalWorkflowParameterDefinition(3, "existingSoftwareVersion", "Existing software version", true, LocalWorkflowType.text, "[-a-zA-Z0-9.]+"),
+                new LocalWorkflowParameterDefinition(4, "newSoftwareVersion", "New software version", true, LocalWorkflowType.text, "[-a-zA-Z0-9.]+")
             )
         ))
         .put("VNF Config Update", new LocalWorkflowParameterDefinitions(
             ImmutableList.of(
-                new LocalWorkflowParameterDefinition(5, "Attach configuration file", true, LocalWorkflowType.FILE, ".*", "Invalid file type. Please select a file with a CSV extension.", "Invalid file structure.", ".csv")
+                new LocalWorkflowParameterDefinition(5, "configUpdateFile", "Attach configuration file", true, LocalWorkflowType.FILE, ".*", "Invalid file type. Please select a file with a CSV extension.", "Invalid file structure.", ".csv")
             )
         ))
         .build();
 
+
+    private LocalWorkflowParameterDefinitions defaultEmptyParams() {
+        return new LocalWorkflowParameterDefinitions(emptyList());
+    }
+
     @Override
     public LocalWorkflowParameterDefinitions getWorkflowParameterDefinitions(String workflowName) {
-        return WORKFLOWS_WITH_PARAMETERS.get(workflowName);
+        return WORKFLOWS_WITH_PARAMETERS.getOrDefault(workflowName, defaultEmptyParams());
     }
 
 }
index 28b3eea..f70d625 100644 (file)
             $uibModalInstance.close();
         };
 
-        vm.uploadConfigFile = function (file) {
+        vm.uploadConfigFile = function (file, item) {
             var defer = $q.defer();
             Upload.upload({
                 url: "change-management/uploadConfigUpdateFile",
                 }]
             })
                 .then(function (configUpdateResponse) {
-                    vm.getInternalWorkFlowParameter("VNF Config Update", "FILE", "Attach configuration file").value = configUpdateResponse && JSON.parse(configUpdateResponse.data).payload;
+                    item.value = configUpdateResponse && JSON.parse(configUpdateResponse.data).payload;
                     defer.resolve(true);
                 })
                 .catch(function (error) {
             }
         };
 
+        vm.collectWorkflowFieldsValues = function () {
+            /**
+             * Transforms items with name and value properties, to associative map, e.g the array
+             * [{name: foo, value: bar}, {name: baz, value: fiz}] will become the object {foo: bar, baz: fiz}
+             */
+            return vm.getAllInternalWorkFlowParameters(
+                    vm.changeManagement.workflow
+            ).reduce(function (result, item) {
+                result[item.name] = item.value;
+                return result;
+            }, {});
+        };
+
         vm.scheduleWorkflow = function () {
             $scope.widgetParameter = ""; // needed by the scheduler?
 
             }
             var data = {
                 widgetName: 'Portal-Common-Scheduler',
-                widgetData: vm.changeManagement,
+                widgetData: Object.assign({}, vm.changeManagement, vm.collectWorkflowFieldsValues()),
                 widgetParameter: $scope.widgetParameter
             };
 
-            window.parent.postMessage(data, VIDCONFIGURATION.SCHEDULER_PORTAL_URL);
+            console.log("vm.scheduleWorkflow data:", data);
+
+            if (window.parent !== window.self) {
+                window.parent.postMessage(data, VIDCONFIGURATION.SCHEDULER_PORTAL_URL);
+            } else {
+                vm.errorMsg = {message: "Portal not found. Cannot send: " + JSON.stringify(data)};
+                throw vm.errorMsg; // prevent popup closure
+            }
         };
 
         vm.executeWorkflow = function () {
             return form[itemName].$error.validateAsyncFn;
         };
 
-        vm.getIdFor = function (type, id, name) {
-            return "internal-workflow-parameter-" + type + "-" + id + "-" + (name ? name.split(' ').join('-').toLowerCase() : "");
+        vm.getIdFor = function (type, item) {
+            return "internal-workflow-parameter-" + type + "-" + item.id + "-" + (item.displayName ? item.displayName.split(' ').join('-').toLowerCase() : "");
         };
 
-        vm.getInternalWorkFlowParameters = function (workflow, type) {
-            if (workflow && vm.localWorkflowsParameters.has(workflow) && vm.localWorkflowsParameters.get(workflow).filter(parameter => parameter.type == type) != []) {
-                return vm.localWorkflowsParameters.get(workflow).filter(parameter => parameter.type == type);
+        vm.getAllInternalWorkFlowParameters = function (workflow) {
+            if (workflow && vm.localWorkflowsParameters.has(workflow) && vm.localWorkflowsParameters.get(workflow)) {
+                return vm.localWorkflowsParameters.get(workflow);
             }
             return [];
         };
 
+        vm.getInternalWorkFlowParameters = function (workflow, type) {
+            return vm.getAllInternalWorkFlowParameters(workflow).filter(parameter => parameter.type === type);
+        };
+
         vm.getInternalWorkFlowParameter = function (workflow, type, parameterName) {
-            if (workflow && vm.localWorkflowsParameters.has(workflow) && vm.localWorkflowsParameters.get(workflow).filter(parameter => parameter.type == type) != []) {
-                return vm.localWorkflowsParameters.get(workflow).filter(parameter => parameter.type == type).filter(parameter => parameter.name === parameterName)[0]
-            }
+            return vm.getInternalWorkFlowParameters(workflow, type).filter(parameter => parameter.displayName === parameterName)[0];
         };
 
         vm.getRemoteWorkflowSource = (workflow) => {
index 675c1b7..e8cba4a 100644 (file)
@@ -318,6 +318,23 @@ describe('Testing workFlows from SO', () => {
     });
   });
 
+  test('Verify get internal workflow parameters should return an empty list if type exist but mapped to undefined', () => {
+    // given
+    $featureFlags.isOn = jestMock.fn(() => false);
+    let getWorkflowsStub = Promise.resolve({"data": {"workflows": ["VNF Scale Out"]}});
+    let getLocalWorkflowsParametersStub = Promise.resolve({"data": undefined});
+
+    $controller.changeManagement.vnfNames = [{name: 'test1'}];
+    $changeManagementService.getWorkflows = () => getWorkflowsStub;
+    $changeManagementService.getLocalWorkflowParameter = () => getLocalWorkflowsParametersStub;
+    // when
+    return $controller.loadWorkFlows()
+    .then(() => {
+      let internalWorkFlowParameters = $controller.getInternalWorkFlowParameters("VNF Scale Out", "FILE");
+      expect(internalWorkFlowParameters).toEqual([]);
+    });
+  });
+
   test('Verify get internal workflow parameters should return a list if such workflow and type exist', () => {
     // given
     $featureFlags.isOn = jestMock.fn(() => false);
index f06d883..40bb92b 100644 (file)
@@ -22,7 +22,7 @@
 <div class="modal-header">
     <h3 class="modal-title" id="modal-title">New VNF Change</h3>
     <span ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
-    <div ng-if="vm.errorMsg!==''"><font color='red'>{{vm.errorMsg.message}}</font></div>
+    <div ng-if="vm.errorMsg!==''" style="max-height: 150px; overflow: auto;" data-tests-id="error-message"><font color='red'>{{vm.errorMsg.message}}</font></div>
 </div>
 <form class="form-create" data-tests-id="newChangeManagementForm" name="newChangeManagement"
       ng-submit="vm.openModal();vm.close();" novalidate>
 
         <div class="form-group" ng-if="vm.changeManagement.workflow"
              ng-repeat="item in vm.getInternalWorkFlowParameters(vm.changeManagement.workflow, 'FILE')">
-            <label class="control-label">{{item.name}}</label>
+            <label class="control-label">{{item.displayName}}</label>
             <div class="file-wrapper">
-                <input id="{{vm.getIdFor('file',item.id,item.name)}}" ng-change="vm.onChange(item)" class="file-input"
-                       type="file" ngf-select ng-model="item.value" ngf-validate-async-fn="vm.uploadConfigFile($file)"
+                <input id="{{vm.getIdFor('file',item)}}" ng-change="vm.onChange(item)" class="file-input"
+                       type="file" ngf-select ng-model="item.file" ngf-validate-async-fn="vm.uploadConfigFile($file, item)"
                        ng-attr-name="{{'internal-workflow-parameter-file-name-' + item.id}}"
                        accept="{{item.acceptableFileType}}" ngf-pattern="{{item.acceptableFileType}}"
                        ng-required="{{item.required}}"/>
-                <label id="{{vm.getIdFor('file',item.id,item.name)}}-label" class="file-input-label">
-                    {{item.value&&item.value.name||"Select File"}} </label>
-                <label ng-attr-for="{{vm.getIdFor('file',item.id,item.name)}}"><span class="icon-browse"></span></label>
+                <label id="{{vm.getIdFor('file',item)}}-label" class="file-input-label">
+                    {{item.file&&item.file.name||"Select File"}} </label>
+                <label ng-attr-for="{{vm.getIdFor('file',item)}}"><span class="icon-browse"></span></label>
             </div>
             <label id="errorLabel" class="icon-alert error"
                    ng-if="vm.hasPatternError(newChangeManagement, 'internal-workflow-parameter-file-name-' + item.id)">{{item.msgOnPatternError}}</label>
 
         <div class="form-group" ng-if="vm.changeManagement.workflow"
              ng-repeat="item in vm.getInternalWorkFlowParameters(vm.changeManagement.workflow, 'text')">
-            <label ng-attr-for="{{vm.getIdFor('text',item.id,item.name)}}" class="control-label">{{item.name}}</label>
-            <input ng-model="item.value" type="text" id="{{vm.getIdFor('text',item.id,item.name)}}"
+            <label ng-attr-for="{{vm.getIdFor('text',item)}}" class="control-label">{{item.displayName}}</label>
+            <input ng-model="item.value" type="text" id="{{vm.getIdFor('text',item)}}"
                    pattern="{{item.pattern}}" ng-required="{{item.required}}">
         </div>
 
index 4da713a..ed0180d 100644 (file)
@@ -1,11 +1,14 @@
 package vid.automation.test.test;
 
 
+import static java.util.Collections.emptyMap;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.everyItem;
 import static org.hamcrest.CoreMatchers.hasItem;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.collection.IsEmptyCollection.empty;
@@ -15,6 +18,7 @@ import static org.onap.vid.api.BaseApiTest.getResourceAsString;
 import static vid.automation.test.infra.Features.FLAG_FLASH_REDUCED_RESPONSE_CHANGEMG;
 import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.primitives.Ints;
 import java.sql.Connection;
@@ -23,8 +27,10 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import net.javacrumbs.jsonunit.core.Option;
 import org.json.JSONException;
 import org.junit.Assert;
 import org.onap.sdc.ci.tests.datatypes.UserCredentials;
@@ -60,6 +66,7 @@ import vid.automation.test.utils.DB_CONFIG;
 public class ChangeManagementTest extends VidBaseTestCase {
 
     public static final String SCHEDULED_ID = "0b87fe60-50b0-4bac-a0a7-49e951b0ba9e";
+    private final String SCHEDULE_ERROR_PREFIX = "Portal not found. Cannot send: ";
 
     @Test
     public void testLeftPanelChangeManagementButton() {
@@ -484,10 +491,33 @@ public class ChangeManagementTest extends VidBaseTestCase {
         };
     }
 
-    // Deleted testVidToMsoCallbackDataWithInPlaceSWUpdate test. It was using assertThatVidToMsoCallbackDataIsOk which is no longer valid.
+    @Test(dataProvider = "dataForUpdateWorkflowPartialWithInPlace")
+    public void testVidToMsoCallbackDataWithInPlaceSWUpdate(String operationsTimeout, String existingSwVersion, String newSwVersion) {
 
+        openAndFill1stScreenWithWorkflowVNFInPlaceSoftwareUpdate();
+        fillVNFInPlace3Fields(operationsTimeout, existingSwVersion, newSwVersion);
+
+        assertThatVidToPortalCallbackDataIsOk(VNF_DATA_WITH_IN_PLACE.workflowName, ImmutableMap.of(
+            "existingSoftwareVersion", existingSwVersion,
+            "newSoftwareVersion", newSwVersion,
+            "operationTimeout", operationsTimeout
+        ));
+    }
+
+    @Test
+    public void testUploadConfigUpdateFile() {
+        String fileName = "configuration_file.csv";
+        updateConfigFile(fileName);
+        Assert.assertEquals(Get.byId(Constants.ChangeManagement.newModalConfigUpdateInputId + "-label").getText(), fileName);
+        Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
+        assertThatVidToPortalCallbackDataIsOk("VNF Config Update", ImmutableMap.of(
+            "configUpdateFile",
+            "{\"request-parameters\":{\"vm\":[{\"vnfc\":["
+                + "{\"vnfc-name\":\"ibcx0001vm001dbg001\",\"vnfc-function-code\":\"dbg\"}],\"vm-name\":\"ibcx0001vm001\"},"
+                + "{\"vnfc\":[{\"vnfc-name\":\"ibcx0001vm002dbg001\"}],\"vm-name\":\"ibcx0001vm002\"}]},\"configuration-parameters\":{\"node0_hostname\":\"dbtx0001vm001\"}}"
+        ));
+    }
 
-    // Deleted testUploadConfigUpdateFile test. It was using assertThatVidToMsoCallbackDataIsOk which is no longer valid.
     @FeatureTogglingTest(value = Features.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH, flagActive = false)
     @Test
     public void testUploadConfigUpdateNonCsvFile() {
@@ -516,7 +546,14 @@ public class ChangeManagementTest extends VidBaseTestCase {
         };
     }
 
-    // Deleted testVidToMsoCallbackData test. It was using assertThatVidToMsoCallbackDataIsOk which is no longer valid.
+    @Test
+    public void testVidToMsoCallbackData() {
+        String workflow = "Replace";
+
+        openAndFill1stScreen(VNF_DATA_WITH_IN_PLACE.vnfName, VNF_DATA_WITH_IN_PLACE.vnfTargetVersion, workflow);
+
+        assertThatVidToPortalCallbackDataIsOk(workflow, emptyMap());
+    }
 
     private void assertThatVidToMsoCallbackDataIsOk(String workflow, String payload) {
         Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
@@ -537,6 +574,42 @@ public class ChangeManagementTest extends VidBaseTestCase {
         Click.byId(Constants.generalCancelButtonId);
     }
 
+    private void assertThatVidToPortalCallbackDataIsOk(String workflowName, Map<String, String> workflowParams) {
+        Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
+        Click.byId(Constants.generalSubmitButtonId);
+
+        String errorMessage = GeneralUIUtils.getWebElementByTestID("error-message", 2).getText();
+
+        String modelInvariantId = "72e465fe-71b1-4e7b-b5ed-9496118ff7a8";
+        String vnfInstanceId = "8e5e3ba1-3fe6-4d86-966e-f9f03dab4855";
+
+            assertThat(errorMessage, startsWith(SCHEDULE_ERROR_PREFIX));
+            assertThat(errorMessage.replace(SCHEDULE_ERROR_PREFIX, ""), jsonEquals(
+                ImmutableMap.of(
+                    "widgetName", "Portal-Common-Scheduler",
+                    "widgetParameter", "",
+                    "widgetData", ImmutableMap.builder()
+                        .put("vnfNames", ImmutableList.of(ImmutableMap.of(
+                            "id", vnfInstanceId,
+                            "invariant-id", modelInvariantId
+                        )))
+                        .put("workflowParameters", emptyMap())
+                        .put("subscriberId", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb")
+                        .put("fromVNFVersion", "" + "76e908e0-5201-44d2-a3e2-9e6128d05820" + "")
+                        .put("workflow", "" + workflowName + "")
+                        .put("policyYN", "Y")
+                        .put("sniroYN", "Y")
+                        .put("testApi", "VNF_API")
+                        .put("vnfType", "vMobileDNS")
+                        .putAll(workflowParams)
+                    .build()
+                    )
+                ).when(Option.IGNORING_EXTRA_FIELDS));
+
+
+        Click.byId(Constants.generalCancelButtonId);
+    }
+
     @Test(enabled = false)
     public void testUpdateWorkflowNow() {