Fix Bug 2336: Manual Healing option in Ui
[osm/NG-UI.git] / src / app / utilities / edit-packages / EditPackagesComponent.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 Edit Actions Component
20  */
21 import { HttpHeaders } from '@angular/common/http';
22 import { Component, Injector, OnInit } from '@angular/core';
23 import { ActivatedRoute, Router } from '@angular/router';
24 import { TranslateService } from '@ngx-translate/core';
25 import { NotifierService } from 'angular-notifier';
26 import 'codemirror/addon/dialog/dialog';
27 import 'codemirror/addon/display/autorefresh';
28 import 'codemirror/addon/display/fullscreen';
29 import 'codemirror/addon/edit/closebrackets';
30 import 'codemirror/addon/edit/matchbrackets';
31 import 'codemirror/addon/fold/brace-fold';
32 import 'codemirror/addon/fold/foldcode';
33 import 'codemirror/addon/fold/foldgutter';
34 import 'codemirror/addon/search/search';
35 import 'codemirror/addon/search/searchcursor';
36 import 'codemirror/keymap/sublime';
37 import 'codemirror/lib/codemirror';
38 import 'codemirror/mode/javascript/javascript';
39 import 'codemirror/mode/markdown/markdown';
40 import 'codemirror/mode/yaml/yaml';
41 import { APIURLHEADER, ERRORDATA, GETAPIURLHEADER } from 'CommonModel';
42 import { environment } from 'environment';
43 import * as HttpStatus from 'http-status-codes';
44 import * as jsyaml from 'js-yaml';
45 import { NSDDetails } from 'NSDModel';
46 import { RestService } from 'RestService';
47 import { SharedService } from 'SharedService';
48
49 /**
50  * Creating component
51  * @Component takes EditPackagesComponent.html as template url
52  */
53 @Component({
54   selector: 'app-edit-packages',
55   templateUrl: './EditPackagesComponent.html',
56   styleUrls: ['./EditPackagesComponent.scss']
57 })
58
59 /** Exporting a class @exports EditPackagesComponent */
60 export class EditPackagesComponent implements OnInit {
61   /** To inject services @public */
62   public injector: Injector;
63
64   /** dataService to pass the data from one component to another @public */
65   public identifier: {} = {};
66
67   /** readOnly @public */
68   public readOnly: boolean = false;
69
70   /** Handle the formate Change @public */
71   public defaults: {} = {
72     'text/x-yaml': '',
73     'text/json': ''
74   };
75
76   /** Get & Update URL VNFD & NSD */
77   public getUpdateURL: string;
78
79   /** Pass the type of VNFD & NSD for fetching text */
80   public getFileContentType: string;
81
82   /** Pass the type of VNFD & NSD for fileUpdate */
83   public updateFileContentType: string;
84
85   /** To Set Mode @public */
86   public mode: string = 'text/x-yaml';
87
88   /** To Set Mode @public */
89   public modeDefault: string = 'yaml';
90
91   /** options @public */
92   public options: {} = {
93     // eslint-disable-next-line no-invalid-this
94     mode: this.modeDefault,
95     showCursorWhenSelecting: true,
96     autofocus: true,
97     autoRefresh: true,
98     lineNumbers: true,
99     lineWrapping: true,
100     foldGutter: true,
101     gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
102     autoCloseBrackets: true,
103     matchBrackets: true,
104     theme: 'neat',
105     keyMap: 'sublime'
106   };
107
108   /** Ymal Url for the VNFD & NSD */
109   public ymalUrl: string;
110
111   /** json Url for the VNFD & NSD */
112   public jsonUrl: string;
113
114   /** Navigation Path for the VNFD & NSD */
115   public navigatePath: string;
116
117   /** Package type */
118   public pacakgeType: string;
119
120   /** variables contains paramsID @public */
121   public paramsID: string;
122
123   /** Controls the File Type List form @public */
124   public fileTypes: { value: string; viewValue: string; }[] = [];
125
126   /** Check the loading results @public */
127   public isLoadingResults: boolean = true;
128
129   /** Give the message for the loading @public */
130   public message: string = 'PLEASEWAIT';
131
132   /** Instance of the rest service @private */
133   private restService: RestService;
134
135   /** Holds teh instance of AuthService class of type AuthService @private */
136   private router: Router;
137
138   /** Holds teh instance of AuthService class of type AuthService @private */
139   private activatedRoute: ActivatedRoute;
140
141   /** Data @private */
142   private data: string = '';
143
144   /** Contains updated data @private */
145   private updateData: string;
146
147   /** contains http options @private */
148   private httpOptions: HttpHeaders;
149
150   /** Controls the header form @private */
151   private headers: HttpHeaders;
152
153   /** Notifier service to popup notification @private */
154   private notifierService: NotifierService;
155
156   /** Contains tranlsate instance @private */
157   private translateService: TranslateService;
158
159   /** Contains all methods related to shared @private */
160   private sharedService: SharedService;
161
162   constructor(injector: Injector) {
163     this.injector = injector;
164     this.restService = this.injector.get(RestService);
165     this.activatedRoute = this.injector.get(ActivatedRoute);
166     this.router = this.injector.get(Router);
167     this.notifierService = this.injector.get(NotifierService);
168     this.translateService = this.injector.get(TranslateService);
169     this.sharedService = this.injector.get(SharedService);
170   }
171
172   /** Lifecyle Hooks the trigger before component is instantiate @public */
173   public ngOnInit(): void {
174     this.headers = new HttpHeaders({
175       'Content-Type': 'application/json',
176       Accept: 'text/plain',
177       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
178     });
179     this.paramsID = this.activatedRoute.snapshot.paramMap.get('id');
180     this.pacakgeType = this.activatedRoute.snapshot.paramMap.get('type');
181     this.generateURLPath();
182   }
183
184   /** generate ymalURL, JSONURL, navigation Path */
185   public generateURLPath(): void {
186     if (this.pacakgeType === 'vnf') {
187       this.getUpdateURL = environment.VNFPACKAGES_URL;
188       this.getFileContentType = 'vnfd';
189       this.updateFileContentType = 'package_content';
190       this.navigatePath = 'vnf';
191       this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }, { value: 'text/json', viewValue: 'json' }];
192       this.httpOptions = this.getHeadersWithContentAccept('application/gzip', 'application/json');
193       this.getEditFileData();
194     } else if (this.pacakgeType === 'netslice') {
195       this.getUpdateURL = environment.NETWORKSLICETEMPLATE_URL;
196       this.getFileContentType = 'nst';
197       this.updateFileContentType = 'nst_content';
198       this.navigatePath = 'netslice';
199       this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }];
200       this.httpOptions = this.getHeadersWithContentAccept('application/yaml', 'application/json');
201       this.getEditFileData();
202     } else {
203       this.getUpdateURL = environment.NSDESCRIPTORS_URL;
204       this.getFileContentType = 'nsd';
205       this.updateFileContentType = 'nsd_content';
206       this.pacakgeType = 'nsd';
207       this.navigatePath = 'ns';
208       this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }, { value: 'text/json', viewValue: 'json' }];
209       this.httpOptions = this.getHeadersWithContentAccept('application/gzip', 'application/json');
210       this.getEditFileData();
211     }
212   }
213
214   /** Get the headers based on the type @public */
215   public getHeadersWithContentAccept(contentType: string, acceptType: string): HttpHeaders {
216     this.headers = new HttpHeaders({
217       'Content-Type': contentType,
218       Accept: acceptType,
219       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
220     });
221     return this.headers;
222   }
223
224   /** ChangeMode function @public */
225   public changeMode(): void {
226     if (this.mode === 'text/x-yaml') {
227       this.modeDefault = 'yaml';
228     } else {
229       this.modeDefault = 'javascript';
230     }
231     this.options = {
232       ...this.options,
233       mode: this.modeDefault
234     };
235     this.data = '';
236   }
237
238   /** HandleChange function @public */
239   public handleChange($event: string): void {
240     this.data = $event;
241   }
242
243   /** Update function @public */
244   public update(showgraph: boolean): void {
245     if (this.data === '' || this.data === this.updateData) {
246       this.notifierService.notify('warning', this.translateService.instant('PAGE.TOPOLOGY.DATAEMPTY'));
247     } else {
248       this.updateCheck(showgraph);
249     }
250   }
251   /** Update the file Data @public */
252   public updateFileData(urlHeader: APIURLHEADER, fileData: string | ArrayBuffer, showgraph: boolean, packageType: string): void {
253     this.restService.putResource(urlHeader, fileData).subscribe(() => {
254       this.isLoadingResults = false;
255       this.notifierService.notify('success', this.translateService.instant(
256         (packageType !== 'netslice') ? 'PAGE.NSPACKAGE.EDITPACKAGES.UPDATEDSUCCESSFULLY' : 'PAGE.NETSLICE.UPDATEDSUCCESSFULLY'));
257       if (showgraph) {
258         if (packageType === 'nsd') {
259           this.router.navigate(['/packages/ns/compose/' + this.paramsID]).catch((): void => {
260             // Catch Navigation Error
261           });
262         } else if (packageType === 'vnf') {
263           this.router.navigate(['/packages/vnf/compose/' + this.paramsID]).catch((): void => {
264             // Catch Navigation Error
265           });
266         }
267       }
268       this.getEditFileData();
269     }, (error: ERRORDATA) => {
270       this.isLoadingResults = false;
271       this.restService.handleError(error, 'put');
272     });
273   }
274   /** Update method for NS, VNF and net-slice template */
275   private updateCheck(showgraph: boolean): void {
276     this.isLoadingResults = true;
277     const apiURLHeader: APIURLHEADER = {
278       url: this.getUpdateURL + '/' + this.paramsID + '/' + this.updateFileContentType,
279       httpOptions: { headers: this.httpOptions }
280     };
281     let descriptorInfo: string = '';
282     if (this.mode === 'text/json') {
283       descriptorInfo = jsyaml.dump(JSON.parse(this.data), { sortKeys: true });
284     } else {
285       descriptorInfo = this.data;
286     }
287     this.updateData = this.data;
288     if (this.getFileContentType !== 'nst') {
289       this.sharedService.targzFile({ packageType: this.pacakgeType, id: this.paramsID, descriptor: descriptorInfo })
290         .then((content: ArrayBuffer): void => {
291           this.updateFileData(apiURLHeader, content, showgraph, this.pacakgeType);
292         }).catch((): void => {
293           this.isLoadingResults = false;
294           this.notifierService.notify('error', this.translateService.instant('ERROR'));
295         });
296     } else {
297       this.updateFileData(apiURLHeader, descriptorInfo, showgraph, this.pacakgeType);
298     }
299   }
300   /** Get the YAML content response as a plain/text and convert to JSON Format @private */
301   private getEditFileData(): void {
302     this.isLoadingResults = true;
303     const gethttpOptions: HttpHeaders = this.getHeadersWithContentAccept('application/json', 'text/plain');
304     const httpOptions: GETAPIURLHEADER = {
305       headers: gethttpOptions,
306       responseType: 'text'
307     };
308     this.restService.getResource(this.getUpdateURL + '/' + this.paramsID + '/' + this.getFileContentType, httpOptions)
309       .subscribe((nsData: NSDDetails[]) => {
310         const getJson: string = jsyaml.load(nsData.toString(), { json: true });
311         this.defaults['text/x-yaml'] = nsData.toString();
312         this.defaults['text/json'] = JSON.stringify(getJson, null, '\t');
313         this.isLoadingResults = false;
314       }, (error: ERRORDATA) => {
315         error.error = typeof error.error === 'string' ? jsyaml.load(error.error) : error.error;
316         if (error.error.status === HttpStatus.NOT_FOUND || error.error.status === HttpStatus.UNAUTHORIZED) {
317           this.router.navigateByUrl('404', { skipLocationChange: true }).catch((): void => {
318             // Catch Navigation Error
319           });
320         } else {
321           this.restService.handleError(error, 'get');
322         }
323         this.isLoadingResults = false;
324       });
325   }
326 }