NG-UI BUG 1118 YAML not supported in config text-area when launching NS
[osm/NG-UI.git] / src / app / packages / instantiate-net-slice-template / InstantiateNetSliceTemplateComponent.ts
1 /*
2  Copyright 2020 TATA ELXSI
3
4  Licensed under the Apache License, Version 2.0 (the 'License');
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8   http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15
16  Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17  */
18 /**
19  * @file Instantiate NS Modal Component.
20  */
21 import { HttpHeaders } from '@angular/common/http';
22 import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
23 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { Router } from '@angular/router';
25 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
26 import { TranslateService } from '@ngx-translate/core';
27 import { NotifierService } from 'angular-notifier';
28 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
29 import { DataService } from 'DataService';
30 import { environment } from 'environment';
31 import * as jsyaml from 'js-yaml';
32 import { NetworkSliceData } from 'NetworkSliceModel';
33 import { NSICREATEPARAMS } from 'NSDModel';
34 import { RestService } from 'RestService';
35 import { SharedService } from 'SharedService';
36 import { isNullOrUndefined } from 'util';
37 import { VimAccountDetails } from 'VimAccountModel';
38 /**
39  * Creating component
40  * @Component takes InstantiateNetSliceTemplateComponent.html as template url
41  */
42 @Component({
43   selector: 'app-instantiate-net-slice-template',
44   templateUrl: './InstantiateNetSliceTemplateComponent.html',
45   styleUrls: ['./InstantiateNetSliceTemplateComponent.scss']
46 })
47 /** Exporting a class @exports InstantiateNetSliceTemplateComponent */
48 export class InstantiateNetSliceTemplateComponent implements OnInit {
49   /** To inject services @public */
50   public injector: Injector;
51
52   /** FormGroup instance added to the form @ html @public */
53   public netSliceInstantiateForm: FormGroup;
54
55   /** Instance for active modal service @public */
56   public activeModal: NgbActiveModal;
57
58   /** Variable set for twoway bindng @public  */
59   public vimAccountId: string;
60
61   /** Contains all the net slice data collections */
62   public netSliceSelect: NetworkSliceData;
63
64   /** Contains all the VIM data collections */
65   public vimDetailsSelect: VimAccountDetails;
66
67   /** Variable set for twoway binding @public */
68   public netsliceNstId: string;
69
70   /** Form submission Add */
71   public submitted: boolean = false;
72
73   /** Check the loading results for loader status @public */
74   public isLoadingResults: boolean = false;
75
76   /** Give the message for the loading @public */
77   public message: string = 'PLEASEWAIT';
78
79   /** Element ref for fileInputConfig @public */
80   @ViewChild('fileInputConfig', { static: true }) public fileInputConfig: ElementRef;
81
82   /** Element ref for fileInputConfigLabel @public */
83   @ViewChild('fileInputConfigLabel', { static: true }) public fileInputConfigLabel: ElementRef;
84
85   /** Element ref for fileInputSSH @public */
86   @ViewChild('fileInputSSH', { static: true }) public fileInputSSH: ElementRef;
87
88   /** Element ref for fileInputSSHLabel @public */
89   @ViewChild('fileInputSSHLabel', { static: true }) public fileInputSSHLabel: ElementRef;
90
91   /** Holds teh instance of AuthService class of type AuthService @private */
92   private router: Router;
93
94   /** FormBuilder instance added to the formBuilder @private */
95   private formBuilder: FormBuilder;
96
97   /** Utilizes rest service for any CRUD operations @private */
98   private restService: RestService;
99
100   /** Utilizes data service for any communication @private */
101   private dataService: DataService;
102
103   /** Controls the header form @private */
104   private headers: HttpHeaders;
105
106   /** Notifier service to popup notification @private */
107   private notifierService: NotifierService;
108
109   /** Contains tranlsate instance @private */
110   private translateService: TranslateService;
111
112   /** Contains all methods related to shared @private */
113   private sharedService: SharedService;
114
115   /** Contains the ssh key to be hosted in dom @private */
116   private copySSHKey: string;
117
118   constructor(injector: Injector) {
119     this.injector = injector;
120     this.restService = this.injector.get(RestService);
121     this.activeModal = this.injector.get(NgbActiveModal);
122     this.formBuilder = this.injector.get(FormBuilder);
123     this.dataService = this.injector.get(DataService);
124     this.notifierService = this.injector.get(NotifierService);
125     this.router = this.injector.get(Router);
126     this.translateService = this.injector.get(TranslateService);
127     this.sharedService = this.injector.get(SharedService);
128   }
129
130   /** Lifecyle Hooks the trigger before component is instantiate @public */
131   public ngOnInit(): void {
132     /** Setting up initial value for NSD */
133     this.netsliceNstId = '';
134     this.dataService.currentMessage.subscribe((event: NetworkSliceData) => {
135       if (event.identifier !== undefined || event.identifier !== '' || event.identifier !== null) {
136         this.netsliceNstId = event.identifier;
137       }
138     });
139     this.netSliceInstantiateFormAction();
140     this.headers = new HttpHeaders({
141       'Content-Type': 'application/json',
142       Accept: 'application/json',
143       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
144     });
145     /** On Initializing call the methods */
146     this.getNetSliceDetails();
147     this.getVIMDetails();
148   }
149
150   /** Call the netSlice details in the selection options @public */
151   public getNetSliceDetails(): void {
152     this.restService.getResource(environment.NETWORKSLICETEMPLATECONTENT_URL).subscribe((netSlicePackages: NetworkSliceData) => {
153       this.netSliceSelect = netSlicePackages;
154     }, (error: ERRORDATA) => {
155       this.restService.handleError(error, 'get');
156     });
157   }
158
159   /** Call the VIM details in the selection options @public */
160   public getVIMDetails(): void {
161     this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimDetails: VimAccountDetails) => {
162       this.vimDetailsSelect = vimDetails;
163     }, (error: ERRORDATA) => {
164       this.restService.handleError(error, 'get');
165     });
166   }
167
168   /** On modal initializing forms  @public */
169   public netSliceInstantiateFormAction(): void {
170     this.netSliceInstantiateForm = this.formBuilder.group({
171       nsiName: ['', [Validators.required]],
172       nsiDescription: ['', [Validators.required]],
173       nstId: ['', [Validators.required]],
174       vimAccountId: ['', [Validators.required]],
175       ssh_keys: [null],
176       config: [null]
177     });
178   }
179   /** convenience getter for easy access to form fields */
180   get f(): FormGroup['controls'] { return this.netSliceInstantiateForm.controls; }
181
182   /** On modal submit instantiateNsSubmit will called @public */
183   public instantiateNSTSubmit(): void {
184     this.submitted = true;
185     this.sharedService.cleanForm(this.netSliceInstantiateForm);
186     if (this.netSliceInstantiateForm.invalid) {
187       return;
188     }
189     const modalData: MODALCLOSERESPONSEDATA = {
190       message: 'Done'
191     };
192     if (isNullOrUndefined(this.netSliceInstantiateForm.value.ssh_keys) || this.netSliceInstantiateForm.value.ssh_keys === '') {
193       delete this.netSliceInstantiateForm.value.ssh_keys;
194     } else {
195       this.copySSHKey = JSON.parse(JSON.stringify(this.netSliceInstantiateForm.value.ssh_keys));
196       // tslint:disable-next-line: no-backbone-get-set-outside-model
197       this.netSliceInstantiateForm.get('ssh_keys').setValue(this.copySSHKey);
198     }
199     if (isNullOrUndefined(this.netSliceInstantiateForm.value.config) || this.netSliceInstantiateForm.value.config === '') {
200       delete this.netSliceInstantiateForm.value.config;
201     } else {
202       const validJSON: boolean = this.sharedService.checkJson(this.netSliceInstantiateForm.value.config);
203       if (validJSON) {
204         this.netSliceInstantiateForm.value.config = JSON.parse(this.netSliceInstantiateForm.value.config);
205         Object.keys(this.netSliceInstantiateForm.value.config).forEach((item: string) => {
206           this.netSliceInstantiateForm.value[item] = this.netSliceInstantiateForm.value.config[item];
207         });
208         delete this.netSliceInstantiateForm.value.config;
209       } else {
210         const getConfigJson: string = jsyaml.load(this.netSliceInstantiateForm.value.config, { json: true });
211         Object.keys(getConfigJson).forEach((item: string) => {
212           this.netSliceInstantiateForm.value[item] = getConfigJson[item];
213         });
214         delete this.netSliceInstantiateForm.value.config;
215       }
216     }
217     this.isLoadingResults = true;
218     const apiURLHeader: APIURLHEADER = {
219       url: environment.NETWORKSLICEINSTANCESCONTENT_URL,
220       httpOptions: { headers: this.headers }
221     };
222     this.restService.postResource(apiURLHeader, this.netSliceInstantiateForm.value)
223       .subscribe((result: {}) => {
224         this.activeModal.close(modalData);
225         this.isLoadingResults = false;
226         this.notifierService.notify('success', this.netSliceInstantiateForm.value.nsiName +
227           this.translateService.instant('PAGE.NETSLICE.CREATEDSUCCESSFULLY'));
228         this.router.navigate(['/instances/netslice']).catch();
229       }, (error: ERRORDATA) => {
230         this.restService.handleError(error, 'post');
231         if (!isNullOrUndefined(this.copySSHKey)) {
232           // tslint:disable-next-line: no-backbone-get-set-outside-model
233           this.netSliceInstantiateForm.get('ssh_keys').setValue(this.copySSHKey);
234         }
235         this.isLoadingResults = false;
236       });
237   }
238
239   /** ssh file process @private */
240   public sshFile(files: FileList): void {
241     if (files && files.length === 1) {
242       this.sharedService.getFileString(files, 'pub').then((fileContent: string): void => {
243         const getSSHJson: string = jsyaml.load(fileContent, { json: true });
244         // tslint:disable-next-line: no-backbone-get-set-outside-model
245         this.netSliceInstantiateForm.get('ssh_keys').setValue(getSSHJson);
246       }).catch((err: string): void => {
247         if (err === 'typeError') {
248           this.notifierService.notify('error', this.translateService.instant('PUBFILETYPEERRROR'));
249         } else {
250           this.notifierService.notify('error', this.translateService.instant('ERROR'));
251         }
252         this.fileInputSSHLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
253         this.fileInputSSH.nativeElement.value = null;
254       });
255     } else if (files && files.length > 1) {
256       this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
257     }
258     this.fileInputSSHLabel.nativeElement.innerText = files[0].name;
259     this.fileInputSSH.nativeElement.value = null;
260   }
261
262   /** Config file process @private */
263   public configFile(files: FileList): void {
264     if (files && files.length === 1) {
265       const fileFormat: string = this.sharedService.fetchFileExtension(files).toLocaleLowerCase();
266       if (fileFormat === 'yaml' || fileFormat === 'yml') {
267         this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
268           const getConfigJson: string = jsyaml.load(fileContent, { json: true });
269           // tslint:disable-next-line: no-backbone-get-set-outside-model
270           this.netSliceInstantiateForm.get('config').setValue(JSON.stringify(getConfigJson));
271         }).catch((err: string): void => {
272           if (err === 'typeError') {
273             this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
274           } else {
275             this.notifierService.notify('error', this.translateService.instant('ERROR'));
276           }
277           this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
278           this.fileInputConfig.nativeElement.value = null;
279         });
280       } else if (fileFormat === 'json') {
281         this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
282           const getConfigJson: string = jsyaml.load(fileContent, { json: true });
283           // tslint:disable-next-line: no-backbone-get-set-outside-model
284           this.netSliceInstantiateForm.get('config').setValue(JSON.stringify(getConfigJson));
285         }).catch((err: string): void => {
286           if (err === 'typeError') {
287             this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
288           } else {
289             this.notifierService.notify('error', this.translateService.instant('ERROR'));
290           }
291           this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
292           this.fileInputConfig.nativeElement.value = null;
293         });
294       }
295     } else if (files && files.length > 1) {
296       this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
297     }
298     this.fileInputConfigLabel.nativeElement.innerText = files[0].name;
299     this.fileInputConfig.nativeElement.value = null;
300   }
301 }