1 import {Injectable} from "@angular/core";
 
   2 import {GenericFormService} from "../../generic-form.service";
 
   3 import {AaiService} from "../../../../services/aaiService/aai.service";
 
   4 import {NgRedux} from "@angular-redux/store";
 
   5 import {HttpClient} from "@angular/common/http";
 
   6 import {BasicControlGenerator} from "../basic.control.generator";
 
   7 import * as _ from 'lodash';
 
   8 import {Observable, of} from "rxjs";
 
  11   CustomValidatorOptions,
 
  15 } from "../../../../models/formControlModels/formControl.model";
 
  16 import {LogService} from "../../../../utils/log/log.service";
 
  17 import {AppState} from "../../../../store/reducers";
 
  18 import {FormGroup} from "@angular/forms";
 
  19 import {DropdownFormControl} from "../../../../models/formControlModels/dropdownFormControl.model";
 
  20 import {FormControlType} from "../../../../models/formControlModels/formControlTypes.enum";
 
  21 import {InputFormControl} from "../../../../models/formControlModels/inputFormControl.model";
 
  22 import {SelectOption} from "../../../../models/selectOption";
 
  23 import {VfModuleInstance} from "../../../../models/vfModuleInstance";
 
  24 import {VfModule} from "../../../../models/vfModule";
 
  25 import {VNFModel} from "../../../../models/vnfModel";
 
  26 import {VnfInstance} from "../../../../models/vnfInstance";
 
  27 import {FileFormControl} from "../../../../models/formControlModels/fileFormControl.model";
 
  28 import {CheckboxFormControl} from "../../../../models/formControlModels/checkboxFormControl.model";
 
  29 import {FileUnit} from "../../../formControls/component/file/fileUnit.enum";
 
  30 import {Constants} from "../../../../utils/constants";
 
  33 export enum FormControlNames {
 
  34   INSTANCE_NAME = 'instanceName',
 
  35   VOLUME_GROUP_NAME = 'volumeGroupName',
 
  36   LCPCLOUD_REGION_ID = 'lcpCloudRegionId',
 
  37   LEGACY_REGION = 'legacyRegion',
 
  38   TENANT_ID = 'tenantId',
 
  39   ROLLBACK_ON_FAILURE = 'rollbackOnFailure',
 
  40   SDN_C_PRE_LOAD = 'sdncPreLoad',
 
  41   SUPPLEMENTARY_FILE = 'supplementaryFile'
 
  46 export class VfModuleControlGenerator {
 
  47   aaiService: AaiService;
 
  48   vfModuleModel: VfModule;
 
  49   isUpdateMode : boolean;
 
  51   constructor(private genericFormService: GenericFormService,
 
  52               private _basicControlGenerator: BasicControlGenerator,
 
  53               private store: NgRedux<AppState>,
 
  54               private http: HttpClient,
 
  55               private _aaiService: AaiService,
 
  56               private _logService: LogService) {
 
  57     this.aaiService = _aaiService;
 
  60   setVFModuleStoreKey = (serviceId: string, vfModuleUuid: string) => {
 
  61       const vfModules = this.store.getState().service.serviceHierarchy[serviceId].vfModules;
 
  62       const vfModulesKeys = Object.keys(vfModules);
 
  63       for(let key of  vfModulesKeys){
 
  64         if(vfModules[key].uuid === vfModuleUuid){
 
  71   getVfModuleInstance = (serviceId: string, vnfStoreKey: string, UUIDData: Object, isUpdateMode: boolean): VfModuleInstance => {
 
  72     let vfModuleInstance: VfModuleInstance = null;
 
  73     if (isUpdateMode && this.store.getState().service.serviceInstance[serviceId] &&
 
  74       _.has(this.store.getState().service.serviceInstance[serviceId].vnfs, vnfStoreKey) &&
 
  75       _.has(this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules, UUIDData['modelName'])) {
 
  76        vfModuleInstance = Object.assign({},this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules[UUIDData['modelName']][UUIDData['vFModuleStoreKey']]);
 
  78     return vfModuleInstance;
 
  81   extractVfAccordingToVfModuleUuid(serviceId: string, UUIDData: Object): VfModule {
 
  82     const vfModule = this.store.getState().service.serviceHierarchy[serviceId].vfModules[UUIDData['modelName']];
 
  83     this.vfModuleModel = vfModule;
 
  87   getMacroFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
 
  88     this.isUpdateMode = isUpdateMode;
 
  89     this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
 
  90     if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
 
  92         this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
 
  97     const vfModuleInstance = this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode);
 
  98     const vfModuleModel = this.vfModuleModel;
 
  99     const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
 
 100     const vnfModelName: string = vnf.originalName;
 
 101     const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfModelName]);
 
 103     let result: FormControlModel[] = [];
 
 105     if (!_.isNil(vfModuleModel)) {
 
 106       result = this.pushInstanceAndVGToForm(result, vfModuleInstance, serviceId, vnfModel, false);
 
 108     if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
 
 109       let suppFileInput:FileFormControl = <FileFormControl>(this.getSupplementaryFile(vfModuleInstance));
 
 110       result.push(suppFileInput);
 
 111       result = result.concat(suppFileInput.hiddenFile);
 
 116   pushInstanceAndVGToForm(result: FormControlModel[], vfModuleElement: any, serviceId: string, vnfModel: any, isALaCarte: boolean) :FormControlModel[]{
 
 117     result.push(this.getInstanceName(vfModuleElement, serviceId, vnfModel.isEcompGeneratedNaming));
 
 118     if (this.vfModuleModel.volumeGroupAllowed) {
 
 119       result.push(this.getVolumeGroupData(vfModuleElement, serviceId, vnfModel.isEcompGeneratedNaming, isALaCarte));
 
 124   getAlaCarteFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
 
 125     this.isUpdateMode = isUpdateMode;
 
 126     this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
 
 127     if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
 
 129         this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
 
 133     const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
 
 134     const vnfModelName: string = vnf.originalName;
 
 135     const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfModelName]);
 
 137     const vfModuleInstance = this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode);
 
 138     let result: FormControlModel[] = [];
 
 139     this.pushInstanceAndVGToForm(result, vfModuleInstance, serviceId, vnfModel, true);
 
 140     result.push(this.getLcpRegionControl(serviceId, vfModuleInstance, result));
 
 141     result.push(this._basicControlGenerator.getLegacyRegion(vfModuleInstance));
 
 142     result.push(this.getTenantControl(serviceId, vfModuleInstance, result));
 
 143     result.push(this.getRollbackOnFailureControl(vfModuleInstance, result));
 
 144     result.push(this.getSDNCControl(vfModuleInstance, result));
 
 145     if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
 
 146       let suppFileInput:FileFormControl = <FileFormControl>(this.getSupplementaryFile(vfModuleInstance));
 
 147       result.push(suppFileInput);
 
 148       result = result.concat(suppFileInput.hiddenFile);
 
 154   getInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): FormControlModel {
 
 155     let formControlModel:FormControlModel = this._basicControlGenerator.getInstanceNameController(instance, serviceId, isEcompGeneratedNaming, this.vfModuleModel);
 
 156     formControlModel.onBlur = (event, form : FormGroup) => {
 
 157         if(!_.isNil(form.controls['volumeGroupName'])&& event.target.value.length > 0){
 
 158           form.controls['volumeGroupName'].setValue(event.target.value + "_vol");
 
 162     return formControlModel;
 
 165   getDefaultVolumeGroupName(instance: any, isEcompGeneratedNaming: boolean): string {
 
 166     if ((!_.isNil(instance) && instance.volumeGroupName))  {
 
 167       return instance.volumeGroupName;
 
 169     if (isEcompGeneratedNaming) {
 
 172     return this._basicControlGenerator.getDefaultInstanceName(instance, this.vfModuleModel) + "_vol";
 
 175   getVolumeGroupData(instance: any, serviceId: string, isEcompGeneratedNaming: boolean, isALaCarte: boolean): FormControlModel {
 
 176     let validations: ValidatorModel[] = [
 
 177       new ValidatorModel(ValidatorOptions.pattern, 'Instance name may include only alphanumeric characters and underscore.', BasicControlGenerator.INSTANCE_NAME_REG_EX),
 
 178       new ValidatorModel(CustomValidatorOptions.uniqueInstanceNameValidator, 'Volume Group instance name is already in use, please pick another name', [this.store, serviceId, instance && instance.volumeGroupName])
 
 180     // comment out because if not provided vid won't create VG
 
 181     // if (!isEcompGeneratedNaming)  {
 
 182     //   validations.push(new ValidatorModel(ValidatorOptions.required, 'is required'));
 
 184     return new InputFormControl({
 
 185       controlName: 'volumeGroupName',
 
 186       displayName: 'Volume Group Name',
 
 187       dataTestId: 'volumeGroupName',
 
 188       // placeHolder: (!isEcompGeneratedNaming) ? 'Volume Group Name' : 'Automatically generated when not provided',
 
 189       validations: validations,
 
 190       tooltip : 'When filled, VID will create a Volume Group by this name and associate with this module.\n' +
 
 191                 'When empty, the module is created without a Volume Group.',
 
 192       isVisible: this.shouldVGNameBeVisible(isEcompGeneratedNaming,isALaCarte),
 
 193       value: this.getDefaultVolumeGroupName(instance, isEcompGeneratedNaming),
 
 194       onKeypress: (event) => {
 
 195         const pattern:RegExp = BasicControlGenerator.INSTANCE_NAME_REG_EX;
 
 197           if (!pattern.test(event['key'])) {
 
 198             event.preventDefault();
 
 206   private shouldVGNameBeVisible(isEcompGeneratedNaming: boolean, isALaCarte: boolean) {
 
 207     if((!isALaCarte && !isEcompGeneratedNaming) || isALaCarte){
 
 214   getSupplementaryFile(instance: any): FormControlModel {
 
 215     return new FileFormControl({
 
 216       controlName: FormControlNames.SUPPLEMENTARY_FILE,
 
 217       displayName: 'Supplementary Data File (JSON format)',
 
 218       dataTestId: 'SupplementaryFile',
 
 219       placeHolder: 'Choose file',
 
 220       selectedFile:  !_.isNil(instance) ? instance.supplementaryFileName: null,
 
 222       acceptedExtentions: "application/json",
 
 223       hiddenFile : [new InputFormControl({
 
 224         controlName: FormControlNames.SUPPLEMENTARY_FILE + "_hidden",
 
 226         validations: [new ValidatorModel(CustomValidatorOptions.isFileTooBig, "File size exceeds 5MB.", [FileUnit.MB, 5])]
 
 228         new InputFormControl({
 
 229           controlName: FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content",
 
 231           validations: [new ValidatorModel(CustomValidatorOptions.isValidJson,
 
 232             "File is invalid, please make sure a legal JSON file is uploaded using name:value pairs.",[]),
 
 233             new ValidatorModel(CustomValidatorOptions.isStringContainTags,
 
 234               "File is invalid, please remove tags <>.",[])],
 
 235           value: !_.isNil(instance) ? (instance.supplementaryFile_hidden_content): null,
 
 238       onDelete : (form : FormGroup) => {
 
 239         form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
 
 240         form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
 
 242       onChange : (files: FileList, form : FormGroup)  => {
 
 243         if (files.length > 0) {
 
 244           const file = files.item(0);
 
 245           let reader = new FileReader();
 
 246           reader.onload = function(event) {
 
 247             form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content"].setValue(reader.result);
 
 248             form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden"].setValue(file);
 
 250           reader.readAsText(file);
 
 253           form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
 
 254           form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
 
 260   getTenantControl = (serviceId: string, instance: any, controls: FormControlModel[]): DropdownFormControl => {
 
 261     const service = this.store.getState().service.serviceInstance[serviceId];
 
 262     const globalCustomerId: string = service.globalSubscriberId;
 
 263     const serviceType: string = service.subscriptionServiceType;
 
 264     return new DropdownFormControl({
 
 265       type: FormControlType.DROPDOWN,
 
 266       controlName: FormControlNames.TENANT_ID,
 
 267       displayName: 'Tenant',
 
 268       dataTestId: 'tenant',
 
 269       placeHolder: 'Select Tenant',
 
 271       isDisabled: _.isNil(instance) || _.isNil(instance.lcpCloudRegionId),
 
 272       onInitSelectedField: instance ? ['lcpRegionsTenantsMap', instance.lcpCloudRegionId] : null,
 
 273       value: instance ? instance.tenantId : null,
 
 274       validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
 
 275       onInit: instance ? this._basicControlGenerator.getSubscribeInitResult.bind(
 
 277         this.aaiService.getLcpRegionsAndTenants.bind(this, globalCustomerId, serviceType)) : () => {
 
 282   getLcpRegionControl = (serviceId: string, instance: any, controls: FormControlModel[]): DropdownFormControl => {
 
 283     const service = this.store.getState().service.serviceInstance[serviceId];
 
 284     const globalCustomerId: string = service.globalSubscriberId;
 
 285     const serviceType: string = service.subscriptionServiceType;
 
 286     return new DropdownFormControl({
 
 287       type: FormControlType.DROPDOWN,
 
 288       controlName: 'lcpCloudRegionId',
 
 289       displayName: 'LCP region',
 
 290       dataTestId: 'lcpRegion',
 
 291       placeHolder: 'Select LCP Region',
 
 294       value: instance ? instance.lcpCloudRegionId : null,
 
 295       validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
 
 296       onInitSelectedField: ['lcpRegionList'],
 
 297       onInit: this._basicControlGenerator.getSubscribeInitResult.bind(
 
 299         this._aaiService.getLcpRegionsAndTenants.bind(this, globalCustomerId, serviceType)),
 
 300       onChange: (param: string, form: FormGroup) => {
 
 301         form.controls[FormControlNames.TENANT_ID].enable();
 
 302         form.controls[FormControlNames.TENANT_ID].reset();
 
 303         if (!_.isNil(globalCustomerId) && !_.isNil(serviceType)) {
 
 304           this._basicControlGenerator.getSubscribeResult.bind(this, this._aaiService.getLcpRegionsAndTenants(globalCustomerId, serviceType).subscribe(res => {
 
 305             controls.find(item => item.controlName === FormControlNames.TENANT_ID)['options$'] = res.lcpRegionsTenantsMap[param];
 
 306             if (res.lcpRegionsTenantsMap[param]) {
 
 307               controls.find(item => item.controlName === FormControlNames.TENANT_ID)['hasEmptyOptions'] = res.lcpRegionsTenantsMap[param].length === 0;
 
 312         if (Constants.LegacyRegion.MEGA_REGION.indexOf(param) !== -1) {
 
 313           form.controls['legacyRegion'].enable();
 
 314           controls.find(item => item.controlName === 'legacyRegion').isVisible = true;
 
 317           controls.find(item => item.controlName === 'legacyRegion').isVisible = false;
 
 318           form.controls['legacyRegion'].setValue(null);
 
 319           form.controls['legacyRegion'].reset();
 
 320           form.controls['legacyRegion'].disable();
 
 326   getSDNCControl = (instance: any, controls: FormControlModel[]): CheckboxFormControl => {
 
 327     return new CheckboxFormControl({
 
 328       type: FormControlType.CHECKBOX,
 
 329       controlName: 'sdncPreLoad',
 
 330       displayName: 'SDN-C pre-load',
 
 331       dataTestId: 'sdncPreLoad',
 
 332       value: instance ? instance.sdncPreLoad : false,
 
 333       validations: [new ValidatorModel(ValidatorOptions.required, 'is required')]
 
 337   getRollbackOnFailureControl = (instance: any, controls: FormControlModel[]): DropdownFormControl => {
 
 338     return new DropdownFormControl({
 
 339       type: FormControlType.DROPDOWN,
 
 340       controlName: FormControlNames.ROLLBACK_ON_FAILURE,
 
 341       displayName: 'Rollback on failure',
 
 342       dataTestId: 'rollback',
 
 344       validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
 
 345       value: instance ? instance.rollbackOnFailure : 'true',
 
 346       onInit: this._basicControlGenerator.getSubscribeInitResult.bind(null, this.getRollBackOnFailureOptions)
 
 350   getRollBackOnFailureOptions = (): Observable<SelectOption[]> => {
 
 352       new SelectOption({id: 'true', name: 'Rollback'}),
 
 353       new SelectOption({id: 'false', name: 'Don\'t Rollback'})