befafb8d8598c3b53808a488c8393da741380df1
[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     mode: this.modeDefault,
94     showCursorWhenSelecting: true,
95     autofocus: true,
96     autoRefresh: true,
97     lineNumbers: true,
98     lineWrapping: true,
99     foldGutter: true,
100     gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
101     autoCloseBrackets: true,
102     matchBrackets: true,
103     theme: 'neat',
104     keyMap: 'sublime'
105   };
106
107   /** Ymal Url for the VNFD & NSD */
108   public ymalUrl: string;
109
110   /** json Url for the VNFD & NSD */
111   public jsonUrl: string;
112
113   /** Navigation Path for the VNFD & NSD */
114   public navigatePath: string;
115
116   /** Package type */
117   public pacakgeType: string;
118
119   /** variables contains paramsID @public */
120   public paramsID: string;
121
122   /** Controls the File Type List form @public */
123   public fileTypes: { value: string; viewValue: string; }[] = [];
124
125   /** Check the loading results @public */
126   public isLoadingResults: boolean = true;
127
128   /** Give the message for the loading @public */
129   public message: string = 'PLEASEWAIT';
130
131   /** Instance of the rest service @private */
132   private restService: RestService;
133
134   /** Holds teh instance of AuthService class of type AuthService @private */
135   private router: Router;
136
137   /** Holds teh instance of AuthService class of type AuthService @private */
138   private activatedRoute: ActivatedRoute;
139
140   /** Data @private */
141   private data: string = '';
142
143   /** contains http options @private */
144   private httpOptions: HttpHeaders;
145
146   /** Controls the header form @private */
147   private headers: HttpHeaders;
148
149   /** Notifier service to popup notification @private */
150   private notifierService: NotifierService;
151
152   /** Contains tranlsate instance @private */
153   private translateService: TranslateService;
154
155   /** Contains all methods related to shared @private */
156   private sharedService: SharedService;
157
158   constructor(injector: Injector) {
159     this.injector = injector;
160     this.restService = this.injector.get(RestService);
161     this.activatedRoute = this.injector.get(ActivatedRoute);
162     this.router = this.injector.get(Router);
163     this.notifierService = this.injector.get(NotifierService);
164     this.translateService = this.injector.get(TranslateService);
165     this.sharedService = this.injector.get(SharedService);
166   }
167
168   /** Lifecyle Hooks the trigger before component is instantiate @public */
169   public ngOnInit(): void {
170     this.headers = new HttpHeaders({
171       'Content-Type': 'application/json',
172       Accept: 'text/plain',
173       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
174     });
175     // tslint:disable-next-line: no-backbone-get-set-outside-model
176     this.paramsID = this.activatedRoute.snapshot.paramMap.get('id');
177     // tslint:disable-next-line: no-backbone-get-set-outside-model
178     this.pacakgeType = this.activatedRoute.snapshot.paramMap.get('type');
179     this.generateURLPath();
180   }
181
182   /** generate ymalURL, JSONURL, navigation Path */
183   public generateURLPath(): void {
184     if (this.pacakgeType === 'vnf') {
185       this.getUpdateURL = environment.VNFPACKAGES_URL;
186       this.getFileContentType = 'vnfd';
187       this.updateFileContentType = 'package_content';
188       this.navigatePath = 'vnf';
189       this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }, { value: 'text/json', viewValue: 'json' }];
190       this.httpOptions = this.getHeadersWithContentAccept('application/zip', 'application/json');
191       this.getEditFileData();
192     } else if (this.pacakgeType === 'netslice') {
193       this.getUpdateURL = environment.NETWORKSLICETEMPLATE_URL;
194       this.getFileContentType = 'nst';
195       this.updateFileContentType = 'nst_content';
196       this.navigatePath = 'netslice';
197       this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }];
198       this.httpOptions = this.getHeadersWithContentAccept('application/yaml', 'application/json');
199       this.getEditFileData();
200     } else {
201       this.getUpdateURL = environment.NSDESCRIPTORS_URL;
202       this.getFileContentType = 'nsd';
203       this.updateFileContentType = 'nsd_content';
204       this.pacakgeType = 'nsd';
205       this.navigatePath = 'ns';
206       this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }, { value: 'text/json', viewValue: 'json' }];
207       this.httpOptions = this.getHeadersWithContentAccept('application/zip', 'application/json');
208       this.getEditFileData();
209     }
210   }
211
212   /** Get the headers based on the type @public */
213   public getHeadersWithContentAccept(contentType: string, acceptType: string): HttpHeaders {
214     this.headers = new HttpHeaders({
215       'Content-Type': contentType,
216       Accept: acceptType,
217       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
218     });
219     return this.headers;
220   }
221
222   /** ChangeMode function @public */
223   public changeMode(): void {
224     if (this.mode === 'text/x-yaml') {
225       this.modeDefault = 'yaml';
226     } else {
227       this.modeDefault = 'javascript';
228     }
229     this.options = {
230       ...this.options,
231       mode: this.modeDefault
232     };
233     this.data = '';
234   }
235
236   /** HandleChange function @public */
237   public handleChange($event: string): void {
238     this.data = $event;
239   }
240
241   /** Update function @public */
242   public update(showgraph: boolean): void {
243     if (this.data === '') {
244       this.notifierService.notify('warning', this.translateService.instant('PAGE.TOPOLOGY.DATAEMPTY'));
245     } else {
246       this.updateCheck(showgraph);
247     }
248   }
249   /** Update the file Data @public */
250   public updateFileData(urlHeader: APIURLHEADER, fileData: string | ArrayBuffer, showgraph: boolean, packageType: string): void {
251     this.restService.putResource(urlHeader, fileData).subscribe(() => {
252       this.isLoadingResults = false;
253       this.notifierService.notify('success', this.translateService.instant(
254         (packageType !== 'netslice') ? 'PAGE.NSPACKAGE.EDITPACKAGES.UPDATEDSUCCESSFULLY' : 'PAGE.NETSLICE.UPDATEDSUCCESSFULLY'));
255       if (showgraph) {
256         if (packageType === 'nsd') {
257           this.router.navigate(['/packages/ns/compose/' + this.paramsID]).catch();
258         } else if (packageType === 'vnf') {
259           this.router.navigate(['/packages/vnf/compose/' + this.paramsID]).catch();
260         }
261       }
262       this.getEditFileData();
263     }, (error: ERRORDATA) => {
264       this.isLoadingResults = false;
265       this.restService.handleError(error, 'put');
266     });
267   }
268   /** Update method for NS, VNF and net-slice template */
269   private updateCheck(showgraph: boolean): void {
270     this.isLoadingResults = true;
271     const apiURLHeader: APIURLHEADER = {
272       url: this.getUpdateURL + '/' + this.paramsID + '/' + this.updateFileContentType,
273       httpOptions: { headers: this.httpOptions }
274     };
275     let descriptorInfo: string = '';
276     if (this.mode === 'text/json') {
277       descriptorInfo = jsyaml.dump(JSON.parse(this.data), {sortKeys: true});
278     } else {
279       descriptorInfo = this.data;
280     }
281     if (this.getFileContentType !== 'nst') {
282       this.sharedService.targzFile({ packageType: this.pacakgeType, id: this.paramsID, descriptor: descriptorInfo })
283         .then((content: ArrayBuffer): void => {
284           this.updateFileData(apiURLHeader, content, showgraph, this.pacakgeType);
285         }).catch((): void => {
286           this.isLoadingResults = false;
287           this.notifierService.notify('error', this.translateService.instant('ERROR'));
288         });
289     } else {
290       this.updateFileData(apiURLHeader, descriptorInfo, showgraph, this.pacakgeType);
291     }
292   }
293   /** Get the YAML content response as a plain/text and convert to JSON Format @private */
294   private getEditFileData(): void {
295     this.isLoadingResults = true;
296     const gethttpOptions: HttpHeaders = this.getHeadersWithContentAccept('application/json', 'text/plain');
297     const httpOptions: GETAPIURLHEADER = {
298       headers: gethttpOptions,
299       responseType: 'text'
300     };
301     this.restService.getResource(this.getUpdateURL + '/' + this.paramsID + '/' + this.getFileContentType, httpOptions)
302       .subscribe((nsData: NSDDetails[]) => {
303         const getJson: string = jsyaml.load(nsData.toString(), { json: true });
304         //tslint:disable-next-line:no-string-literal
305         this.defaults['text/x-yaml'] = nsData.toString();
306         this.defaults['text/json'] = JSON.stringify(getJson, null, '\t');
307         this.isLoadingResults = false;
308       }, (error: ERRORDATA) => {
309         error.error = typeof error.error === 'string' ? jsyaml.load(error.error) : error.error;
310         if (error.error.status === HttpStatus.NOT_FOUND || error.error.status === HttpStatus.UNAUTHORIZED  ) {
311           this.router.navigateByUrl('404', { skipLocationChange: true }).catch();
312         } else {
313           this.restService.handleError(error, 'get');
314         }
315         this.isLoadingResults = false;
316       });
317   }
318 }