Initial Commit - NG UI
[osm/NG-UI.git] / src / services / SharedService.ts
diff --git a/src/services/SharedService.ts b/src/services/SharedService.ts
new file mode 100644 (file)
index 0000000..3a138e5
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ Copyright 2020 TATA ELXSI
+
+ Licensed under the Apache License, Version 2.0 (the 'License');
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
+ */
+/**
+ * @file Provider for Shared Service
+ */
+import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
+import { EventEmitter, Injectable, Output } from '@angular/core';
+import { FormArray, FormGroup } from '@angular/forms';
+import { Router } from '@angular/router';
+import { CONSTANTNUMBER, ERRORDATA, GETAPIURLHEADER, PACKAGEINFO, PAGERSMARTTABLE, SMARTTABLECLASS, TARSETTINGS } from 'CommonModel';
+import { environment } from 'environment';
+import * as HttpStatus from 'http-status-codes';
+import * as untar from 'js-untar';
+import * as pako from 'pako';
+import { RestService } from 'RestService';
+import { isNullOrUndefined } from 'util';
+
+/** This is added globally by the tar.js library */
+// tslint:disable-next-line: no-any
+declare const Tar: any;
+
+/**
+ * An Injectable is a class adorned with the @Injectable decorator function.
+ * @Injectable takes a metadata object that tells Angular how to compile and run module code
+ */
+@Injectable({
+    providedIn: 'root'
+})
+/** Exporting a class @exports SharedService */
+export class SharedService {
+    /** call the parent using event information @private */
+    @Output() public dataEvent: EventEmitter<{}> = new EventEmitter<{}>();
+
+    /** Variables to hold regexp pattern for URL */
+    // tslint:disable-next-line: max-line-length
+    public REGX_URL_PATTERN: RegExp = new RegExp(/^(http?|ftp|https):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z0-9]{2,15})(:((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4})))*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/);
+
+    /** Variables to hold regexp pattern for IP Address */
+    public REGX_IP_PATTERN: RegExp = new RegExp(/^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$/);
+
+    /** Variables to hold regexp pattern for Port Number */
+    // tslint:disable-next-line: max-line-length
+    public REGX_PORT_PATTERN: RegExp = new RegExp(/^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$/);
+
+    /** Variables to hold regexp pattern for DPID */
+    public REGX_DPID_PATTERN: RegExp = new RegExp(/^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$/);
+
+    /** Variable to hold regexp pattern for password */
+    // tslint:disable-next-line: max-line-length
+    public REGX_PASSWORD_PATTERN: RegExp = new RegExp(/^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/);
+
+    /** FormGroup instance added to the form @ html @public */
+    public formGroup: FormGroup;
+
+    /** Controls the go to top button on scroll  @public */
+    public showGotoTop: boolean;
+
+    /** Holds OSM Version value @public */
+    public osmVersion: string;
+
+    /** express number for time manupulation -2 */
+    private epochTimeMinus2: number = -2;
+
+    /** express number for time manupulation 1000 */
+    private epochTime1000: number = 1000;
+
+    /** Random string generator length */
+    private randomStringLength: number = 4;
+
+    /** Instance of the rest service @private */
+    private restService: RestService;
+
+    /** Service holds the router information @private */
+    private router: Router;
+
+    /** Check for the root directory @private */
+    private directoryCount: number = 2;
+
+    constructor(restService: RestService, router: Router) {
+        this.restService = restService;
+        this.router = router;
+    }
+
+    /** convert epoch time function @public */
+    public convertEpochTime(unixtimestamp: number): string {
+        const monthsArr: string[] = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+        const date: Date = new Date(unixtimestamp * this.epochTime1000);
+        const year: number = date.getFullYear();
+        const month: string = monthsArr[date.getMonth()];
+        const day: number = date.getDate();
+        const hours: number = date.getHours();
+        const minutes: string = '0' + date.getMinutes();
+        const seconds: string = '0' + date.getSeconds();
+        return month + '-' + day + '-' + year + ' ' + hours + ':' + minutes.substr(this.epochTimeMinus2) + ':'
+            + seconds.substr(this.epochTimeMinus2);
+    }
+
+    /** Download Files function @public */
+    public downloadFiles(shortName: string, binaryData: Blob[], filetype: string): void {
+        const downloadLink: HTMLAnchorElement = document.createElement('a');
+        downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: filetype }));
+        if (shortName !== undefined) {
+            if (window.navigator.msSaveOrOpenBlob) {
+                window.navigator.msSaveBlob(new Blob(binaryData, { type: filetype }), 'OSM_Export_' + shortName + '.tar.gz');
+            } else {
+                downloadLink.setAttribute('download', 'OSM_Export_' + shortName + '.tar.gz');
+                document.body.appendChild(downloadLink);
+                downloadLink.click();
+            }
+        }
+    }
+
+    /** Call this method after delete perform action is completed in the ng-smart-table data @public */
+    public callData(): void {
+        this.dataEvent.emit();
+    }
+
+    /** Generate random string @public */
+    public randomString(): string {
+        const chars: string = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+        let result: string = '';
+        // tslint:disable-next-line:no-increment-decrement
+        for (let randomStringRef: number = this.randomStringLength; randomStringRef > 0; --randomStringRef) {
+            result += chars[Math.floor(Math.random() * chars.length)];
+        }
+        return result;
+    }
+    /** Function to read uploaded file String @public */
+    public async getFileString(files: FileList, fileType: string): Promise<string | ArrayBuffer> {
+        const reader: FileReader = new FileReader();
+        return new Promise<string | ArrayBuffer>((resolve: Function, reject: Function): void => {
+            if (this.vaildataFileInfo(files[0], fileType)) {
+                this.readFileContent(reader, files[0], fileType);
+            } else {
+                reject('typeError');
+            }
+            reader.onload = (): void => {
+                if (reader.result === null) {
+                    reject('contentError');
+                }
+                resolve(reader.result);
+            };
+            reader.onerror = (event: Event): void => {
+                reject('contentError');
+            };
+        });
+    }
+    /** Method to handle tar and tar.gz file for shared YAML file content @public */
+    public async targzFile(packageInfo: PACKAGEINFO): Promise<string | ArrayBuffer> {
+        return new Promise<string | ArrayBuffer>((resolve: Function, reject: Function): void => {
+            const httpOptions: GETAPIURLHEADER = this.getHttpOptions();
+            let apiUrl: string = '';
+            apiUrl = packageInfo.packageType === 'nsd' ? environment.NSDESCRIPTORS_URL + '/' + packageInfo.id + '/nsd_content' :
+                environment.VNFPACKAGES_URL + '/' + packageInfo.id + '/package_content';
+            this.restService.getResource(apiUrl, httpOptions).subscribe((response: ArrayBuffer) => {
+                try {
+                    // tslint:disable-next-line: no-any
+                    const tar: any = new Tar();
+                    const originalInput: Uint8Array = pako.inflate(response, { to: 'Uint8Array' });
+                    untar(originalInput.buffer).then((extractedFiles: TARSETTINGS[]) => {
+                        const getFoldersFiles: {}[] = extractedFiles;
+                        const folderNameStr: string = extractedFiles[0].name;
+                        getFoldersFiles.forEach((value: TARSETTINGS) => {
+                            const getRootFolder: string[] = value.name.split('/');
+                            if (value.name.startsWith(folderNameStr) &&
+                                (value.name.endsWith('.yaml') || value.name.endsWith('.yml')) &&
+                                getRootFolder.length === this.directoryCount) {
+                                tar.append(value.name, packageInfo.descriptor, { type: value.type });
+                            } else {
+                                if (value.type !== 'L') {
+                                    tar.append(value.name, new Uint8Array(value.buffer), { type: value.type });
+                                }
+                            }
+                        });
+                        const out: Uint8Array = tar.out;
+                        const originalOutput: Uint8Array = pako.gzip(out);
+                        resolve(originalOutput.buffer);
+                    }, (err: string) => {
+                        reject('');
+                    });
+                } catch (e) {
+                    reject('');
+                }
+            }, (error: HttpErrorResponse) => {
+                if (error.status === HttpStatus.NOT_FOUND || error.status === HttpStatus.UNAUTHORIZED) {
+                    this.router.navigateByUrl('404', { skipLocationChange: true }).catch();
+                } else {
+                    this.restService.handleError(error, 'get');
+                    reject('');
+                }
+            });
+        });
+    }
+    /** Method to check given string is JSON or not @public */
+    public checkJson(jsonString: string): boolean {
+        jsonString = jsonString.replace(/'/g, '"');
+        try {
+            JSON.parse(jsonString);
+        } catch (e) {
+            return false;
+        }
+        return true;
+    }
+    /** Clean the form before submit @public */
+    public cleanForm(formGroup: FormGroup): void {
+        Object.keys(formGroup.controls).forEach((key: string) => {
+            if ((!isNullOrUndefined((formGroup.get(key) as FormArray | FormGroup).controls)) && key !== 'vimconfig') {
+                // tslint:disable-next-line: no-shadowed-variable
+                for (const { item, index } of (formGroup.get(key).value).map((item: {}, index: number) => ({ item, index }))) {
+                    const newFormGroup: FormGroup = (formGroup.get(key) as FormArray).controls[index] as FormGroup;
+                    this.cleanForm(newFormGroup);
+                }
+            } else if (formGroup.get(key).value !== undefined && formGroup.get(key).value !== null && key !== 'vimconfig') {
+                if (!Array.isArray(formGroup.get(key).value)) {
+                    if (typeof formGroup.get(key).value === 'string') {
+                        formGroup.get(key).setValue(formGroup.get(key).value.trim());
+                    }
+                }
+            } else if (key === 'vimconfig') {
+                const newFormGroup: FormGroup = formGroup.get(key) as FormGroup;
+                this.cleanForm(newFormGroup);
+            }
+        });
+    }
+    /** Method to return the config of pager value for ngSmarttable @public */
+    public paginationPagerConfig(): PAGERSMARTTABLE {
+        return {
+            display: true,
+            perPage: environment.paginationNumber
+        };
+    }
+    /** Method to return the class for the table for ngSmarttable @public */
+    public tableClassConfig(): SMARTTABLECLASS {
+        return {
+            class: 'table list-data'
+        };
+    }
+    /** Method to return all languages name and its code @public */
+    public languageCodeList(): {}[] {
+        return [
+            { code: 'en', language: 'English' },
+            { code: 'es', language: 'Spanish' },
+            { code: 'pt', language: 'Portuguese' },
+            { code: 'de', language: 'German' }
+        ];
+    }
+    /** Fetch OSM Version @public */
+    public fetchOSMVersion(): void {
+        this.restService.getResource(environment.OSM_VERSION_URL).subscribe((res: { version: string }) => {
+            const version: string[] = res.version.split('+');
+            if (!isNullOrUndefined(version[0])) {
+                this.osmVersion = version[0];
+            } else {
+                this.osmVersion = null;
+            }
+        }, (error: ERRORDATA) => {
+            this.osmVersion = null;
+            this.restService.handleError(error, 'get');
+        });
+    }
+    /** Method to validate file extension and size @private */
+    private vaildataFileInfo(fileInfo: File, fileType: string): boolean {
+        const extension: string = fileInfo.name.substring(fileInfo.name.lastIndexOf('.') + 1);
+        const packageSize: number = CONSTANTNUMBER.oneMB * environment.packageSize;
+        if (extension.toLowerCase() === fileType && fileInfo.size <= packageSize) {
+            return true;
+        }
+        return false;
+    }
+    /** Method to read file content based on type @private */
+    private readFileContent(reader: FileReader, fileInfo: File, fileType: string): void {
+        if (fileType === 'gz') {
+            reader.readAsArrayBuffer(fileInfo);
+        } else {
+            reader.readAsText(fileInfo);
+        }
+    }
+    /** Method to handle http options @public */
+    private getHttpOptions(): GETAPIURLHEADER {
+        return {
+            headers: new HttpHeaders({
+                Accept: 'application/gzip, application/json',
+                'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
+            }),
+            responseType: 'arraybuffer'
+        };
+    }
+}