blob: 48fbb17e780a6a4bde505c5826479e08e416dbe5 [file] [log] [blame]
/*
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 { TranslateService } from '@ngx-translate/core';
import { CONSTANTNUMBER, ERRORDATA, FILESETTINGS, 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}).*$/);
/** Variables to hold maxlength for the description @public */
public MAX_LENGTH_DESCRIPTION: number = 500;
/** Variables to hold maxlength for the name @public */
public MAX_LENGTH_NAME: number = 50;
/** 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;
/** Random color string generator length @private */
private colorStringLength: number = 256;
/** Check for the root directory @private */
private directoryCount: number = 2;
/** Contains tranlsate instance @private */
private translateService: TranslateService;
constructor(restService: RestService, router: Router, translateService: TranslateService) {
this.restService = restService;
this.router = router;
this.translateService = translateService;
}
/** convert epoch time function @public */
public convertEpochTime(unixtimestamp: number): string {
if (!isNullOrUndefined(unixtimestamp)) {
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);
}
return this.translateService.instant('NODATE');
}
/** 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 fileValueObj: FILESETTINGS = this.createFileValueObject(value);
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, fileValueObj);
} else {
if (value.type !== 'L') {
tar.append(value.name, new Uint8Array(value.buffer), fileValueObj);
}
}
});
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 return the file information @public */
public createFileValueObject(value: TARSETTINGS): FILESETTINGS {
return {
type: value.type,
linkname: value.linkname,
owner: value.uname,
group: value.gname
};
}
/** 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, formName?: String): void {
Object.keys(formGroup.controls).forEach((key: string) => {
if ((!isNullOrUndefined((formGroup.get(key) as FormArray | FormGroup).controls)) && key !== 'config') {
// 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 !== 'config') {
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 === 'config' && formName === 'vim') {
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');
});
}
/** Random RGB color code generator @public */
public generateColor(): string {
const x: number = Math.floor(Math.random() * this.colorStringLength);
const y: number = Math.floor(Math.random() * this.colorStringLength);
const z: number = Math.floor(Math.random() * this.colorStringLength);
return 'rgb(' + x + ',' + y + ',' + z + ')';
}
/** Add custom name/tag to the dropdown @public */
public addCustomTag(tag: string): string {
return tag;
}
/** Fetch file extension @public */
public fetchFileExtension(fileInfo: FileList): string {
return fileInfo[0].name.substring(fileInfo[0].name.lastIndexOf('.') + 1);
}
/** 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 (fileType === 'yaml' && (extension.toLowerCase() === 'yaml' || extension.toLowerCase() === 'yml')
&& fileInfo.size <= packageSize) {
return true;
} else 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'
};
}
}