14af6ab47e7ab0179ddcd9f43eefdcc64d2ee6fd
[appc/cdt.git] / src / app / vnfs / build-artifacts / parameter-definitions / parameter-definition.service.ts
1 /*
2 ============LICENSE_START==========================================
3 ===================================================================
4 Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
5
6 Copyright (C) 2018 IBM.
7 ===================================================================
8
9 Unless otherwise specified, all software contained herein is licensed
10 under the Apache License, Version 2.0 (the License);
11 you may not use this software except in compliance with the License.
12 You may obtain a copy of the License at
13
14     http://www.apache.org/licenses/LICENSE-2.0
15
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
21 ============LICENSE_END============================================
22 */
23
24
25 import {Injectable, ViewChild} from '@angular/core';
26 import {saveAs} from 'file-saver';
27 import {ParamShareService} from '../../../shared/services/paramShare.service';
28 import {MappingEditorService} from '../../../shared/services/mapping-editor.service';
29 import {ModalComponent} from '../../../shared/modal/modal.component';
30 import {UtilityService} from '../../../shared/services/utilityService/utility.service';
31 import {NotificationsService} from 'angular2-notifications';
32 import 'rxjs/add/operator/map';
33 import { appConstants } from '../../../../constants/app-constants';
34
35 let YAML = require('yamljs');
36
37 declare var $: any;
38
39 @Injectable()
40 export class ParameterDefinitionService {
41
42     public vnfcTypeData: string = '';
43     public selectedUploadType: string;
44     @ViewChild(ModalComponent) modalComponent: ModalComponent;
45     public title: string;
46     public parameterDefinitionMap: { [index: string]: string; } = {};
47     public parameterNameValues = {};
48     public displayParamObjects;
49     public modelParamDefinitionObjects;
50     public vnfType: any;
51     vnfcType: any;
52     protocol: any;
53     public refNameObj = {};
54     public action;
55     public artifactName;
56     public type;
57     public appDataObject: any;
58     public downloadDataObject: any;
59     public artifact_fileName;
60     identifier: any;
61     public myKeyFileName = null;
62     public myPdFileName = null;
63     private selectedActionReference: any;
64     private apiToken = localStorage['apiToken'];
65     private userId = localStorage['userId'];
66     constructor(private mappingEditorService: MappingEditorService,
67                 private paramShareService: ParamShareService,
68                 private nService: NotificationsService,
69                 private utilService: UtilityService) {
70     }
71
72     public initialize() {
73
74     }
75
76     public setValues(vnfType, vnfcType, protocol, action, artifactName) {
77         this.vnfType = vnfType;
78         this.vnfcType = vnfcType;
79         this.protocol = protocol;
80         this.action = action;
81         this.artifact_fileName = artifactName;
82     }
83
84     public afterInit(artifactName, displayParamObjects) {
85
86     }
87
88     //========================== End of saveChanges() Method============================================
89     /* Saves pd to appc */
90     public sendPD(yamlString: String) {
91         let result: any;
92         let payload = '{"userID": "' + this.userId + '","vnf-type" : "' + this.vnfType + '","action" : "' + this.action + '","artifact-name" : "' + this.artifact_fileName + '","artifact-type" : "APPC-CONFIG","artifact-version" : "0.0.1","artifact-contents" : ' + yamlString + '}';
93         let input = {
94             'input': {
95                 'design-request': {
96                     'request-id': this.apiToken,
97                     'action': 'uploadArtifact',
98                     'payload': payload
99                 }
100             }
101         };
102         this.appDataObject.pd = input;
103     }
104
105
106     //========================== End of filetrByFieldChanged() Method============================================
107     removeUnwantedvalues(obj) {
108         let result = Object.assign({}, obj);
109         result['vnf-parameter-list'].forEach(obj => {
110             delete obj['ruleTypeValues'];
111             delete obj['showFilterFields'];
112             delete obj['enableFilterByValue'];
113         });
114         return result;
115     }
116
117     //========================== End of removeUnwantedvalues() Method============================================
118     populateDataUponSource(displayParamObjects) {
119         displayParamObjects.forEach(parameter => {
120             if (parameter.source == 'A&AI') {
121                 parameter.ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list'];
122                 if (parameter['rule-type'] == 'vm-name-list' || parameter['rule-type'] == 'vnfc-name-list' || parameter['rule-type'] == 'vnfc-oam-ipv4-address-list') {
123                     parameter.showFilterFields = true;
124                     parameter.enableFilterByValue = false;
125                 } else {
126                     parameter.showFilterFields = false;
127                 }
128
129             } else if (parameter.source == 'Manual') {
130                 parameter.ruleTypeValues = [null];
131             }
132             else {
133                 parameter.ruleTypeValues = [parameter['rule-type']];
134             }
135         });
136
137     }
138
139     //========================== End of getPD() Method============================================
140     populatePD(result: any) {
141         let fileContent = JSON.stringify(result);
142         //Added code to deserialize, serialize and format the response keys for display purposes ??May be unneessary?? To Do: - Check 
143         let fileObj = JSON.parse(fileContent);
144         this.displayParamObjects = this.formatFileContentForDisplay(fileObj);
145         this.populateDataUponSource(this.displayParamObjects);
146         this.formatResponseForKey(this.displayParamObjects);
147         if (undefined !== this.displayParamObjects)
148             this.modelParamDefinitionObjects = this.displayParamObjects;
149         if (this.displayParamObjects !== undefined && this.displayParamObjects.length > 0) {
150             this.paramShareService.setSessionParamData(this.displayParamObjects);
151         }
152         return this.displayParamObjects;
153     }
154
155     //========================== End of populatePD() Method============================================
156     /* Formats each object read from YAML file as per page expectations */
157     formatResponseForKey(param: any[]) {
158         for (var i = 0; i < param.length; i++) {
159             this.formatKeys(param[i]);
160         }
161     }
162
163     //========================== End of formatResponseForKey() Method============================================
164     /* Formats for responsekeys of each object */
165     formatKeys(parameterDefinitionObject: any) {
166         if (null == parameterDefinitionObject || undefined === parameterDefinitionObject)
167             return;
168         if (null == parameterDefinitionObject['response-keys'])
169             parameterDefinitionObject['response-keys'] = [{}];
170         for (var j = 0; j < 5; j++) {
171             var keysObj = {
172                 'key-name': null,
173                 'key-value': null
174             };
175             if (undefined == parameterDefinitionObject['response-keys'][j] || null == parameterDefinitionObject['response-keys'][j]) {
176                 parameterDefinitionObject['response-keys'].push(keysObj);
177             }
178             if (undefined == parameterDefinitionObject['response-keys'][j]['key-name']) {
179                 parameterDefinitionObject['response-keys'][j]['key-name'] = null;
180             }
181             if (undefined == parameterDefinitionObject['response-keys'][j]['key-value']) {
182                 parameterDefinitionObject['response-keys'][j]['key-value'] = null;
183             }
184         }
185         if (null == parameterDefinitionObject['request-keys'])
186             parameterDefinitionObject['request-keys'] = [{}];
187         for (var k = 0; k < 3; k++) {
188             var keysObj = {
189                 'key-name': null,
190                 'key-value': null
191             };
192             if (undefined == parameterDefinitionObject['request-keys'][k] || null == parameterDefinitionObject['request-keys'][k]) {
193                 parameterDefinitionObject['request-keys'].push(keysObj);
194             }
195             if (undefined == parameterDefinitionObject['request-keys'][k]['key-name']) {
196                 parameterDefinitionObject['request-keys'][k]['key-name'] = null;
197             }
198             if (undefined == parameterDefinitionObject['request-keys'][k]['key-value']) {
199                 parameterDefinitionObject['request-keys'][k]['key-value'] = null;
200             }
201         }
202     }
203
204     //========================== End of formatKeys() Method============================================
205     //Send null if there are no keys present - Check with key names being absent
206     formatKeysForFileGeneration() {
207         for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
208             if (this.modelParamDefinitionObjects[i]['response-keys'][0]['key-name'] == null && this.modelParamDefinitionObjects[i]['response-keys'][1]['key-name'] == null && this.modelParamDefinitionObjects[i]['response-keys'][2]['key-name'] == null)
209                 this.modelParamDefinitionObjects[i]['response-keys'] = null;
210             if (this.modelParamDefinitionObjects[i]['request-keys'][0]['key-name'] == null && this.modelParamDefinitionObjects[i]['request-keys'][1]['key-name'] == null && this.modelParamDefinitionObjects[i]['request-keys'][2]['key-name'] == null)
211                 this.modelParamDefinitionObjects[i]['request-keys'] = null;
212         }
213     }
214
215     //========================== End of formatKeysForFileGeneration() Method============================================
216     /* Fn to restore response keys in desired format per backend consumption*/
217     processResponseKeys(saveModel: any[]) {
218         for (var i = 0; i < saveModel.length; i++) {
219             if (saveModel[i]['response-keys'] != null) {
220                 saveModel[i]['response-keys-new'] = [{}];
221                 saveModel[i]['response-keys-new'][0] = {};//An array of objects ?? so accessing first element
222                 if (undefined != saveModel[i]['response-keys'][0]['key-name'] && undefined != saveModel[i]['response-keys'][0]['key-value']) {
223                     let keyName1 = saveModel[i]['response-keys'][0]['key-name'];
224                     saveModel[i]['response-keys-new'][0][keyName1] = saveModel[i]['response-keys'][0]['key-value'];
225                 }
226                 if (undefined != saveModel[i]['response-keys'][1]['key-name'] && undefined != saveModel[i]['response-keys'][1]['key-value']) {
227                     let keyName2 = saveModel[i]['response-keys'][1]['key-name'];
228                     saveModel[i]['response-keys-new'][0][keyName2] = saveModel[i]['response-keys'][1]['key-value'];
229                 }
230                 if (undefined != saveModel[i]['response-keys'][2]['key-name'] && undefined != saveModel[i]['response-keys'][2]['key-value']) {
231                     let keyName3 = saveModel[i]['response-keys'][2]['key-name'];
232                     saveModel[i]['response-keys-new'][0][keyName3] = saveModel[i]['response-keys'][2]['key-value'];
233                 }
234                 if (saveModel[i]['response-keys'][3]['key-value'] != undefined && saveModel[i]['response-keys'][3]['key-value'] != null) {
235                     let keyName4 = saveModel[i]['response-keys'][3]['key-name'];
236                     saveModel[i]['response-keys-new'][0]['filter-by-key'] = saveModel[i]['response-keys'][3]['key-value'];
237                 }
238                 if (saveModel[i]['response-keys'][4]['key-value'] != undefined && saveModel[i]['response-keys'][4]['key-value'] != null) {
239                     let keyName4 = saveModel[i]['response-keys'][4]['key-name'];
240                     saveModel[i]['response-keys-new'][0]['filter-by-value'] = saveModel[i]['response-keys'][4]['key-value'];
241                 }
242             }
243             else {
244                 saveModel[i]['response-keys-new'] = null;
245             }
246             delete saveModel[i]['response-keys'];
247             saveModel[i]['response-keys'] = saveModel[i]['response-keys-new'];
248             delete saveModel[i]['response-keys-new'];
249         }
250         return saveModel;
251     }
252
253     //========================== End of processResponseKeys() Method============================================
254     /*Fn to format response keys for front end display */
255     formatFileContentForDisplay(fileModel: any[]) {
256         for (var i = 0; i < fileModel.length; i++) {
257             if (undefined != fileModel[i]['response-keys']) {
258                 let testObj = fileModel[i]['response-keys'];
259                 let keyNum = 0;
260                 fileModel[i]['response-keys-new'] = [{}];
261                 for (var prop in testObj[0]) {
262                     if (testObj[0].hasOwnProperty(prop)) {
263                         let key = prop;
264                         fileModel[i]['response-keys-new'][keyNum] = {};
265                         fileModel[i]['response-keys-new'][keyNum]['key-name'] = key;
266                         fileModel[i]['response-keys-new'][keyNum]['key-value'] = testObj[0][key];
267                     }
268                     keyNum++;
269                 }
270                 delete fileModel[i]['response-keys'];
271                 fileModel[i]['response-keys'] = fileModel[i]['response-keys-new'];
272                 delete fileModel[i]['response-keys=new'];
273             }
274         }
275         return fileModel;
276     }
277
278     //========================== End of openModal() Method============================================
279     getCorrectParameterDefinitionObject(paramName: string) {
280         var result = {
281             'obj': {},
282             'present': false
283         };
284         for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
285             var paramObj = this.modelParamDefinitionObjects[i];
286             if (paramObj.name === paramName) {
287                 result.obj = this.modelParamDefinitionObjects[i];
288                 result.present = true;
289                 return result;
290             }
291         }
292         var parameterDefinitionObject = {
293             'name': paramName,
294             'type': null,
295             'description': null,
296             'required': null,
297             'default': null,
298             'source': null,
299             'rule-type': null,
300             'response-keys': [{}],
301             'request-keys': [{}]
302         };
303         result.obj = parameterDefinitionObject;
304         result.present = false;
305         return result;
306     }
307
308    
309     public prepareFileName(): any {
310         let fileNameObject: any = this.mappingEditorService.latestAction;
311         this.appDataObject = this.mappingEditorService.appDataObject;
312         this.downloadDataObject = this.mappingEditorService.downloadDataObject;
313         return fileNameObject;
314     }
315
316     public destroy(displayParamObjects) {
317         this.displayParamObjects = displayParamObjects;
318         if (this.mappingEditorService.referenceNameObjects) {
319             this.saveChanges('send');
320             this.saveChanges('download');
321             this.mappingEditorService.changeNavAppData(this.appDataObject);
322             this.mappingEditorService.changeNavDownloadData(this.downloadDataObject);
323         }
324     }
325
326     //========================== End of fileChangeEvent() Method============================================
327     /* Saves pd file in YAML format */
328     public saveChanges(downLoadOrSend: String) {
329         if (undefined != this.displayParamObjects && null != this.displayParamObjects && this.displayParamObjects.length > 0) {
330             this.paramShareService.setSessionParamData(this.displayParamObjects);
331
332             //Generate File Name per given rules - if not, return without saving
333             this.modelParamDefinitionObjects = this.displayParamObjects.slice(0);
334             this.paramShareService.setDisplayData(this.displayParamObjects);
335             this.formatKeysForFileGeneration();
336             //Added code to serialize, deserialize and then make changes needed to save response keys as needed in pd file
337             let jsonString = JSON.stringify(this.modelParamDefinitionObjects, null, '\t');
338             jsonString = jsonString.replace(/"null"/g, 'null');
339             let saveModel = JSON.parse(jsonString);
340             let pdFileObject = this.processResponseKeys(saveModel);
341                 let yamlObject = {
342                     'kind': 'Property Definition',
343                     'version': 'V1',
344                     'vnf-parameter-list': []
345                 };
346                 yamlObject['vnf-parameter-list'] = pdFileObject;
347                 yamlObject = this.removeUnwantedvalues(yamlObject);
348                 let yamlStringTemp = YAML.stringify(yamlObject, 6, 1);
349                 var re = /\'/gi;
350                 var newYamlStringTemp = yamlStringTemp.replace(re, '"');
351                 var re2 = / -\n  +/gi;
352                 var newYamlStringTemp2 = newYamlStringTemp.replace(re2, '- ');
353                 let yamlString = '---\n' + newYamlStringTemp2;
354                 if (downLoadOrSend === 'download') {
355                     var blob = new Blob([yamlString], {
356                         type: 'text/plain'
357                     });
358                     //let fileName = "pd_" + this.action + "_" + this.type + "_0.0.1V.yaml"
359                     this.downloadDataObject.pd.pdData = yamlString;
360                     this.downloadDataObject.pd.pdFileName = this.artifact_fileName;
361                 }
362                 else {
363                     this.sendPD(JSON.stringify(yamlString));
364                 }
365             
366             //Restore Keys for display
367             for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
368                 this.formatKeys(this.modelParamDefinitionObjects[i]);
369             }
370         }
371
372     }
373
374
375     //This method will create parameter definitions as an array of objects from template name-value pairs and associative array for value from external key file if present
376     createOrUpdateParameterDefinitionData(usecase) {
377         this.parameterNameValues = JSON.parse(localStorage['paramsContent']);
378         this.parameterDefinitionMap = this.paramShareService.getData();
379         //Return if there are no name-value pairs or send some alert notification
380         if (undefined != this.modelParamDefinitionObjects && this.modelParamDefinitionObjects.length > 0 && usecase == 'create') {
381             //Do not recreate if object is already created
382             return;
383         }
384         else {
385         }
386         this.parameterDefinitionMap = this.paramShareService.getData();
387         //To Do:: Add Check for empty parameterDefinitionmap
388         var nameValueObj = {}, pName, pValue;
389         for (var key in this.parameterNameValues) {
390             if (this.parameterNameValues.hasOwnProperty(key)) {
391                 pName = key;
392                 pValue = this.parameterNameValues[key];
393             }
394
395             if (this.parameterDefinitionMap !== undefined)
396             //Check if parameter exists - if so, just update the keys, else create new object
397                 var result = this.getCorrectParameterDefinitionObject(pName);
398             var parameterDefinitionObject = result.obj;
399             if (parameterDefinitionObject['source'] != 'A&AI' && (undefined !== this.parameterDefinitionMap) && (undefined !== this.parameterDefinitionMap[pValue.toUpperCase()])) {
400                 var fields = this.parameterDefinitionMap[pValue.toUpperCase()].split('|');
401                 //Starts with 2, first vallue is source, second is rule-type
402                 let respInd = 0;
403                 for (var i = 2; i < fields.length; i += 2) {
404                     parameterDefinitionObject['response-keys'][respInd] = {};
405                     parameterDefinitionObject['response-keys'][respInd]['key-name'] = fields[i];
406                     if ((i + 1) < fields.length) {
407                         parameterDefinitionObject['response-keys'][respInd]['key-value'] = fields[i + 1];
408                     }
409                     respInd++;
410                 }
411                 parameterDefinitionObject['source'] = fields[0];
412                 parameterDefinitionObject['rule-type'] = fields[1];
413             } 
414             this.formatKeys(parameterDefinitionObject); //Ensure there are 3 elements for response-keys, request-keys for display purposes
415             if (!result.present) { //only push if not present
416                 this.modelParamDefinitionObjects.push(parameterDefinitionObject);
417             }
418         }
419         for (var indx in this.modelParamDefinitionObjects) {
420             if (this.modelParamDefinitionObjects[indx] != undefined && (this.modelParamDefinitionObjects[indx].source == undefined || this.modelParamDefinitionObjects[indx].source == null || this.modelParamDefinitionObjects[indx].source == '')) {
421                 this.modelParamDefinitionObjects[indx].source = 'Manual';
422             }
423         }
424         this.displayParamObjects = this.modelParamDefinitionObjects.slice(0);
425         this.paramShareService.setDisplayData(this.displayParamObjects);
426     }
427
428     public processKeyFile(fileName, result) {
429         this.myKeyFileName = fileName;
430         if (!this.myKeyFileName.endsWith('.txt')) {
431             this.nService.error(appConstants.notifications.titles.error, appConstants.errors.notTxtFileError);
432         }
433         this.parameterDefinitionMap = {};
434         var rows = result.split(/\r\n|\r|\n/g);
435         for (var i = 1; i < rows.length; i++) { //Omit headings, so start from 1
436             let ind = rows[i].indexOf('|');
437             let key = rows[i].slice(0, ind);
438             let value = rows[i].slice(ind + 1);
439             this.parameterDefinitionMap[key.toUpperCase()] = value;
440         }
441         this.paramShareService.setData(this.parameterDefinitionMap);
442         //this.notificationService.notifySuccessMessage('External Key file successfully uploaded..');
443         let sessionVar = [{}];
444         sessionVar = this.paramShareService.getSessionParamData();
445         if (sessionVar !== undefined && sessionVar != null && sessionVar.length > 0) {
446             if (undefined == this.displayParamObjects)
447                 this.displayParamObjects = this.modelParamDefinitionObjects = [];
448             this.displayParamObjects = sessionVar;
449             this.modelParamDefinitionObjects = this.displayParamObjects;
450             if (localStorage['paramsContent'] && (undefined !== this.displayParamObjects) && (this.displayParamObjects.length > 0)) {
451                 this.createOrUpdateParameterDefinitionData('update');
452                 //update the session variable with the updated data
453                 this.paramShareService.setSessionParamData(this.displayParamObjects);
454             }
455         } else {
456             this.displayParamObjects = this.modelParamDefinitionObjects = [];
457         }
458         this.populateDataUponSource(this.displayParamObjects);
459         return this.displayParamObjects;
460     }
461
462     public processPDfile(fileName, result) {
463         this.myPdFileName = fileName;
464         if (!this.myPdFileName.endsWith('.yaml')) {
465             this.nService.error(appConstants.notifications.titles.error, appConstants.errors.notYAMLFileError);
466         }
467         var pdObject = YAML.parse(result);
468         let fileModel = pdObject['vnf-parameter-list'];
469         this.populatePD(fileModel);
470         return this.displayParamObjects;
471     }
472 }