2 ============LICENSE_START==========================================
3 ===================================================================
4 Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
5 ===================================================================
7 Unless otherwise specified, all software contained herein is licensed
8 under the Apache License, Version 2.0 (the License);
9 you may not use this software except in compliance with the License.
10 You may obtain a copy of the License at
12 http://www.apache.org/licenses/LICENSE-2.0
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.
20 ============LICENSE_END============================================
23 import { Component, Input, OnInit, ViewChild } from '@angular/core';
24 import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service';
25 import { MappingEditorService } from '../../../../shared/services/mapping-editor.service';
26 import { ArtifactRequest } from '../../../../shared/models/index';
27 import { ActivatedRoute, Router } from '@angular/router';
28 import { saveAs } from 'file-saver';
29 import { NotificationService } from '../../../../shared/services/notification.service';
30 import { NotificationsService } from 'angular2-notifications';
31 import { ParamShareService } from '../../../../shared/services/paramShare.service';
32 import { DialogService } from 'ng2-bootstrap-modal';
33 import { ConfirmComponent } from '../../../../shared/confirmModal/confirm.component';
34 import { BuildDesignComponent } from '../../build-artifacts.component';
35 import { environment } from '../../../../../environments/environment';
36 import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
37 import { NgProgress } from 'ngx-progressbar';
40 @Component({ selector: 'app-golden-configuration', templateUrl: './template-configuration.component.html', styleUrls: ['./template-configuration.component.css'] })
41 export class GoldenConfigurationComponent implements OnInit {
42 @ViewChild('templateeditor') templateeditor;
43 @Input() configMappingEditorContent: string;
44 @Input() isMappingComp: boolean;
45 @ViewChild('myInput') myInputVariable: any;
46 @ViewChild('myModal') modal: ModalComponent;
49 showTemplateVersionDiv: any;
50 downloadedTemplateFileName: any;
51 downloadedParamFileName: any;
52 templateVersionNo: any = '0.0.1';
53 saveToGuiCacheFlag = 'false';
55 public referenceData: Array<Object> = [];
56 public scopeName: any;
57 public subscription: any;
58 public item: any = {};
59 public goldenActions: Array<string> = [];
60 public refNameObj = {};
62 public artifactName = '';
64 public showError: boolean = false;
65 public tempretrieveFlag: boolean = false;
66 public fileNameForTempSave;
68 showDownloadDiv: boolean = false;
70 enableBrowse: boolean = true;
71 enableMerge: boolean = false;
72 uploadValidationSuccess: boolean = false;
73 fileExtension: any = "xml";
74 apiToken = localStorage['apiToken'];
75 public appDataObject: any;
76 public downloadDataObject: any;
77 public checkNameEntered: boolean = true;
78 public selectedWord: any = this.mappingEditorService.getSelectedWord();
80 { action: "ConfigBackup", value: "ConfigBackup" },
81 { action: "ConfigModify", value: "ConfigModify" },
82 { action: "ConfigRestore", value: "ConfigRestore" },
83 { action: "Configure", value: "Configure" },
84 { action: "GetRunningConfig", value: "GetRunningConfig" },
85 { action: "HealthCheck", value: "HealthCheck" },
86 { action: "StartApplication", value: "StartApplication" },
87 { action: "StopApplication", value: "StopApplication" }
91 showProgressBar: true,
97 public enableDownloadButtons: boolean = false;
98 constructor(private buildDesignComponent: BuildDesignComponent, private paramShareService: ParamShareService, private dialogService: DialogService, private notificationService: NotificationService, private httpUtil: HttpUtilService, private mappingEditorService: MappingEditorService, private activeRoutes: ActivatedRoute, private router: Router, private nService: NotificationsService, private ngProgress: NgProgress) {
99 this.artifactRequest.action = '';
100 this.artifactRequest.version = '';
101 this.artifactRequest.paramsContent = '{}';
102 this.artifactRequest.paramKeysContent = '';
104 public templateEditor: any;
105 public fileType: any = '';
106 public actionType: any;
107 public myfileName: any;
108 userId = localStorage['userId'];
109 public artifactRequest: ArtifactRequest = new ArtifactRequest();
110 public showUploadStatus: boolean = false;
111 public uploadStatus: boolean = false;
112 public uploadTypes = [
114 value: 'Generated Template',
115 display: 'Sample Json Param File'
118 value: 'Mapping Data',
119 display: 'Sample Json Param File'
129 enableValidateTemplate: boolean = false;;
130 public selectedUploadType: string = this.uploadTypes[0].value;
132 public tempRetrievalResponse: any;
133 public mergeStatus: boolean = false;
135 //======================================Start of ngOnInit() Method============================================
137 var refObj = this.refObj = this.prepareFileName();
138 if (refObj && refObj != undefined) {
141 this.vnfType = this.item.scope["vnf-type"];
142 this.vnfcType = this.item.scope["vnfc-type"];
143 this.protocol = this.item['device-protocol'];
144 this.action = this.item.action;
145 this.artifactRequest.action = this.item.action;
146 this.artifactRequest.vnfType = this.vnfType;
147 if (this.vnfcType != undefined && this.vnfcType.length != 0) {
148 this.scopeName = this.vnfcType;
151 this.scopeName = this.vnfType;
155 this.item = { "action": "", "scope": { "vnf-type": "", "vnfc-type": "" }, "vm": [], "protocol": "", "download-dg-reference": "", "user-name": "", "port-number": "", "artifact-list": [], "deviceTemplate": "", "scopeType": "" };
157 this.initialAction = this.item.action;
158 this.activeRoutes.url.subscribe(UrlSegment => {
159 this.actionType = UrlSegment[0].path
161 this.mappingEditorService.fromScreen = 'MappingScreen';
162 this.identifier = this.mappingEditorService.identifier;
164 //========================== End of ngOnInit() Method============================================
166 if (this.refObj && this.refObj != undefined) {
167 if (this.configMappingEditorContent && this.configMappingEditorContent != undefined) {
169 this.prepareAppData();
170 this.prepareDownloadData();
171 this.mappingEditorService.changeNavAppData(this.appDataObject);
172 this.mappingEditorService.changeNavDownloadData(this.downloadDataObject);
176 //========================== End of ngOnDestroy() Method============================================
178 if (this.mappingEditorService.latestAction) {
179 this.refNameObj = this.mappingEditorService.latestAction;
180 if (this.vnfcType !== 'null') {
181 this.type = this.vnfcType;
184 this.type = this.vnfType;
186 for (let i = 0; i < this.refNameObj['artifact-list'].length; i++) {
187 let artifactList = this.refNameObj['artifact-list'];
188 if (artifactList[i]['artifact-type'] === 'config_template') {
189 var artifactName = artifactList[i]['artifact-name'];
190 var artifactNameWithoutExtension = '';
192 artifactNameWithoutExtension = artifactName.substring(0, artifactName.lastIndexOf("."));
194 if(this.mappingEditorService.identifier) {
195 if(artifactNameWithoutExtension.endsWith(this.mappingEditorService.identifier)) {
196 this.artifactName = artifactName;
200 this.artifactName = artifactName;
207 this.templateEditor = self.templateeditor.getEditor();
208 this.templateeditor.getEditor().commands.addCommand({
209 name: 'annotateCommandAlternate',
210 bindKey: { win: 'CTRL-4', mac: 'Command-4' },
211 exec: (editor: any) => {
212 this.handleAnnotation(this.modal);
215 if (this.mappingEditorService.fromScreen === 'MappingScreen') {
216 this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore();
217 this.fileType = sessionStorage.getItem('fileType');
219 if (this.configMappingEditorContent) {
220 this.artifactRequest.templateContent = this.configMappingEditorContent;
221 this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal);
224 if (this.mappingEditorService.getTemplateMappingDataFromStore() && this.mappingEditorService.getTemplateMappingDataFromStore() != undefined) {
225 this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore();
228 if (this.artifactName) this.retrieveTemplateFromAppc();
233 this.enableBrowse = false;
234 this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen");
238 //========================== End of ngAfterViewInit() Method============================================
240 $("#inputFile").trigger('click');
242 //========================== End of browseOption() Method============================================
244 public saveTemplate() {
245 this.saveToGuiCacheFlag = 'true';
246 this.mappingEditorService.paramData = [];
247 if (this.configMappingEditorContent) {
248 this.initialData = this.configMappingEditorContent;
249 this.mappingEditorService.refreshEditor();
250 let paramArr: any = []
251 if (this.mappingEditorService.paramData && this.mappingEditorService.paramData != undefined) {
252 if (this.mappingEditorService.paramData.length === 0 && this.mappingEditorService.hasErrorCode === true) {
253 this.nService.error("Error", 'Special characters error', 'Error')
257 this.showError = false;
260 this.showTemplateVersionDiv = true;
262 if (this.mappingEditorService.fromScreen === 'MappingScreen') {
263 this.mappingEditorService.setTemplateMappingDataFromStore(this.configMappingEditorContent);
265 if (this.fileType === 'text/xml') {
266 sessionStorage.setItem('fileType', 'text/xml');
268 if (this.fileType === '') {
269 sessionStorage.setItem('fileType', '');
273 //========================== End of saveTemplate() Method============================================
274 retrieveTemplateFromAppc() {
275 let refObj = this.refObj;
276 if (refObj && refObj != undefined) {
278 let fileName = this.artifactName;
279 let payload = '{"userID": "' + this.userId + '","action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}';
283 "request-id": this.apiToken,
284 "action": "getArtifact",
289 let artifactContent: any;
290 this.ngProgress.start();
292 url: environment.getDesigns,
294 }).subscribe(resp => {
295 if (resp.output.status.code === '400' && resp.output.status.message === "success") {
296 this.nService.success("Success", "Template retrieved successfully from APPC");
297 this.tempRetrievalResponse = resp;
298 let result = JSON.parse(resp.output.data.block).artifactInfo[0];
299 result = result['artifact-content'];
300 if ('Generated Template' === this.selectedUploadType) {
301 this.configMappingEditorContent = result
302 this.artifactRequest.templateContent = this.configMappingEditorContent;
303 this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
304 if (this.artifactRequest.templateContent) {
305 this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal);
308 this.tempretrieveFlag = true;
309 this.fileNameForTempSave = fileName;
310 this.enableDownloadButtons = true;
311 this.initialData = result;
315 this.nService.info("Information", "There is no template saved in APPC for the selected action!");
317 this.ngProgress.done();
319 error => this.nService.error("Error", "Error in connecting to APPC Server"));
321 this.ngProgress.done();
325 //========================== End of retrieveTemplateFromAppc() Method============================================
327 let refObj = this.refObj;
328 if (refObj && refObj != undefined) {
329 let paramsKeyValueFromEditor: JSON;
331 paramsKeyValueFromEditor = JSON.parse(localStorage["paramsContent"]);
334 console.log("Could not parse name value pairs==" + error);
336 if (paramsKeyValueFromEditor) {
337 this.showTemplateVersionDiv = true;
338 let action = this.item.action;
339 var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, '');
341 let id = this.mappingEditorService.identifier;
342 if (id) fileName = this.updateFileNameForConfigScaleOut(this.item.action, scopeName, this.templateVersionNo, id);
343 else fileName = this.updateParamFileName(this.item.action, scopeName, this.templateVersionNo);
345 let vnfType = this.vnfType;
346 let Json = [paramsKeyValueFromEditor];
347 let slashedPayload = this.appendSlashes(JSON.stringify(Json));
350 "userID": this.userId,
351 "vnf-type": this.vnfType,
353 "artifact-name": fileName,
354 "artifact-type": "APPC-CONFIG",
355 "artifact-version": this.templateVersionNo,
356 "artifact-contents": slashedPayload
362 "request-id": this.apiToken,
363 "action": "uploadArtifact",
364 "payload": JSON.stringify(newPayload)
369 this.appDataObject.template.nameValueData = data;
371 if (this.configMappingEditorContent) {
372 let actualContent = this.configMappingEditorContent;
373 this.mappingEditorService.generateTemplate(this.templateEditor);
374 this.showTemplateVersionDiv = true;
375 let action = this.item.action;
376 let versionandFileType: any;
377 if (this.fileType === "text/xml") {
379 versionandFileType = this.templateVersionNo + 'V.xml'
382 versionandFileType = this.templateVersionNo + 'V.json'
385 if (this.tempretrieveFlag) {
386 fileName = this.fileNameForTempSave;
389 fileName = this.artifactName;
391 let vnfType = this.vnfType;
394 "userID": this.userId,
395 "vnf-type": this.vnfType,
397 "artifact-name": fileName,
398 "artifact-type": "APPC-CONFIG",
399 "artifact-version": this.templateVersionNo,
400 "artifact-contents": this.configMappingEditorContent.replace(/\(([^()]|(R))*\)=\(/g, '').replace(/\)}/g, '}')
407 "request-id": this.apiToken,
408 "action": "uploadArtifact",
409 "payload": JSON.stringify(newPayload)
414 this.appDataObject.template.templateData = data;
415 this.mappingEditorService.initialise(this.templateeditor.getEditor(), actualContent, this.modal);
419 //========================== End of prepareAppData() Method============================================
420 prepareFileName(): any {
421 let fileNameObject: any = this.mappingEditorService.latestAction;
422 this.appDataObject = this.mappingEditorService.appDataObject;
423 this.downloadDataObject = this.mappingEditorService.downloadDataObject;
424 this.referenceData = fileNameObject;
425 return fileNameObject;
427 //========================== End of prepareFileName() Method============================================
428 onDownloadParameter() {
429 let refObj = this.refObj;
431 let paramsKeyValueFromEditor: JSON;
433 paramsKeyValueFromEditor = JSON.parse(localStorage["paramsContent"]);
436 console.log("Could not parse name value pairs==" + error);
438 let theJSON = JSON.stringify(paramsKeyValueFromEditor, null, "\t")
439 var blob = new Blob([theJSON], {
442 this.showTemplateVersionDiv = true;
444 var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, '');
445 let id = this.mappingEditorService.identifier;
446 if (id) fileName = this.updateFileNameForConfigScaleOut(this.item.action, scopeName, this.templateVersionNo, id);
447 else fileName = this.updateParamFileName(this.item.action, scopeName, this.templateVersionNo);
449 this.downloadDataObject.template.nameValueData = theJSON;
450 this.downloadDataObject.template.nameValueFileName = fileName;
453 this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen");
457 //========================== End of onDownloadParameter() Method============================================
458 updateParamFileName(action: any, scopeName: any, versionNo: any) {
459 let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V.json';
460 this.downloadedParamFileName = fileName;
463 //========================== End of updateParamFileName() Method============================================
464 updateFileNameForConfigScaleOut(action: any, scopeName: any, versionNo: any, id: any) {
465 let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V_' + id + '.json';
466 this.downloadedParamFileName = fileName;
469 //========================== End of updateFileNameForConfigScaleOut() Method============================================
470 public onDownloadTemplate(artifact: string) {
471 let actualContent = this.configMappingEditorContent;
472 var textToSaveAsBlob: any;
473 var config_template_fileName: any
474 let refObj = this.refObj;
475 let versionandFileType: string;
476 if (artifact == 'Template' && this.artifactRequest && this.configMappingEditorContent && refObj) {
477 this.showTemplateVersionDiv = true;
478 if (this.fileType === "text/xml") {
479 textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
482 versionandFileType = this.templateVersionNo + 'V.xml'
484 if (this.fileType === "text/plain") {
485 textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
488 versionandFileType = this.templateVersionNo + 'V.txt'
490 if (this.fileType === "text/json") {
491 textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
494 versionandFileType = this.templateVersionNo + 'V.json'
496 if (this.tempretrieveFlag) {
497 config_template_fileName = this.fileNameForTempSave;
498 var filextension = config_template_fileName.substring(config_template_fileName.indexOf("V") + 2, config_template_fileName.length);
500 textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
501 type: "text/" + filextension
505 config_template_fileName = this.artifactName;
507 this.mappingEditorService.initialise(this.templateeditor.getEditor(), actualContent, this.modal);
508 this.downloadDataObject.template.templateData = this.configMappingEditorContent.replace(/\(([^()]|(R))*\)=\(/g, '').replace(/\)}/g, '}');
509 this.downloadDataObject.template.templateFileName = config_template_fileName;
513 //========================== End of onDownloadTemplate() Method============================================
517 let refObj = this.refObj;
518 this.enableValidateTemplate = true;
520 if (refObj && refObj != undefined) {
521 if (input.files && input.files[0]) {
522 this.myfileName = input.files[0].name;
523 this.fileName = input.files[0].name;
524 this.fileType = input.files[0].type;
525 let reader = new FileReader();
526 this.readFile(input.files[0], reader, (result) => {
527 if (this.fileType === 'text/xml') {
528 sessionStorage.setItem('fileType', 'text/xml');
530 if (this.fileName.endsWith(".json")) {
531 this.fileType = "text/json";
532 sessionStorage.setItem('fileType', 'text/json');
534 if (this.fileType === '') {
535 sessionStorage.setItem('fileType', '');
539 if ('Generated Template' === this.selectedUploadType) {
540 this.configMappingEditorContent = result
541 this.artifactRequest.templateContent = this.configMappingEditorContent;
542 this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
543 if (this.artifactRequest.templateContent) {
544 this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal);
547 this.enableDownloadButtons = true;
548 this.initialData = result;
554 this.nService.error("Error", "Failed to read file");
556 this.myInputVariable.nativeElement.value = "";
559 this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen");
563 //========================== End of fileChange() Method============================================
564 public readFile(file, reader, callback) {
565 // Set a callback funtion to fire after the file is fully loaded
566 reader.onload = () => {
567 // callback with the results
568 callback(reader.result);
570 this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size);
572 reader.readAsText(file, "UTF-8");
574 //========================== End of readFile() Method============================================
575 validateUploadedFile(fileExtension) {
577 if (fileExtension.toUpperCase() === 'json'.toUpperCase() || fileExtension.toUpperCase() === 'xml'.toUpperCase()) {
585 //========================== End of validateUploadedFile() Method============================================
586 appendSlashes(artifactData) {
587 let x = artifactData.replace(new RegExp(',"', "g"), ',\"');
588 let y = x.replace(new RegExp('":', 'g'), '\":');
589 let z = y.replace(new RegExp('{"', 'g'), '{\"')
590 let t = z.replace(new RegExp(':"', 'g'), ':\"')
591 let m = t.replace(new RegExp('",', 'g'), '\",');
592 let n = y.replace(new RegExp('"}', 'g'), '\"}')
593 let nw = n.replace(new RegExp('{"', 'g'), '{\"');
594 let nw1 = nw.replace(new RegExp(':"', 'g'), ':\"');
595 let nw2 = nw1.replace(new RegExp('",', 'g'), '\",');
598 //========================== End of appendSlashes() Method============================================
599 prepareDownloadData() {
600 this.onDownloadParameter();
601 this.onDownloadTemplate('Template');
603 //========================== End of prepareDownloadData() Method============================================
605 this.mappingEditorService.replaceNamesWithBlankValues();
608 var templateData = this.mappingEditorService.paramData; //template data array
609 var pdData = this.paramShareService.getSessionParamData(); //PD data array
610 var paramsContent = localStorage["paramsContent"];
612 if (paramsContent && paramsContent != undefined) {
614 var paramTabData = JSON.parse(paramsContent);
617 console.log("error is : " + error)
622 var resultParamObj = {};
623 let checkNamesOnlyCondition: boolean = true;
625 if (templateData && templateData != undefined) {
626 templateData.forEach(function (item) {
627 if (item.paramValue !== "" && item.paramValue != undefined && item.paramValue != null) {
628 checkNamesOnlyCondition = false;
633 templateData.forEach(function (item) {
634 resultParamObj[item.paramName] = item.paramValue;
636 if (paramTabData && paramTabData != undefined) {
637 templateData.forEach(function (item) {
638 for (var index in paramTabData) {
639 if (item.paramName === index) {
640 if (checkNamesOnlyCondition) {
641 resultParamObj[index] = paramTabData[index];
644 if (item.paramValue === "") {
645 resultParamObj[index] = paramTabData[index];
648 resultParamObj[index] = item.paramValue;
658 localStorage["paramsContent"] = JSON.stringify(resultParamObj);
659 templateData = Array.from(new Set(templateData.map((itemInArray) => itemInArray.paramName)))
661 //reformatting arr1 to match with PD
662 templateData.forEach(function (item) {
698 "ruleTypeValues": [null]
703 if (pdData && pdData != undefined) {
704 for (var i = 0; i < resultArr.length; i++) {
706 pdData.forEach(function (arr2item) {
707 if (resultArr[i].name === arr2item.name) {
710 "name": arr2item.name,
711 "type": arr2item.type,
712 "description": arr2item.description,
713 "required": arr2item.required,
714 "default": arr2item.default,
715 "source": arr2item.source,
716 "rule-type": arr2item["rule-type"],
717 "request-keys": arr2item["request-keys"],
718 "response-keys": arr2item["response-keys"],
719 "ruleTypeValues": arr2item.ruleTypeValues
721 resultArr.splice(i, 1, json)
729 this.paramShareService.setSessionParamData(resultArr);
730 this.mappingEditorService.paramData = [];
731 //navigate to PD page after sync
734 .navigate(['../../../vnfs/design/parameterDefinitions/create']);
737 //========================== End of syncTemplate() Method============================================
739 this.mergeStatus = this.mappingEditorService.autoAnnotateDataForParams();
740 if (this.mergeStatus) {
741 this.nService.success("Success", "Merge Successful");
744 this.nService.error("Error", "Merge Unsuccessful");
748 //========================== End of mergeParams() Method============================================
749 public handleAnnotation(modal) {
751 this.selectedWord = this.templateeditor.getEditor().session.getTextRange(this.templateeditor.getEditor().selectionRange);
752 if (this.selectedWord && this.selectedWord != undefined) modal.open();
754 //========================== End of handleAnnotations() Method============================================
755 public submitNameValues() {
757 this.checkNameEntered = true;
759 if (this.selectedWord) {
760 if (this.selectedWord.startsWith('${(')) {
761 var replaceWord: any = this.replaceWord = this.selectedWord.substring(3, this.selectedWord.indexOf(')=(')) + this.tempName;
762 this.templateeditor.getEditor().session.replace(this.templateeditor.getEditor().session.selection.getRange(), replaceWord);
765 let mappingKey = this.mappingEditorService.getKeysForValues(this.selectedWord);
766 var replaceWord: any = this.replaceWord = '${(' + this.selectedWord + ')=(' + this.tempName + ')}';
767 this.templateeditor.getEditor().session.replace(this.templateeditor.getEditor().session.selection.getRange(), replaceWord);
771 this.mappingEditorService.refreshEditor();
777 this.checkNameEntered = false;
781 //========================== End of submitNameValues() Method============================================