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 vfModuleName : string;
50 isUpdateMode : boolean;
52 constructor(private genericFormService: GenericFormService,
53 private _basicControlGenerator: BasicControlGenerator,
54 private store: NgRedux<AppState>,
55 private http: HttpClient,
56 private _aaiService: AaiService,
57 private _logService: LogService) {
58 this.aaiService = _aaiService;
61 setVFModuleStoreKey = (serviceId: string, vfModuleUuid: string) => {
62 const vfModules = this.store.getState().service.serviceHierarchy[serviceId].vfModules;
63 const vfModulesKeys = Object.keys(vfModules);
64 for(let key of vfModulesKeys){
65 if(vfModules[key].uuid === vfModuleUuid){
66 this.vfModuleName = key;
73 getVfModuleInstance = (serviceId: string, vnfStoreKey: string, UUIDData: Object, isUpdateMode: boolean): VfModuleInstance => {
74 let vfModuleInstance: VfModuleInstance = null;
75 if (isUpdateMode && this.store.getState().service.serviceInstance[serviceId] &&
76 _.has(this.store.getState().service.serviceInstance[serviceId].vnfs, vnfStoreKey) &&
77 _.has(this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules, UUIDData['modelName'])) {
78 vfModuleInstance = Object.assign({},this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules[UUIDData['modelName']][UUIDData['vFModuleStoreKey']]);
80 return vfModuleInstance;
83 extractVfAccordingToVfModuleUuid(serviceId: string, UUIDData: Object): VfModule {
84 const vfModule = this.store.getState().service.serviceHierarchy[serviceId].vfModules[UUIDData['modelName']];
85 this.vfModuleModel = vfModule;
89 getMacroFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
90 this.isUpdateMode = isUpdateMode;
91 this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
92 if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
94 this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
99 const vfModuleInstance = this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode);
100 const vfModuleModel = this.vfModuleModel;
101 const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
102 const vnfModelName: string = vnf.originalName;
103 const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfModelName]);
105 let result: FormControlModel[] = [];
107 if (!_.isNil(vfModuleModel)) {
108 result.push(this.getInstanceName(vfModuleInstance, serviceId, vnfModel.isEcompGeneratedNaming));
109 if (this.vfModuleModel.volumeGroupAllowed) {
110 result.push(this.getVolumeGroupName(vfModuleInstance, serviceId, vnfStoreKey, vfModuleInstance && vfModuleInstance.volumeGroupName, vnfModel.isEcompGeneratedNaming));
113 if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
114 let suppFileInput:FileFormControl = <FileFormControl>(this.getSupplementaryFile(vfModuleInstance));
115 result.push(suppFileInput);
116 result = result.concat(suppFileInput.hiddenFile);
121 getAlaCarteFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
122 this.isUpdateMode = isUpdateMode;
123 this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
124 if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
126 this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
130 const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
131 const vnfModelName: string = vnf.originalName;
132 const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfModelName]);
134 const vfModuleInstance = this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode);
135 let result: FormControlModel[] = [];
136 result.push(this.getInstanceName(vfModuleInstance, serviceId, vnfModel.isEcompGeneratedNaming));
138 if (this.vfModuleModel.volumeGroupAllowed) {
139 result.push(this.getVolumeGroupName(vfModuleInstance, serviceId, vnfStoreKey, this.vfModuleName, vnfModel.isEcompGeneratedNaming));
141 result.push(this.getLcpRegionControl(serviceId, vfModuleInstance, result));
142 result.push(this._basicControlGenerator.getLegacyRegion(vfModuleInstance));
143 result.push(this.getTenantControl(serviceId, vfModuleInstance, result));
144 result.push(this.getRollbackOnFailureControl(vfModuleInstance, result));
145 result.push(this.getSDNCControl(vfModuleInstance, result));
146 if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
147 let suppFileInput:FileFormControl = <FileFormControl>(this.getSupplementaryFile(vfModuleInstance));
148 result.push(suppFileInput);
149 result = result.concat(suppFileInput.hiddenFile);
155 getInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): FormControlModel {
156 let formControlModel:FormControlModel = this._basicControlGenerator.getInstanceNameController(instance, serviceId, isEcompGeneratedNaming, this.vfModuleModel);
157 formControlModel.onBlur = (event, form : FormGroup) => {
158 if(!_.isNil(form.controls['volumeGroupName'])&& event.target.value.length > 0){
159 form.controls['volumeGroupName'].setValue(event.target.value + "_vol");
163 return formControlModel;
166 getDefaultVolumeGroupName(instance: any, vfModuleName: string, isEcompGeneratedNaming: boolean): string {
167 if ((!_.isNil(instance) && instance.volumeGroupName)) {
168 return instance.volumeGroupName;
170 if (isEcompGeneratedNaming) {
173 return this._basicControlGenerator.getDefaultInstanceName(instance, this.vfModuleModel) + "_vol";
176 getVolumeGroupName(instance: any, serviceId: string, vnfStoreKey: string, vfModuleName: string, isEcompGeneratedNaming: boolean): FormControlModel {
177 let validations: ValidatorModel[] = [
178 new ValidatorModel(ValidatorOptions.pattern, 'Instance name may include only alphanumeric characters and underscore.', BasicControlGenerator.INSTANCE_NAME_REG_EX),
179 new ValidatorModel(CustomValidatorOptions.uniqueInstanceNameValidator, 'Volume Group instance name is already in use, please pick another name', [this.store, serviceId, instance && instance.volumeGroupName])
181 // comment out because if not provided vid won't create VG
182 // if (!isEcompGeneratedNaming) {
183 // validations.push(new ValidatorModel(ValidatorOptions.required, 'is required'));
185 return new InputFormControl({
186 controlName: 'volumeGroupName',
187 displayName: 'Volume Group Name',
188 dataTestId: 'volumeGroupName',
189 // placeHolder: (!isEcompGeneratedNaming) ? 'Volume Group Name' : 'Automatically generated when not provided',
190 validations: validations,
191 tooltip : 'When filled, VID will create a Volume Group by this name and associate with this module.\n' +
192 'When empty, the module is created without a Volume Group.',
194 value: this.getDefaultVolumeGroupName(instance, vfModuleName, isEcompGeneratedNaming),
195 onKeypress: (event) => {
196 const pattern:RegExp = BasicControlGenerator.INSTANCE_NAME_REG_EX;
198 if (!pattern.test(event['key'])) {
199 event.preventDefault();
207 getSupplementaryFile(instance: any): FormControlModel {
208 return new FileFormControl({
209 controlName: FormControlNames.SUPPLEMENTARY_FILE,
210 displayName: 'Supplementary Data File (JSON format)',
211 dataTestId: 'SupplementaryFile',
212 placeHolder: 'Choose file',
213 selectedFile: !_.isNil(instance) ? instance.supplementaryFileName: null,
215 acceptedExtentions: "application/json",
216 hiddenFile : [new InputFormControl({
217 controlName: FormControlNames.SUPPLEMENTARY_FILE + "_hidden",
219 validations: [new ValidatorModel(CustomValidatorOptions.isFileTooBig, "File size exceeds 5MB.", [FileUnit.MB, 5])]
221 new InputFormControl({
222 controlName: FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content",
224 validations: [new ValidatorModel(CustomValidatorOptions.isValidJson,
225 "File is invalid, please make sure a legal JSON file is uploaded using name:value pairs.",[]),
226 new ValidatorModel(CustomValidatorOptions.isStringContainTags,
227 "File is invalid, please remove tags <>.",[])],
228 value: !_.isNil(instance) ? (instance.supplementaryFile_hidden_content): null,
231 onDelete : (form : FormGroup) => {
232 form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
233 form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
235 onChange : (files: FileList, form : FormGroup) => {
236 if (files.length > 0) {
237 const file = files.item(0);
238 let reader = new FileReader();
239 reader.onload = function(event) {
240 form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content"].setValue(reader.result);
241 form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden"].setValue(file);
243 reader.readAsText(file);
246 form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
247 form.controls[FormControlNames.SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
253 getTenantControl = (serviceId: string, instance: any, controls: FormControlModel[]): DropdownFormControl => {
254 const service = this.store.getState().service.serviceInstance[serviceId];
255 const globalCustomerId: string = service.globalSubscriberId;
256 const serviceType: string = service.subscriptionServiceType;
257 return new DropdownFormControl({
258 type: FormControlType.DROPDOWN,
259 controlName: FormControlNames.TENANT_ID,
260 displayName: 'Tenant',
261 dataTestId: 'tenant',
262 placeHolder: 'Select Tenant',
264 isDisabled: _.isNil(instance) || _.isNil(instance.lcpCloudRegionId),
265 onInitSelectedField: instance ? ['lcpRegionsTenantsMap', instance.lcpCloudRegionId] : null,
266 value: instance ? instance.tenantId : null,
267 validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
268 onInit: instance ? this._basicControlGenerator.getSubscribeInitResult.bind(
270 this.aaiService.getLcpRegionsAndTenants.bind(this, globalCustomerId, serviceType)) : () => {
275 getLcpRegionControl = (serviceId: string, instance: any, controls: FormControlModel[]): DropdownFormControl => {
276 const service = this.store.getState().service.serviceInstance[serviceId];
277 const globalCustomerId: string = service.globalSubscriberId;
278 const serviceType: string = service.subscriptionServiceType;
279 return new DropdownFormControl({
280 type: FormControlType.DROPDOWN,
281 controlName: 'lcpCloudRegionId',
282 displayName: 'LCP region',
283 dataTestId: 'lcpRegion',
284 placeHolder: 'Select LCP Region',
287 value: instance ? instance.lcpCloudRegionId : null,
288 validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
289 onInitSelectedField: ['lcpRegionList'],
290 onInit: this._basicControlGenerator.getSubscribeInitResult.bind(
292 this._aaiService.getLcpRegionsAndTenants.bind(this, globalCustomerId, serviceType)),
293 onChange: (param: string, form: FormGroup) => {
294 form.controls[FormControlNames.TENANT_ID].enable();
295 form.controls[FormControlNames.TENANT_ID].reset();
296 if (!_.isNil(globalCustomerId) && !_.isNil(serviceType)) {
297 this._basicControlGenerator.getSubscribeResult.bind(this, this._aaiService.getLcpRegionsAndTenants(globalCustomerId, serviceType).subscribe(res => {
298 controls.find(item => item.controlName === FormControlNames.TENANT_ID)['options$'] = res.lcpRegionsTenantsMap[param];
299 if (res.lcpRegionsTenantsMap[param]) {
300 controls.find(item => item.controlName === FormControlNames.TENANT_ID)['hasEmptyOptions'] = res.lcpRegionsTenantsMap[param].length === 0;
305 if (Constants.LegacyRegion.MEGA_REGION.indexOf(param) !== -1) {
306 form.controls['legacyRegion'].enable();
307 controls.find(item => item.controlName === 'legacyRegion').isVisible = true;
310 controls.find(item => item.controlName === 'legacyRegion').isVisible = false;
311 form.controls['legacyRegion'].setValue(null);
312 form.controls['legacyRegion'].reset();
313 form.controls['legacyRegion'].disable();
319 getSDNCControl = (instance: any, controls: FormControlModel[]): CheckboxFormControl => {
320 return new CheckboxFormControl({
321 type: FormControlType.CHECKBOX,
322 controlName: 'sdncPreLoad',
323 displayName: 'SDN-C pre-load',
324 dataTestId: 'sdncPreLoad',
325 value: instance ? instance.sdncPreLoad : false,
326 validations: [new ValidatorModel(ValidatorOptions.required, 'is required')]
330 getRollbackOnFailureControl = (instance: any, controls: FormControlModel[]): DropdownFormControl => {
331 return new DropdownFormControl({
332 type: FormControlType.DROPDOWN,
333 controlName: FormControlNames.ROLLBACK_ON_FAILURE,
334 displayName: 'Rollback on failure',
335 dataTestId: 'rollback',
337 validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
338 value: instance ? instance.rollbackOnFailure : 'true',
339 onInit: this._basicControlGenerator.getSubscribeInitResult.bind(null, this.getRollBackOnFailureOptions)
343 getRollBackOnFailureOptions = (): Observable<SelectOption[]> => {
345 new SelectOption({id: 'true', name: 'Rollback'}),
346 new SelectOption({id: 'false', name: 'Don\'t Rollback'})