Fix for Penetration test _ Session and cookie management
[vid.git] / vid-app-common / src / main / webapp / app / vid / scripts / modals / new-change-management / new-change-management.controller.js
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2020 Nokia Intellectual Property. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 (function () {
23     'use strict';
24
25     appDS2.controller("newChangeManagementModalController", ["$uibModalInstance", "$uibModal", '$q', "AaiService", "changeManagementService", "Upload",
26         "$log", "$scope", "_", "COMPONENT", "VIDCONFIGURATION", "DataService", "featureFlags", newChangeManagementModalController]);
27
28     function newChangeManagementModalController($uibModalInstance, $uibModal, $q, AaiService, changeManagementService, Upload, $log, $scope, _, COMPONENT, VIDCONFIGURATION, DataService, featureFlags) {
29
30
31         var vm = this;
32         vm.hasScheduler = !featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_GUILIN_CHANGEMG_SUBMIT_TO_SO);
33         vm.errorMsg = '';
34
35         vm.isSearchedVNF = false;
36
37         vm.wizardStep = 1;
38         vm.nextStep = function () {
39             vm.wizardStep++;
40             $(".modal-dialog").animate({"width": "1200px"}, 400, 'linear');
41         };
42         vm.prevStep = function () {
43             vm.wizardStep--;
44             $(".modal-dialog").animate({"width": "600px"}, 400, 'linear');
45         };
46
47         vm.softwareVersionRegex = "[-a-zA-Z0-9\.]+";
48
49         var attuid;
50
51         $scope.showReportWindow = function () {
52             const modalWindow = $uibModal.open({
53                 templateUrl: 'app/vid/scripts/modals/report-modal/report-modal.html',
54                 controller: 'reportModalController',
55                 controllerAs: 'vm',
56                 resolve: {
57                     errorMsg: function () {
58                         return vm.errorMsg.message;
59                     }
60                 }
61             });
62
63         };
64
65         $scope.isShowErrorReport = function () {
66             return featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_CREATE_ERROR_REPORTS);
67         };
68
69         $scope.isNewFilterChangeManagmentEnabled = function () {
70             return (featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH));
71         };
72
73         $scope.removeVendorFromCloudOwner = function (cloudOwner) {
74             return AaiService.removeVendorFromCloudOwner(cloudOwner)
75         };
76
77         vm.isDisabledVNFmodelVersion = function (vnfTypePristine) {
78             if ($scope.isNewFilterChangeManagmentEnabled()) {
79                 return !vm.isSearchedVNF;
80             } else return vnfTypePristine;
81         };
82
83         function fetchAttUid() {
84             var defer = $q.defer();
85             if (attuid) {
86                 defer.resolve(attuid);
87             } else {
88                 AaiService.getLoggedInUserID(function (response) {
89                         attuid = response.data;
90                         defer.resolve(attuid);
91                     },
92                     function (err) {
93                         defer.reject(err);
94                         vm.errorMsg = err;
95                     });
96             }
97             return defer.promise;
98         }
99
100         var init = function () {
101             vm.changeManagement = {};
102             vm.changeManagement.workflowParameters = new Map();
103
104             loadServicesCatalog();
105             fetchAttUid().then(registerVNFNamesWatcher);
106             vm.loadSubscribers();
107         };
108
109         var loadServicesCatalog = function () {
110             changeManagementService.getAllSDCServices()
111                 .then(function (response) {
112                     vm.SDCServicesCatalog = response.data;
113                 })
114                 .catch(function (error) {
115                     $log.error(error);
116                     vm.errorMsg = err;
117                 });
118         };
119
120         var registerVNFNamesWatcher = function () {
121             $scope.$watch('vm.changeManagement.vnfNames', function (newVal, oldVal) {
122                 if (!oldVal || newVal && newVal.length > oldVal.length) { //JUST THE LAST ONE ADDED
123                     var newVNFName = _.last(vm.changeManagement.vnfNames);
124                     if (oldVal) {
125                         vm.changeManagement.vnfNames = oldVal;
126                         vm.changeManagement.vnfNames.push(newVNFName);
127                     }
128                     if (newVNFName && newVNFName["service-instance-node"]) {
129                         var availableVersions = [];
130                         var services = _.filter(vm.SDCServicesCatalog.services,
131                             {"invariantUUID": newVNFName["service-instance-node"][0].properties["model-invariant-id"]});
132
133                         _.each(services, function (service) {
134                             changeManagementService.getSDCService(service.uuid)
135                                 .then(function (response) {
136                                     _.each(response.data.vnfs, function (vnf) {
137                                         if (newVNFName["invariant-id"] === vnf.invariantUuid) {
138                                             availableVersions.push(extractVNFModel(vnf, response.data.service, newVNFName));
139
140                                             //for scale out screen
141                                             if (service.uuid === newVNFName["service-instance-node"][0].properties["model-version-id"]) {
142                                                 newVNFName.vfModules = vnf.vfModules;
143                                                 newVNFName.category = response.data.service.category;
144                                                 newVNFName.groupModules = _.groupBy(newVNFName.vfModules, "customizationUuid");
145
146                                                 //list vfmodules ids in AAI that belong to that vnf instance
147                                                 var modulesAaiIds = _.filter(newVNFName.relatedTo, function (item) {
148                                                     return item["node-type"] === "vf-module";
149                                                 }).map(function (item) {
150                                                     return item.id;
151                                                 });
152
153                                                 _.forEach(newVNFName.vfModules, function (mdl, key) {
154                                                     mdl.scale = false; //defaults to not scale unless user changes it
155                                                     if (mdl.properties && mdl.properties.maxCountInstances) {
156
157                                                         //how many vf modules of the same customizationId belong to that vnf instance
158                                                         mdl.currentCount = _.filter(vm.vfModules, function (item) {
159                                                             return modulesAaiIds.indexOf(item.id) > -1 && item.properties["model-customization-id"] === mdl.customizationUuid;
160                                                         }).length;
161
162                                                         mdl.scalable = mdl.properties.maxCountInstances - mdl.currentCount > 0;
163                                                     } else {
164                                                         mdl.scalable = false;
165                                                     }
166                                                 });
167                                             }
168                                         }
169                                     });
170                                     var versions = _.uniqBy(availableVersions, 'modelInfo.modelVersion');
171                                     newVNFName.availableVersions = _.sortBy(_.uniq(versions, response.data.service, true), "modelInfo.modelVersion");
172                                 }).catch(function (error) {
173                                 $log.error(error);
174                                 vm.errorMsg = error;
175                             });
176                         });
177                     }
178                 }
179             }, true);
180         };
181
182         var extractVNFModel = function (csarVNF, sdcService, selectionVNF) {
183             /**
184              @param selectionVNF A vnf *instance* selected in "available VNF" drop-down box
185              @param csarVNF      A VNF *MODEL* that has an invariantUuid same as selectionVNF (might be
186              a different version; i.e. selectionVNF.modelVersionId <> csarVNF.uuid)
187              @param sdcService   The Service *MODEL* which has the related VNF `csarVNF`.
188              */
189             var versionCsarData = {
190                 vnfInstanceId: "",
191                 vnfName: csarVNF.name,
192                 modelInfo: {
193                     modelType: "vnf",
194                     modelInvariantId: csarVNF.invariantUuid,
195                     modelVersionId: csarVNF.uuid,
196                     modelName: csarVNF.name,
197                     modelVersion: csarVNF.version,
198                     modelCustomizationName: csarVNF.modelCustomizationName,
199                     modelCustomizationId: csarVNF.customizationUuid
200                 },
201                 cloudConfiguration: selectionVNF.cloudConfiguration || {},
202                 requestInfo: {
203                     source: "VID",
204                     suppressRollback: false,
205                     requestorId: attuid
206                 },
207                 relatedInstanceList: [
208                     {
209                         relatedInstance: {
210                             instanceId: selectionVNF["service-instance-node"]["0"].properties['service-instance-id'],
211                             modelInfo: {
212                                 modelType: "service",
213                                 modelInvariantId: sdcService.invariantUuid,
214                                 modelVersionId: sdcService.uuid,
215                                 modelName: sdcService.name,
216                                 modelVersion: sdcService.version
217                             }
218                         }
219                     }
220                 ],
221                 requestParameters: {
222                     usePreload: true
223                 }
224             };
225
226             return versionCsarData;
227         };
228
229         vm.close = function () {
230             $uibModalInstance.close();
231         };
232
233         vm.uploadConfigFile = function (file, item) {
234             var defer = $q.defer();
235             Upload.upload({
236                 url: "change-management/uploadConfigUpdateFile",
237                 file: file,
238                 transformResponse: [function (data) {
239                     return data;
240                 }]
241             })
242                 .then(function (configUpdateResponse) {
243                     item.value = configUpdateResponse && JSON.parse(configUpdateResponse.data).payload;
244                     defer.resolve(true);
245                 })
246                 .catch(function (error) {
247                     defer.resolve(false);
248                 });
249             return defer.promise;
250         };
251
252
253         /***converting objects to scheduler format (taken from IST) - was altered for Scale out support ***/
254         function extractChangeManagementCallbackDataStr(changeManagement) {
255             var result = {};
256             result.requestType = changeManagement.workflow;
257             var workflowType = changeManagement.workflow;
258             result.requestDetails = [];
259             _.forEach(changeManagement.vnfNames, function (vnf) {
260
261                 try {
262                     var requestInfoData = {};
263                     var requestParametersData = {};
264                     var moduleToScale = _.find(vnf.vfModules, {"scale": true});
265                     if (vnf.availableVersions && vnf.availableVersions.length != 0) {
266
267                         requestInfoData = {
268                             source: vnf.availableVersions[0].requestInfo.source,
269                             suppressRollback: vnf.availableVersions[0].requestInfo.suppressRollback,
270                             requestorId: vnf.availableVersions[0].requestInfo.requestorId
271                         };
272
273                         if (workflowType == 'Update') {
274                             requestParametersData = {
275                                 usePreload: vnf.availableVersions[0].requestParameters.usePreload
276                             };
277                         } else if (workflowType == "Replace") {
278                             requestParametersData = {
279                                 rebuildVolumeGroups: vnf.availableVersions[0].requestParameters.usePreload
280                             };
281                         } else if (workflowType == "VNF In Place Software Update") {
282                             var payloadObj = {
283                                 'existing_software_version': vm.getInternalWorkFlowParameter(workflowType, 'text', 'Existing software version').value,
284                                 'new_software_version': vm.getInternalWorkFlowParameter(workflowType, 'text', 'New software version').value,
285                                 'operations_timeout': vm.getInternalWorkFlowParameter(workflowType, 'text', 'Operations timeout').value
286                             };
287                             requestParametersData = {
288                                 payload: JSON.stringify(payloadObj)
289                             };
290                         } else if (workflowType == "PNF Software Upgrade") {
291                             requestParametersData = {
292                                 userParams: [
293                                     { "name":"pnfId",
294                                       "value":vnf.properties["vnf-id"]
295                                     },
296                                     { "name":"pnfName",
297                                       "value": vnf.name
298                                     },
299                                     { "name":"targetSoftwareVersion",
300                                       "value":vm.getInternalWorkFlowParameter(workflowType, 'text', 'Target software version').value
301                                     }
302                                 ]
303                             };
304
305                         } else if (workflowType == "VNF Config Update") {
306                             requestParametersData = {
307                                 payload: vm.getInternalWorkFlowParameter("VNF Config Update", "FILE", "Attach configuration file").value
308                             };
309                         } else if (workflowType == "VNF Scale Out") {
310                             if (!moduleToScale) return null;
311
312                             if (moduleToScale.userParams) {
313                                 requestParametersData = {
314                                     userParams: moduleToScale.userParams
315                                     //,usePreload: true
316                                 };
317                             } else {
318                                 requestParametersData = {
319                                     userParams: []
320                                     //,usePreload: false
321                                 };
322                             }
323                         }
324                         $log.info('SchedulerWidgetCtrl:extractChangeManagementCallbackDataStr info:: workflowType ' + workflowType);
325                         $log.info('SchedulerWidgetCtrl:extractChangeManagementCallbackDataStr info:: requestParametersData ' + requestParametersData);
326
327                     } else if (workflowType == "VNF In Place Software Update") {
328                         var payloadObj = {
329                             'existing_software_version': vm.getInternalWorkFlowParameter(workflowType, 'text', 'Existing software version').value,
330                             'new_software_version': vm.getInternalWorkFlowParameter(workflowType, 'text', 'New software version').value,
331                             'operations_timeout': vm.getInternalWorkFlowParameter(workflowType, 'text', 'Operations timeout').value
332                         };
333                         requestParametersData = {
334                             payload: JSON.stringify(payloadObj)
335                         };
336                     }  else if (workflowType == "VNF Config Update") {
337                         requestParametersData = {
338                             payload: vm.getInternalWorkFlowParameter("VNF Config Update", "FILE", "Attach configuration file").value
339                         };
340                     }
341
342                     var data;
343                     if (workflowType == "VNF Scale Out") {
344                         data = {
345                             vnfName: vnf.name,
346                             vnfInstanceId: vnf.id,
347                             modelInfo: {
348                                 modelType: 'vfModule',
349                                 modelInvariantId: moduleToScale.invariantUuid,
350                                 modelName: moduleToScale.modelCustomizationName,
351                                 modelVersion: moduleToScale.version,
352                                 modelCustomizationName: moduleToScale.modelCustomizationName,
353                                 modelCustomizationId: moduleToScale.customizationUuid,
354                                 modelVersionId: moduleToScale.uuid
355                             },
356                             cloudConfiguration: vnf.cloudConfiguration,
357                             requestInfo: requestInfoData,
358                             relatedInstanceList: [],
359                             requestParameters: requestParametersData,
360                             configurationParameters: JSON.parse(vm.getInternalWorkFlowParameter("VNF Scale Out", "text", "Configuration Parameters").value)
361                         };
362                         requestInfoData.instanceName = vnf.name + "_" + (moduleToScale.currentCount + 1);
363                     } else if (workflowType === "PNF Software Upgrade") {
364                          data = nativeWorkflowRequestData('pnf', requestParametersData, vnf, requestInfoData);
365                     } else {
366                          data = nativeWorkflowRequestData('vnf', requestParametersData, vnf, requestInfoData);
367                     }
368
369                     var serviceInstanceId = '';
370                     _.forEach(vnf['service-instance-node'], function (instanceNode) {
371                         if (instanceNode['node-type'] === 'service-instance') {
372                             serviceInstanceId = instanceNode.properties['service-instance-id'];
373                         }
374                     });
375
376                     if (vnf.availableVersions && vnf.availableVersions.length != 0) {
377                         _.forEach(vnf.availableVersions[0].relatedInstanceList, function (related) {
378                             var rel = related.relatedInstance;
379                             var relatedInstance = {
380                                 instanceId: serviceInstanceId,
381                                 modelInfo: {
382                                     modelType: rel.modelInfo.modelType,
383                                     modelInvariantId: rel.modelInfo.modelInvariantId,
384                                     modelVersionId: rel.modelInfo.modelVersionId,
385                                     modelName: rel.modelInfo.modelName,
386                                     modelVersion: rel.modelInfo.modelVersion,
387                                     modelCustomizationName: rel.modelInfo.modelCustomizationName,
388                                     modelCustomizationId: rel.modelInfo.modelCustomizationId
389                                 }
390                             };
391                             if (rel.vnfInstanceId)
392                                 relatedInstance.instanceId = rel.vnfInstanceId;
393
394                             data.relatedInstanceList.push({relatedInstance: relatedInstance});
395                         });
396                         if (workflowType == "VNF Scale Out") {
397                             //push vnf to related as well as the service instance
398                             var relatedInstance = {
399                                 instanceId: vnf.id,
400                                 modelInfo: {
401                                     modelCustomizationId: vnf.availableVersions[0].modelInfo.modelCustomizationId,
402                                     modelCustomizationName: vnf.availableVersions[0].modelInfo.modelCustomizationName,
403                                     modelInvariantId: vnf.availableVersions[0].modelInfo.modelInvariantId,
404                                     modelName: vnf.availableVersions[0].modelInfo.modelName,
405                                     modelType: vnf.availableVersions[0].modelInfo.modelType,
406                                     modelVersion: vnf.availableVersions[0].modelInfo.modelVersion,
407                                     modelVersionId: vnf.availableVersions[0].modelInfo.modelVersionId
408                                 }
409                             };
410                             data.relatedInstanceList.push({relatedInstance: relatedInstance});
411                         }
412                     }
413                 } catch (err) {
414                     $log.error('SchedulerCtrl::extractChangeManagementCallbackDataStr error: ' + err);
415                     vm.errorMsg = err;
416                 }
417
418                 result.requestDetails.push(data);
419             });
420             return JSON.stringify(result);
421         }
422
423         function nativeWorkflowRequestData(modelType, requestParametersData, vnf, requestInfoData) {
424             var data = {
425                    modelInfo: {
426                       modelType: modelType,
427                       modelInvariantId: vnf.properties['model-invariant-id'],
428                       modelVersionId: vnf.modelVersionId,
429                       modelName: vnf.properties['vnf-name'],
430                       modelVersion: vnf.version,
431                       modelCustomizationName: vnf.properties['model-customization-name'],
432                       modelCustomizationId: vnf.properties['model-customization-id']
433                    },
434                    cloudConfiguration: vnf.cloudConfiguration,
435                    requestInfo: requestInfoData,
436                    requestParameters: requestParametersData
437             };
438             data[modelType + 'InstanceId'] = vnf.id;
439             if (modelType == "vnf"){
440                data[modelType + 'Name'] = vnf.name;
441                data['relatedInstanceList'] =  [] ;
442             }
443             return data;
444         }
445
446         function getWorkflowParametersFromForm() {
447             let workflowParameters =
448                 {
449                     requestDetails: {
450                         cloudConfiguration: {},
451                         requestParameters: {userParams: [{}]}
452                     }
453                 };
454             workflowParameters.requestDetails.cloudConfiguration = vm.changeManagement.vnfNames[0].cloudConfiguration;
455
456             let parameters = vm.getRemoteWorkFlowParameters(vm.changeManagement.workflow);
457             parameters.forEach((parameter) => {
458                 let inputField = document.getElementById('so-workflow-parameter-' + parameter.soFieldName);
459                 workflowParameters.requestDetails.requestParameters.userParams[0][parameter.soFieldName] = inputField.value;
460             });
461
462             return workflowParameters;
463         }
464
465         vm.openModal = function () {
466             if (vm.hasScheduler) { //scheduling supported
467                 vm.scheduleWorkflow();
468             } else {
469                 //no scheduling support
470                 vm.executeWorkflow();
471             }
472         };
473
474         vm.collectWorkflowFieldsValues = function () {
475             /**
476              * Transforms items with name and value properties, to associative map, e.g the array
477              * [{name: foo, value: bar}, {name: baz, value: fiz}] will become the object {foo: bar, baz: fiz}
478              */
479             return vm.getAllInternalWorkFlowParameters(
480                     vm.changeManagement.workflow
481             ).reduce(function (result, item) {
482                 result[item.name] = item.value;
483                 return result;
484             }, {});
485         };
486
487         vm.scheduleWorkflow = function () {
488             $scope.widgetParameter = ""; // needed by the scheduler?
489
490             // properties needed by the scheduler so it knows whether to show
491             // policy or sniro related features on the scheduler UI or not.
492             vm.changeManagement.policyYN = "Y";
493             vm.changeManagement.sniroYN = "Y";
494
495             if (featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_ADD_MSO_TESTAPI_FIELD)) {
496                 vm.changeManagement.testApi = DataService.getMsoRequestParametersTestApi();
497             }
498             var data = {
499                 widgetName: 'Portal-Common-Scheduler',
500                 widgetData: Object.assign({}, vm.changeManagement, vm.collectWorkflowFieldsValues()),
501                 widgetParameter: $scope.widgetParameter
502             };
503
504             if (window.parent !== window.self) {
505                 window.parent.postMessage(data, VIDCONFIGURATION.SCHEDULER_PORTAL_URL);
506             } else {
507                 vm.errorMsg = {message: "Portal not found. Cannot send: " + JSON.stringify(data)};
508                 throw vm.errorMsg; // prevent popup closure
509             }
510         };
511
512         vm.executeWorkflow = function () {
513             if (vm.localWorkflows && vm.localWorkflows.length > 0) {
514                 vm.triggerLocalWorkflow();
515             } else {
516                 let source = vm.getRemoteWorkflowSource(vm.changeManagement.workflow);
517                 if (_.toUpper(source) === "NATIVE") {
518                     vm.triggerLocalWorkflow();
519                 } else {
520                     vm.triggerRemoteWorkflow();
521                 }
522             }
523         };
524
525         vm.triggerLocalWorkflow = function () {
526             var dataToSo = extractChangeManagementCallbackDataStr(vm.changeManagement);
527             if (dataToSo) {
528                 var vnfName = vm.changeManagement.vnfNames[0].name;
529                 changeManagementService.postChangeManagementNow(dataToSo, vnfName);
530             }
531         };
532
533         vm.triggerRemoteWorkflow = function () {
534             let cachedWorkflowDetails = vm.getCachedWorkflowDetails(vm.changeManagement.workflow);
535             if (cachedWorkflowDetails.length > 0) {
536                 let workflowParameters = getWorkflowParametersFromForm();
537                 if (workflowParameters) {
538                     let servieInstanceId = vm.changeManagement.vnfNames[0]['service-instance-node'][0].properties['service-instance-id'];
539                     let vnfInstanceId = vm.changeManagement.vnfNames[0].id;
540                     let workflow_UUID = cachedWorkflowDetails[0].id;
541                     changeManagementService.postWorkflowsParametersNow(servieInstanceId, vnfInstanceId, workflow_UUID, workflowParameters);
542                 }
543             }
544         };
545
546         vm.loadSubscribers = function () {
547             vm.subscribers = [];
548             AaiService.getSubscribers(function (response) {
549                 vm.subscribers = response;
550             });
551         };
552
553         vm.loadServiceTypes = function () {
554             vm.serviceTypes = [];
555
556             AaiService.getSubscriberServiceTypes(vm.changeManagement.subscriberId)
557                 .then(function (response) {
558                     vm.serviceTypes = response.data;
559                 })
560                 .catch(function (error) {
561                     $log.error(error);
562                     vm.errorMsg = error;
563                 });
564         };
565
566         function isCompatibleNFRole(vnf) {
567
568             return vnf.properties['nf-role'] === vm.changeManagement['vnfType'] || !vm.changeManagement['vnfType'];
569
570         }
571
572         function isValidVnf(vnf) {
573
574             let result =  isCompatibleNFRole(vnf) && vnf.properties["model-invariant-id"]
575                 && vnf.properties["model-version-id"];
576
577             return result;
578         }
579
580         function loadCloudRegions() {
581             AaiService.getLcpCloudRegionTenantList(
582                 vm.changeManagement.subscriberId,
583                 vm.changeManagement.serviceType["service-type"],
584                 function (response) {
585                     $scope.isFeatureFlagCloudOwner = featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST);
586                     $scope.cloudRegionList = _.uniqBy(response, 'cloudRegionOptionId');
587                 });
588         }
589
590         vm.serviceTypeChanged = function () {
591             if ($scope.isNewFilterChangeManagmentEnabled()) {
592                 loadCloudRegions();
593             } else {
594                 vm.searchVNFs();
595             }
596         };
597
598         vm.searchVNFs = function () {
599             vm.vnfTypes = [];
600             vm.vnfTypesTemp = [];
601             vm.serviceInstances = [];
602             vm.fromVNFVersions = [];
603             vm.vnfNames = [];
604             vm.changeManagement.vnfNames = [];
605
606             vm.vnfs = [];
607             vm.vfModules = [];
608             vm.genericVnfs = [];
609
610             let nfRole = null;
611             let cloudRegion = null;
612
613             if ($scope.isNewFilterChangeManagmentEnabled()) {
614                 nfRole = vm.changeManagement.vnfType ? vm.changeManagement.vnfType : null;
615                 cloudRegion = vm.changeManagement.cloudRegion ? vm.changeManagement.cloudRegion : null;
616             }
617
618             return AaiService.getVnfsByCustomerIdAndServiceType(
619                 vm.changeManagement.subscriberId,
620                 vm.changeManagement.serviceType["service-type"],
621                 nfRole,
622                 cloudRegion,
623             ).then(function (response) {
624                     vm.isSearchedVNF = true;
625                     var vnfsData = response.data.results;
626                     if (vnfsData) {
627                         for (var i = 0; i < vnfsData.length; i++) {
628                             if (vnfsData[i]) {
629                                 const nodeType = vnfsData[i]['node-type'];
630                                 if (nodeType === "generic-vnf") {
631                                     vm.genericVnfs.push(vnfsData[i]);
632                                 } else if (nodeType === "service-instance") {
633                                     vm.serviceInstances.push(vnfsData[i]);
634                                 } else if (nodeType === "vf-module") {
635                                     vm.vfModules.push(vnfsData[i]);
636                                 }
637                             }
638                         }
639
640                         vm.genericVnfs.forEach(function (vnf) {
641                             if (vnf['related-to'].find(function (node) {return node['node-type'] === 'vf-module';}) !== undefined) {
642                                 let vfModuleRel = vnf['related-to'].find(function (node) {
643                                     return node['node-type'] === 'vf-module'
644                                 })
645                                 for (var i = 0; i < vm.vfModules.length; i++) {
646                                     const vfModule = vm.vfModules[i];
647                                     if (vfModule['id'] === vfModuleRel['id']){
648                                         if (vfModule['related-to'].find(function (node) {return node['node-type'] === 'vserver';}) !== undefined) {
649                                             vm.vnfs.push(vnf);
650                                         }
651                                     }
652                                 }
653                             } else if (vnf['related-to'].find(function (node) {return node['node-type'] === 'vserver';}) !== undefined) {
654                                 vm.vnfs.push(vnf);
655                             }
656                         });
657
658                         vm.vnfs = _.flattenDeep(
659                             _.remove(vm.vnfs, function (vnf) {
660                                 var nfRole = vnf.properties['nf-role'];
661                                 if (nfRole !== undefined) {
662                                     return nfRole !== 'null' && nfRole !== '';
663                                 }
664                             })
665                         );
666
667                         var filteredVnfs = _.uniqBy(vm.vnfs, function (vnf) {
668                             return vnf.properties['nf-role'];
669                         });
670
671                         _.forEach(filteredVnfs, function (vnf) {
672                             vm.vnfTypes.push(vnf.properties['nf-role'])
673                         });
674                     }
675                     if ($scope.isNewFilterChangeManagmentEnabled()) {
676                         vm.loadVNFVersions();
677                     }
678                 }
679             );
680         };
681
682         var fromVNFVersions = [];
683
684         vm.loadVNFVersions = function () {
685             fromVNFVersions = [];
686             vm.serviceInstancesToGetVersions = [];
687             var versions = [];
688             _.forEach(vm.vnfs, function (vnf) {
689                 if (isValidVnf(vnf)) {
690                     vm.serviceInstancesToGetVersions.push({
691                             "model-invariant-id": vnf.properties["model-invariant-id"],
692                             "model-version-id": vnf.properties["model-version-id"]
693                         }
694                     );
695
696                     versions.push(vnf.properties["model-invariant-id"]);
697                 }
698             });
699
700             if (versions.length > 0) {
701                 AaiService.getVnfVersionsByInvariantId(versions).then(function (response) {
702                     if (response.data) {
703
704                         $log.debug("getVnfVersionsByInvariantId: response", response);
705
706                         fromVNFVersions = vm.serviceInstancesToGetVersions
707                             .map(function (serviceInstanceToGetVersion) {
708                                 const model = _.find(response.data.model, {'model-invariant-id': serviceInstanceToGetVersion['model-invariant-id']});
709                                 $log.debug("getVnfVersionsByInvariantId: model for " + serviceInstanceToGetVersion['model-invariant-id'], model);
710
711                                 const modelVer = _.find(model["model-vers"]["model-ver"], {'model-version-id': serviceInstanceToGetVersion['model-version-id']});
712                                 $log.debug("getVnfVersionsByInvariantId: modelVer for " + serviceInstanceToGetVersion['model-version-id'], modelVer);
713
714                                 var modelVersionId = serviceInstanceToGetVersion["model-version-id"];
715                                 var modelVersion = modelVer["model-version"];
716
717                                 return {"key": modelVersionId, "value": modelVersion};
718                             });
719
720                         vm.fromVNFVersions = _.uniqBy(fromVNFVersions, 'value');
721                     }
722                 });
723             }
724         };
725
726
727         function getVnfs(modelInvariantId) {
728             return new Promise(function (resolve, reject) {
729                 AaiService.getVnfVersionsByInvariantId(modelInvariantId)
730                     .then(function (response) {
731                         if (response.data.httpCode !== null &&
732                             response.data.httpCode === 200) {
733                             var vnfsData = response.data.t.results;
734                             for (var i = 0; i < vnfsData.length; i++) {
735                                 if (vnfsData[i]) {
736                                     if (vnfsData[i].nodeType === "generic-vnf") {
737                                         resolve(vnfsData[i]);
738                                     } else if (vnfsData[i].nodeType === "service-instance") {
739                                         vm.serviceInstances.push(vnfsData[i]);
740                                     }
741                                 }
742                             }
743                             resolve(null);
744                         }
745                         resolve(null);
746                     })
747                     .catch(function (error) {
748                         reject(error);
749                         vm.errorMsg = error;
750                     });
751             });
752         }
753
754         var getVersionNameForId = function (versionId) {
755             var version = _.find(fromVNFVersions, {"key": versionId});
756             return version.value;
757         };
758
759         vm.loadVNFNames = function () {
760             vm.changeManagement.vnfNames = [];
761             vm.vnfNames = [];
762
763             const vnfs = vm.changeManagement.fromVNFVersion ? vm.vnfs : [];
764             _.forEach(vnfs, function (vnf) {
765
766                 var selectedVersionNumber = getVersionNameForId(vm.changeManagement.fromVNFVersion);
767
768                 if (isCompatibleNFRole(vnf) &&
769                     selectedVersionNumber === getVersionNameForId(vnf.properties["model-version-id"])) {
770                     var vServer = {};
771
772                     _.forEach(vnf['related-to'], function (node) {
773                         if (node['node-type'] === 'vserver') {
774                             vServer = extractLcpRegionIdAndTenantId(node.url);
775                         }
776                     });
777
778                     var serviceInstancesIds =
779                         _.filter(vnf['related-to'], {'node-type': 'service-instance'})
780                             .map(function (serviceInstance) {
781                                 return serviceInstance.id
782                             });
783
784                     var serviceInstances = _.filter(vm.serviceInstances, function (serviceInstance) {
785                         return _.includes(serviceInstancesIds, serviceInstance.id);
786                     });
787
788                     // logging only
789                     if (serviceInstancesIds.length === 0) {
790                         $log.error("loadVNFNames: no serviceInstancesIds for vnf", vnf);
791                     } else {
792                         $log.debug("loadVNFNames: serviceInstancesIds", serviceInstancesIds);
793                         $log.debug("loadVNFNames: serviceInstances", serviceInstances);
794                     }
795
796                     vm.vnfNames.push({
797                         "id": vnf.properties["vnf-id"],
798                         "name": vnf.properties["vnf-name"],
799                         "invariant-id": vnf.properties["model-invariant-id"],
800                         "service-instance-node": serviceInstances,
801                         "modelVersionId": vnf.properties["model-version-id"],
802                         "properties": vnf.properties,
803                         'cloudConfiguration': vServer,
804                         "relatedTo": vnf['related-to']
805                     });
806                 }
807             });
808         };
809
810         function extractLcpRegionIdAndTenantId(url) {
811
812             var cloudConfiguration = {
813                 lcpCloudRegionId: '',
814                 tenantId: ''
815             };
816
817             /*
818              e.g., in both URLs below -
819              Â  - lcpCloudRegionId == 'rdm5b'
820              Â  - tenantId == '0675e0709bd7444a9e13eba8b40edb3c'
821
822              "url": "https://aai-conexus-e2e.ecomp.cci.att.com:8443/aai/v10/cloud-infrastructure/cloud-regions/cloud-region/irma-aic/rdm5b/tenants/tenant/0675e0709bd7444a9e13eba8b40edb3c/vservers/vserver/932b330d-733e-427d-a519-14eebd261f70"
823              "url": "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/irma-aic/rdm5b/tenants/tenant/0675e0709bd7444a9e13eba8b40edb3c/vservers/vserver/932b330d-733e-427d-a519-14eebd261f70"
824              */
825
826             var cloudRegionMatch = url.match(/\/cloud-regions\/cloud-region\/[^\/]+\/([^\/]+)/);
827             var tenantMatch = url.match(/\/tenants\/tenant\/([^\/]+)/);
828
829             cloudConfiguration.lcpCloudRegionId = cloudRegionMatch[1];
830             cloudConfiguration.tenantId = tenantMatch[1];
831
832             return cloudConfiguration;
833         };
834
835         vm.loadWorkFlows = function () {
836             vm.localWorkflowsParameters = new Map();
837             vm.remoteWorkflowsParameters = new Map();
838             if (featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_HANDLE_SO_WORKFLOWS)) {
839                 return vm.loadRemoteWorkFlows()
840                     .then(function () {
841                         vm.workflows = vm.remoteWorkflows.map(item => item.name);
842                     }).then(function () {
843                         vm.loadRemoteWorkFlowsParameters();
844                     });
845             } else {
846                 return vm.loadLocalWorkFlows()
847                     .then(vm.loadLocalWorkFlowsParameters)
848                     .then(function () {
849                         vm.workflows = vm.localWorkflows;
850                     });
851             }
852         };
853
854         vm.loadLocalWorkFlows = function () {
855             return changeManagementService.getWorkflows(vm.changeManagement.vnfNames)
856                 .then(function (response) {
857                     vm.localWorkflows = response.data.workflows || [];
858                 }).catch(function (error) {
859                     $log.error(error);
860                     vm.errorMsg = error;
861                 });
862         };
863
864         vm.loadRemoteWorkFlows = function () {
865             let vnfModelIDs = (vm.changeManagement.vnfNames || []).map(vnfName => vnfName.modelVersionId);
866             if (vnfModelIDs.length === 0) {
867                 vm.remoteWorkflows = [];
868                 return $q.resolve();
869             }
870             return changeManagementService.getSOWorkflows(vnfModelIDs)
871                 .then(function (response) {
872                     vm.remoteWorkflows = response.data || [];
873                 }).catch(function (error) {
874                     $log.error(error);
875                     vm.errorMsg = error;
876                 });
877         };
878
879         vm.loadLocalWorkFlowsParameters = function () {
880             vm.localWorkflows.forEach(function (workflow) {
881                 vm.loadLocalWorkFlowParameters(workflow);
882             });
883         };
884
885         vm.loadLocalWorkFlowParameters = function (workflow) {
886             changeManagementService.getLocalWorkflowParameter(workflow)
887                 .then(function (response) {
888                     vm.localWorkflowsParameters.set(workflow, response.data.parameterDefinitions);
889                 })
890                 .catch(function (error) {
891                     $log.error(error);
892                     vm.errorMsg = error;
893                 });
894         };
895
896         vm.loadRemoteWorkFlowsParameters = function () {
897             vm.remoteWorkflows.forEach(function (workflow) {
898                 if (workflow.source === 'SDC' || workflow.source === 'sdc') {
899                     vm.loadRemoteWorkFlowParameters(workflow);
900                 } else {
901                     vm.loadLocalWorkFlowParameters(workflow.name);
902                 }
903             });
904         };
905
906         vm.loadRemoteWorkFlowParameters = function (workflow) {
907             let parameters = [];
908             workflow.workflowInputParameters
909                 .filter(function (param) {
910                     return param.soPayloadLocation === "userParams"
911                 })
912                 .forEach(function (param) {
913                         let workflowParams = vm.repackAttributes(param);
914                         if (param.validation.length > 0) {
915                             let validation = param.validation[0];
916                             if ('maxLength' in validation) {
917                                 workflowParams.maxLength = validation.maxLength;
918                             }
919                             if ('allowableChars' in validation) {
920                                 workflowParams.pattern = validation.allowableChars;
921                             }
922                         }
923                         workflowParams.type = param.inputType;
924
925                         parameters.push(workflowParams);
926                     }
927                 );
928             vm.remoteWorkflowsParameters.set(workflow.name, parameters);
929         };
930
931         vm.repackAttributes = function (workflowParam) {
932             return {
933                 name: workflowParam.label,
934                 required: workflowParam.required,
935                 id: workflowParam.soFieldName,
936                 soFieldName: workflowParam.soFieldName,
937                 maxLength: '500',
938                 pattern: '.*'
939             }
940         };
941
942         vm.getRemoteWorkFlowParameters = function (workflow) {
943             if (workflow && vm.remoteWorkflowsParameters.has(workflow)) {
944                 return vm.remoteWorkflowsParameters.get(workflow)
945             }
946             return [];
947         };
948
949         vm.hasPatternError = function (form, itemName) {
950             return form[itemName].$error.pattern;
951         };
952
953         vm.hasAsyncFnError = function (form, itemName) {
954             return form[itemName].$error.validateAsyncFn;
955         };
956
957         vm.getIdFor = function (type, item) {
958             return "internal-workflow-parameter-" + type + "-" + item.id + "-" + (item.displayName ? item.displayName.split(' ').join('-').toLowerCase() : "");
959         };
960
961         vm.getAllInternalWorkFlowParameters = function (workflow) {
962             if (workflow && vm.localWorkflowsParameters.has(workflow) && vm.localWorkflowsParameters.get(workflow)) {
963                 return vm.localWorkflowsParameters.get(workflow);
964             }
965             return [];
966         };
967
968         vm.getInternalWorkFlowParameters = function (workflow, type) {
969             return vm.getAllInternalWorkFlowParameters(workflow).filter(parameter => parameter.type === type);
970         };
971
972         vm.getInternalWorkFlowParameter = function (workflow, type, parameterName) {
973             return vm.getInternalWorkFlowParameters(workflow, type).filter(parameter => parameter.displayName === parameterName)[0];
974         };
975
976         vm.getRemoteWorkflowSource = (workflow) => {
977             return vm.getCachedWorkflowDetails(workflow)[0].source;
978         };
979
980         vm.getCachedWorkflowDetails = function (workflow) {
981             return vm.remoteWorkflows.filter(function (remoteWorkflow) {
982                 return remoteWorkflow.name === workflow;
983             });
984
985         };
986
987         //Must be $scope because we bind to the onchange of the html (cannot attached to vm variable).
988         $scope.selectFileForVNFName = function (fileInput) {
989             if (fileInput && fileInput.id) {
990                 var vnfName = _.filter(vm.changeManagement.vnfNames, {"invariant-id": fileInput.id});
991                 var file = fileInput.files[0];
992                 var fileReader = new FileReader();
993                 fileReader.onload = function (load) {
994                     try {
995                         var lines = load.target.result;
996                         vnfName[0].selectedFile = JSON.parse(lines);
997                     } catch (error) {
998                         $log.error(error);
999                         vm.errorMsg = error;
1000                     }
1001                 };
1002                 fileReader.readAsText(file);
1003             }
1004         };
1005
1006         vm.selectVersionForVNFName = function (vnfName) {
1007             console.log("Will add version for selected vnf name: " + vnfName.name);
1008         };
1009
1010         vm.isConfigUpdate = function () {
1011             return vm.changeManagement.workflow === COMPONENT.WORKFLOWS.vnfConfigUpdate;
1012         };
1013
1014         vm.isScaleOut = function () {
1015             return vm.changeManagement.workflow === COMPONENT.WORKFLOWS.vnfScaleOut;
1016         };
1017
1018         vm.shouldShowVnfInPlaceFields = function () {
1019             return vm.changeManagement.workflow === COMPONENT.WORKFLOWS.vnfInPlace;
1020         };
1021
1022         vm.setPreload = function (fileEl) {
1023             var files = fileEl.files;
1024             var file = files[0];
1025             var reader = new FileReader();
1026
1027             reader.onloadend = function (evt) {
1028                 if (evt.target.readyState === FileReader.DONE) {
1029                     $scope.$apply(function () {
1030                         $scope.moduleArr[0].userParams = JSON.parse(evt.target.result);
1031                     });
1032                 }
1033             };
1034
1035             reader.readAsText(file);
1036         };
1037
1038         init();
1039     }
1040 })();