diff options
9 files changed, 331 insertions, 113 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/SOWorkflows.kt b/vid-app-common/src/main/java/org/onap/vid/model/SOWorkflows.kt index ea13a76a2..0930c89aa 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/SOWorkflows.kt +++ b/vid-app-common/src/main/java/org/onap/vid/model/SOWorkflows.kt @@ -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, diff --git a/vid-app-common/src/main/java/org/onap/vid/services/LocalWorkflowsServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/LocalWorkflowsServiceImpl.java index 39d433d6a..71d577cd4 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/LocalWorkflowsServiceImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/LocalWorkflowsServiceImpl.java @@ -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()); } } diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js index 28b3eea5d..5c29fb4ae 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js @@ -69,6 +69,10 @@ return (featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH)); }; + $scope.removeVendorFromCloudOwner = function(cloudOwner) { + return AaiService.removeVendorFromCloudOwner(cloudOwner) + }; + vm.isDisabledVNFmodelVersion = function (vnfTypePristine) { if ($scope.isNewFilterChangeManagmentEnabled()) { return !vm.isSearchedVNF; @@ -225,7 +229,7 @@ $uibModalInstance.close(); }; - vm.uploadConfigFile = function (file) { + vm.uploadConfigFile = function (file, item) { var defer = $q.defer(); Upload.upload({ url: "change-management/uploadConfigUpdateFile", @@ -235,7 +239,7 @@ }] }) .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) { @@ -443,6 +447,19 @@ } }; + 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? @@ -456,11 +473,18 @@ } 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 () { @@ -517,8 +541,19 @@ }); }; + function loadCloudRegions() { + AaiService.getLcpCloudRegionTenantList( + vm.changeManagement.subscriberId, + vm.changeManagement.serviceType["service-type"], + function (response) { + $scope.cloudRegionList = _.uniqBy(response, 'cloudRegionOptionId'); + }); + } + vm.serviceTypeChanged = function () { - if (!$scope.isNewFilterChangeManagmentEnabled()) { + if ($scope.isNewFilterChangeManagmentEnabled()) { + loadCloudRegions(); + } else { vm.searchVNFs(); } }; @@ -533,17 +568,22 @@ vm.vnfs = []; vm.vfModules = []; - let vnfRole = $scope.isNewFilterChangeManagmentEnabled() ? vm.changeManagement.vnfType : null; + + let vnfRole = null; let cloudRegion = null; + if ($scope.isNewFilterChangeManagmentEnabled()) { + vnfRole = vm.changeManagement.vnfType ? vm.changeManagement.vnfType : null; + cloudRegion = vm.changeManagement.cloudRegion ? vm.changeManagement.cloudRegion.cloudRegionId : null; + } + AaiService.getVnfsByCustomerIdAndServiceType( vm.changeManagement.subscriberId, vm.changeManagement.serviceType["service-type"], vnfRole, cloudRegion, - ). - then(function (response) { + ).then(function (response) { vm.isSearchedVNF = true; var vnfsData = response.data.results; if (vnfsData) { @@ -581,6 +621,9 @@ vm.vnfTypes.push(vnf.properties['nf-role']) }); } + if ($scope.isNewFilterChangeManagmentEnabled()) { + vm.loadVNFVersions(); + } } ); }; @@ -856,21 +899,23 @@ 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) => { diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.test.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.test.js index 675c1b7c0..e8cba4aa8 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.test.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.test.js @@ -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); diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css index 19b5f2b92..031ffb4d4 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css @@ -138,7 +138,7 @@ } .nf-role-input { - width: 50% + width: 39% } /*LESS*/ diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html index f06d88321..a839ef547 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html @@ -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">×</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> @@ -73,19 +73,35 @@ <div class="col nf-role-input"> <label class="control-label">NF Role</label> <input class="form-control" ng-model="vm.changeManagement.vnfType" - name="vnfType" id="vnfTypeInput" + name="vnfType" id="vnfTypeInput" data-tests-id="vnfType" data-ng-disabled="newChangeManagement.serviceType.$pristine"> </div> + <div class="col nf-role-input"> + <label class="control-label">Cloud Region</label> + <select name="cloud-region" class="form-control" ng-model="vm.changeManagement.cloudRegion" + name="vnfType" id="cloudRegion" + data-ng-disabled="newChangeManagement.serviceType.$pristine"> + <option value="" disabled>select cloud Region</option> + <option ng-repeat="option in cloudRegionList" value="{{option.cloudRegionOptionId}}" + data-ng-if="option.isPermitted && !isFeatureFlagCloudOwner">{{option.cloudRegionId}} + </option> + <option ng-repeat="option in cloudRegionList" value="{{option.cloudRegionOptionId}}" + data-ng-if="option.isPermitted && isFeatureFlagCloudOwner"> + {{option.cloudRegionId}} ({{removeVendorFromCloudOwner(option.cloudOwner).toUpperCase()}}) + </option> + </select> + </div> + <div class="col"> - <button class="search-vnf" type="button" id="searchVNF" name="searchVNFs" class="btn btn-primary" + <button class="btn btn-primary search-vnf" type="button" id="searchVNF" name="searchVNFs" ng-click="vm.searchVNFs()" - ng-disabled="newChangeManagement.subscriber.$pristine || newChangeManagement.serviceType.$pristine"> + ng-disabled="newChangeManagement.subscriber.$pristine || newChangeManagement.serviceType.$pristine" + data-tests-id="searchVNFs"> Search VNFs </button> </div> </div> - </div> @@ -142,16 +158,16 @@ <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> @@ -161,8 +177,8 @@ <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> diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js index 994a3e4ac..0e1beefb6 100755 --- a/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js @@ -86,6 +86,23 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE }).join("&"); } + function getConfigParams(vnfRole, cloudRegion) { + if (!featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH)) { + return null + } + + let data = { + vnfRole: vnfRole, + cloudRegion: cloudRegion, + }; + + let config = { + params: data + }; + + return config; + } + return { getSubscriberName: function (globalCustomerId, successCallbackFunction) { @@ -630,24 +647,17 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE }, getVnfsByCustomerIdAndServiceType: function (globalSubscriberId, serviceType, vnfRole, cloudRegion) { - var deferred = $q.defer(); + let deferred = $q.defer(); let url = globalSubscriberId + COMPONENT.FORWARD_SLASH + serviceType - if (featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH)){ - if (vnfRole) { - url + COMPONENT.FORWARD_SLASH + vnfRole - } - if (cloudRegion) { - url + COMPONENT.FORWARD_SLASH + cloudRegion; - } - } - + const path = COMPONENT.AAI_GET_VNF_BY_CUSTOMERID_AND_SERVICETYPE + url; + let config = getConfigParams(vnfRole, cloudRegion); if (UtilityService.hasContents(globalSubscriberId) && UtilityService.hasContents(serviceType)) { - $http.get(COMPONENT.AAI_GET_VNF_BY_CUSTOMERID_AND_SERVICETYPE + url) + $http.get(path, config) .success(function (response) { if (response) { deferred.resolve({data: response}); diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java index 3e38ba883..83cc61ea4 100644 --- a/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java @@ -39,6 +39,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; +import java.util.List; import java.util.Map; import java.util.UUID; import javax.ws.rs.core.Response; @@ -295,10 +296,10 @@ public class AaiControllerTest { given(aaiService.getAaiZones()).willReturn(new AaiResponse(aicZones, "", HttpStatus.OK.value())); mockMvc.perform(get("/aai_get_aic_zones") - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().json(objectMapper.writeValueAsString(aicZones))); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(aicZones))); } @Test @@ -308,32 +309,32 @@ public class AaiControllerTest { .willReturn(new AaiResponse(null, expectedErrorMessage, HttpStatus.INTERNAL_SERVER_ERROR.value())); mockMvc.perform(get("/aai_get_aic_zones") - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isInternalServerError()) - .andExpect(content().string(expectedErrorMessage)); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isInternalServerError()) + .andExpect(content().string(expectedErrorMessage)); } @Test public void getSpecificPnf_shouldReturnPnfObjectForPnfId() throws Exception { String pnfId = "MyPnfId"; Pnf pnf = Pnf.builder() - .withPnfId(pnfId) - .withPnfName("TestPnf") - .withPnfName2("pnfName2") - .withPnfName2Source("pnfNameSource") - .withEquipModel("model") - .withEquipType("type") - .withEquipVendor("vendor") - .build(); + .withPnfId(pnfId) + .withPnfName("TestPnf") + .withPnfName2("pnfName2") + .withPnfName2Source("pnfNameSource") + .withEquipModel("model") + .withEquipType("type") + .withEquipVendor("vendor") + .build(); AaiResponse<Pnf> aaiResponse = new AaiResponse<>(pnf, "", HttpStatus.OK.value()); given(aaiService.getSpecificPnf(pnfId)).willReturn(aaiResponse); mockMvc.perform(get("/aai_get_pnfs/pnf/{pnf_id}", pnfId) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().json(objectMapper.writeValueAsString(pnf))); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(pnf))); } @Test @@ -343,10 +344,10 @@ public class AaiControllerTest { given(aaiService.getSpecificPnf(pnfId)).willThrow(new RuntimeException(expectedErrorMessage)); mockMvc.perform(get("/aai_get_pnfs/pnf/{pnf_id}", pnfId) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isInternalServerError()) - .andExpect(content().string(expectedErrorMessage)); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isInternalServerError()) + .andExpect(content().string(expectedErrorMessage)); } public void getPNFInstances_shouldReturnOKResponseFromAAIService() throws Exception { @@ -366,12 +367,12 @@ public class AaiControllerTest { equipModel)).willReturn(aaiResponse); mockMvc.perform( - get(urlTemplate, globalCustomerId, serviceType, modelVersionId, - modelInvariantId, cloudRegion, equipVendor, equipModel) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(expectedResponseBody)); + get(urlTemplate, globalCustomerId, serviceType, modelVersionId, + modelInvariantId, cloudRegion, equipVendor, equipModel) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponseBody)); } @Test @@ -385,12 +386,12 @@ public class AaiControllerTest { .getVersionByInvariantId(request.versions)).willReturn(response); mockMvc.perform( - post("/aai_get_version_by_invariant_id") - .content(objectMapper.writeValueAsString(request)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(expectedResponse)); + post("/aai_get_version_by_invariant_id") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponse)); } @Test @@ -408,12 +409,12 @@ public class AaiControllerTest { .willReturn(aaiResponse); mockMvc.perform( - get("/aai_sub_details/{subscriberId}", subscriberId) - .param("omitServiceInstances", Boolean.toString(omitServiceInstances)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(objectMapper.writeValueAsString(okResponseBody))); + get("/aai_sub_details/{subscriberId}", subscriberId) + .param("omitServiceInstances", Boolean.toString(omitServiceInstances)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(okResponseBody))); } @Test @@ -437,50 +438,98 @@ public class AaiControllerTest { @Test public void getPortMirroringConfigData_givenThreeIds_ReturnsThreeResults() { - final AaiResponseTranslator.PortMirroringConfigDataOk toBeReturnedForA = new AaiResponseTranslator.PortMirroringConfigDataOk("foobar"); - final AaiResponseTranslator.PortMirroringConfigDataError toBeReturnedForB = new AaiResponseTranslator.PortMirroringConfigDataError("foo", "{ baz: qux }"); - final AaiResponseTranslator.PortMirroringConfigDataOk toBeReturnedForC = new AaiResponseTranslator.PortMirroringConfigDataOk("corge"); + final AaiResponseTranslator.PortMirroringConfigDataOk toBeReturnedForA = new AaiResponseTranslator.PortMirroringConfigDataOk( + "foobar"); + final AaiResponseTranslator.PortMirroringConfigDataError toBeReturnedForB = new AaiResponseTranslator.PortMirroringConfigDataError( + "foo", "{ baz: qux }"); + final AaiResponseTranslator.PortMirroringConfigDataOk toBeReturnedForC = new AaiResponseTranslator.PortMirroringConfigDataOk( + "corge"); Mockito - .doReturn(toBeReturnedForA) - .doReturn(toBeReturnedForB) - .doReturn(toBeReturnedForC) - .when(aaiService).getPortMirroringConfigData(Mockito.anyString()); + .doReturn(toBeReturnedForA) + .doReturn(toBeReturnedForB) + .doReturn(toBeReturnedForC) + .when(aaiService).getPortMirroringConfigData(Mockito.anyString()); - final Map<String, AaiResponseTranslator.PortMirroringConfigData> result = aaiController.getPortMirroringConfigsData(ImmutableList.of("a", "b", "c")); + final Map<String, AaiResponseTranslator.PortMirroringConfigData> result = aaiController + .getPortMirroringConfigsData(ImmutableList.of("a", "b", "c")); assertThat(result, is(ImmutableMap.of( - "a", toBeReturnedForA, - "b", toBeReturnedForB, - "c", toBeReturnedForC + "a", toBeReturnedForA, + "b", toBeReturnedForB, + "c", toBeReturnedForC ))); } @Test public void getSubscriberDetails_shouldIncludeServiceInstancesFromSubscriberData_whenFeatureDisabled_andOmitFlagIsFalse() - throws Exception { + throws Exception { boolean isFeatureActive = false; boolean omitServiceInstances = false; getSubscriberDetails_assertServiceInstancesInclusion(isFeatureActive, omitServiceInstances); } private void getSubscriberDetails_assertServiceInstancesInclusion(boolean isFeatureActive, - boolean omitServiceInstances) throws Exception { + boolean omitServiceInstances) throws Exception { String subscriberId = "subscriberId"; String okResponseBody = "OK_RESPONSE"; AaiResponse<String> aaiResponse = new AaiResponse<>(okResponseBody, "", HttpStatus.OK.value()); given(featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH)).willReturn(isFeatureActive); given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidatorByRoles.class), - eq(isFeatureActive && omitServiceInstances))) - .willReturn(aaiResponse); + eq(isFeatureActive && omitServiceInstances))) + .willReturn(aaiResponse); mockMvc.perform( - get("/aai_sub_details/{subscriberId}", subscriberId) - .param("omitServiceInstances", Boolean.toString(omitServiceInstances)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(objectMapper.writeValueAsString(okResponseBody))); + get("/aai_sub_details/{subscriberId}", subscriberId) + .param("omitServiceInstances", Boolean.toString(omitServiceInstances)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(okResponseBody))); + } + + @Test + public void getSpecificConfiguration_shouldReturnOkResponse() throws Exception { + String configurationId = "testGlobalCustomerId"; + String expectedResponseBody = "OK_RESPONSE"; + Response response = mock(Response.class); + given(response.readEntity(String.class)).willReturn(expectedResponseBody); + given(response.getStatus()).willReturn(HttpStatus.OK.value()); + + given(aaiRestInterface.RestGet( + eq("VidAaiController"), + anyString(), + eq(Unchecked.toURI("network/configurations/configuration/" + configurationId)), + eq(false)).getResponse()).willReturn(response); + + mockMvc + .perform( + get("/aai_get_configuration/{configuration_id}", configurationId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponseBody)); } + + @Test + public void getServiceInstanceAssociatedPnfs_shouldReturnPnfs() throws Exception { + String globalCustomerId = "testCustomerId"; + String serviceType = "testServiceType"; + String serviceInstanceId = "testServiceInstanceId"; + List<String> expectedPnfs = ImmutableList.of("pnf1", "pnf2", "pnf3"); + + given(aaiService.getServiceInstanceAssociatedPnfs(globalCustomerId, serviceType, serviceInstanceId)) + .willReturn(expectedPnfs); + + mockMvc + .perform( + get("/aai_get_service_instance_pnfs/{globalCustomerId}/{serviceType}/{serviceInstanceId}", + globalCustomerId, serviceType, serviceInstanceId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(expectedPnfs))); + } + } diff --git a/vid-automation/src/main/java/vid/automation/test/test/ChangeManagementTest.java b/vid-automation/src/main/java/vid/automation/test/test/ChangeManagementTest.java index 4da713a74..ed0180dd9 100644 --- a/vid-automation/src/main/java/vid/automation/test/test/ChangeManagementTest.java +++ b/vid-automation/src/main/java/vid/automation/test/test/ChangeManagementTest.java @@ -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() { |