From 1f2a2947990034b9162d386884f1e79892a87976 Mon Sep 17 00:00:00 2001 From: Yoav Schneiderman Date: Mon, 9 Dec 2019 16:42:21 +0200 Subject: Adding unlimited max value to VNF, NETWORK Issue-ID: VID-726 Signed-off-by: Yoav Schneiderman Change-Id: I0c3d503c8e4f6cb14081de8f6a619a67eee080b7 Signed-off-by: Yoav Schneiderman --- .../integration/iFrames/drawingBoard.e2e.ts | 1 + .../iFrames/viewOnlyDrawingBoard.e2e.ts | 2 +- .../jsonBuilders/mocks/jsons/flags.cypress.json | 1 + .../duplicate/duplicate.service.spec.ts | 17 +- .../duplicate/duplicate.service.ts | 108 +++++----- .../models/network/network.model.info.spec.ts | 232 +++++++++++---------- .../models/network/network.model.info.ts | 8 +- .../models/vfModule/vfModule.model.info.spec.ts | 13 +- .../models/vfModule/vfModule.model.info.ts | 2 +- .../models/vnf/vnf.model.info.spec.ts | 11 +- .../objectsToTree/models/vnf/vnf.model.info.ts | 24 ++- .../objectsToTree/models/vrf/vrf.model.info.ts | 4 +- .../objectToModelTree/objectToModelTree.service.ts | 53 +++-- .../objectsToTree/objectToTree.service.ts | 8 +- .../objectsToTree/shared.tree.service.ts | 11 + .../genericFormServices/basic.popup.service.ts | 6 +- .../src/app/shared/models/networkModel.ts | 13 +- .../src/app/shared/models/vnfModel.ts | 13 +- .../services/featureFlag/feature-flags.service.ts | 8 + vid-webpack-master/src/app/shared/utils/utils.ts | 8 + 20 files changed, 324 insertions(+), 219 deletions(-) (limited to 'vid-webpack-master') diff --git a/vid-webpack-master/cypress/integration/iFrames/drawingBoard.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/drawingBoard.e2e.ts index 0049a427f..b678702ff 100644 --- a/vid-webpack-master/cypress/integration/iFrames/drawingBoard.e2e.ts +++ b/vid-webpack-master/cypress/integration/iFrames/drawingBoard.e2e.ts @@ -584,6 +584,7 @@ describe('Drawing board', function () { "FLAG_SERVICE_MODEL_CACHE": true, "FLAG_1906_COMPONENT_INFO" : false, "FLAG_2002_VNF_PLATFORM_MULTI_SELECT" : false, + "FLAG_2002_UNLIMITED_MAX" : true }, "type": "[FLAGS] Update" }, diff --git a/vid-webpack-master/cypress/integration/iFrames/viewOnlyDrawingBoard.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/viewOnlyDrawingBoard.e2e.ts index 688d42e94..d77460a69 100644 --- a/vid-webpack-master/cypress/integration/iFrames/viewOnlyDrawingBoard.e2e.ts +++ b/vid-webpack-master/cypress/integration/iFrames/viewOnlyDrawingBoard.e2e.ts @@ -331,7 +331,7 @@ describe('View only drawing board', function () { ['Model version', '2.0'], ['Model customization ID', '91415b44-753d-494c-926a-456a9172bbb9'], ['Min instances', '0'], - ['Max instances', '1'] + //['Max instances', '1'] ]; const extraLabelsAndValuesForInstance = [['Instance type', 'VNF2_INSTANCE_TYPE'],['In maintenance','true'], ['Instance ID', 'VNF2_INSTANCE_ID']]; testComponentInfoByType('node-VF_vGeraldine 0', labelsAndValuesForModel,'VNF INFO', diff --git a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json b/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json index 5e92e4f4b..531bad3b4 100644 --- a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json +++ b/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json @@ -22,5 +22,6 @@ "FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER": true, "FLAG_2004_INSTANTIATION_STATUS_FILTER": true, "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP" : false, + "FLAG_2002_UNLIMITED_MAX" : true, "FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE": true } diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.spec.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.spec.ts index 3483885b5..50bfa936e 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.spec.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.spec.ts @@ -3,9 +3,10 @@ import {LogService} from '../../../shared/utils/log/log.service'; import {NgRedux} from '@angular-redux/store'; import {ITreeNode} from "angular-tree-component/dist/defs/api"; import {SdcUiServices} from "onap-ui-angular"; -import {IModalConfig} from "onap-ui-angular/dist/components/common"; +import {IModalConfig} from 'onap-ui-angular/dist/components/common'; import {AppState} from "../../../shared/store/reducers"; import {getTestBed, TestBed} from "@angular/core/testing"; +import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service"; class MockAppStore { getState(){ @@ -52,15 +53,23 @@ class MockAppStore { class MockModalService {} +class MockFeatureFlagsService extends FeatureFlagsService{ + getAllFlags(): { [p: string]: boolean } { + return {}; + } +} + describe('Drawing board tree service', () => { let injector; let service: DuplicateService; let store : NgRedux; + let featureFlagsService : FeatureFlagsService; beforeAll(done => (async () => { TestBed.configureTestingModule({ providers : [ DuplicateService, LogService, + {provide: FeatureFlagsService, useClass: MockFeatureFlagsService}, {provide: NgRedux, useClass: MockAppStore}, {provide: SdcUiServices.ModalService, useClass: MockModalService} ] @@ -70,6 +79,7 @@ describe('Drawing board tree service', () => { injector = getTestBed(); service = injector.get(DuplicateService); store = injector.get(NgRedux); + featureFlagsService = injector.get(FeatureFlagsService); })().then(done).catch(done.fail)); @@ -417,6 +427,11 @@ describe('Drawing board tree service', () => { } } + } + }, + global : { + flags : { + } } } diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.ts index 5fb5f0b15..847790de9 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/duplicate/duplicate.service.ts @@ -11,15 +11,18 @@ import {TypeNodeInformation} from "../typeNodeInformation.model"; import {SdcUiCommon, SdcUiServices} from "onap-ui-angular"; import {changeInstanceCounter, duplicateBulkInstances} from "../../../shared/storeUtil/utils/general/general.actions"; import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config"; +import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service"; +import {Utils} from "../../../shared/utils/utils"; @Injectable() export class DuplicateService { - constructor(private _logService : LogService, private _store: NgRedux, modalService: SdcUiServices.ModalService) { + constructor(private _logService: LogService, private _store: NgRedux, modalService: SdcUiServices.ModalService) { this.modalService = modalService; } - numberOfDuplicates:number; + numberOfDuplicates: number; + setNumberOfDuplicates(numberOfDuplicates: number) { this.numberOfDuplicates = numberOfDuplicates; } @@ -30,10 +33,9 @@ export class DuplicateService { storeKey: string = null; padding = '0000'; modalService: SdcUiServices.ModalService; - store : NgRedux; - existingNames : {[key: string] : any}; - currentNode : ITreeNode = null; - + store: NgRedux; + existingNames: { [key: string]: any }; + currentNode: ITreeNode = null; canDuplicate(node: ITreeNode): boolean { @@ -41,25 +43,31 @@ export class DuplicateService { return node.data.type === 'VF' || node.data.type === 'VL'; } - isEnabled(node: ITreeNode, store: NgRedux, serviceId : string): boolean { - if(!_.isNil(node) && !_.isNil(node.data.menuActions['duplicate'])){ - if(this.hasMissingData(node)) return false; - const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node); - const max : number = store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][node.data.modelName].properties['max_instances'] || 1; + isEnabled(node: ITreeNode, store: NgRedux, serviceId: string): boolean { + if (!_.isNil(node) && !_.isNil(node.data.menuActions['duplicate'])) { + if (this.hasMissingData(node)) return false; + const typeNodeInformation: TypeNodeInformation = new TypeNodeInformation(node); + const flags = FeatureFlagsService.getAllFlags(store); + const currentExisting: number = store.getState().service.serviceInstance[serviceId][typeNodeInformation.existingMappingCounterName][node.data.modelUniqueId]; + const maxInstances = Utils.getMaxFirstLevel(store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][node.data.modelName].properties, flags); + if (_.isNil(maxInstances)) { + return true; + } else { + return maxInstances - currentExisting > 0; + } - return max - currentExisting > 0; - }else { + } else { return false; } } - hasMissingData(node : ITreeNode): boolean { - if(!_.isNil(node)){ - if(node.data.missingData) return true; - if(!_.isNil(node.data.children)){ - for(let child of node.data.children) { - if(child.missingData){ + hasMissingData(node: ITreeNode): boolean { + if (!_.isNil(node)) { + if (node.data.missingData) return true; + if (!_.isNil(node.data.children)) { + for (let child of node.data.children) { + if (child.missingData) { return true; } } @@ -69,16 +77,22 @@ export class DuplicateService { return false; } - getRemainsInstance(modelId : string, modelName : string, serviceId : string, store: NgRedux, node : ITreeNode) : number { - const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node); - const properties = store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][modelName].properties; - const currentExisting : number = store.getState().service.serviceInstance[serviceId][typeNodeInformation.existingMappingCounterName][modelId]; - return (!_.isNil(properties) && !_.isNil(properties['max_instances'])) ? properties['max_instances'] - currentExisting : null; + getRemainsInstance(modelId: string, modelName: string, serviceId: string, store: NgRedux, node: ITreeNode): number { + const typeNodeInformation: TypeNodeInformation = new TypeNodeInformation(node); + const properties = store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][modelName].properties; + const currentExisting: number = store.getState().service.serviceInstance[serviceId][typeNodeInformation.existingMappingCounterName][modelId]; + + const flags = FeatureFlagsService.getAllFlags(store); + const maxInstances = Utils.getMaxFirstLevel(properties, flags); + if (_.isNil(maxInstances)) { + return 10; + } else { + return maxInstances - currentExisting; + } } - - openDuplicateModal(currentServiceId: string, currentUuid: string, currentId: string, storeKey : string, numberOfDuplicate: number, _store : NgRedux, node: ITreeNode): IModalConfig { + openDuplicateModal(currentServiceId: string, currentUuid: string, currentId: string, storeKey: string, numberOfDuplicate: number, _store: NgRedux, node: ITreeNode): IModalConfig { this.currentInstanceId = currentId; this.currentServiceId = currentServiceId; this.maxNumberOfDuplicate = this.getRemainsInstance(currentUuid, currentId, currentServiceId, _store, node); @@ -87,7 +101,7 @@ export class DuplicateService { this.currentNode = node; - return { + return { size: SdcUiCommon.ModalSize.medium, title: 'Duplicate Node', type: SdcUiCommon.ModalType.custom, @@ -98,12 +112,12 @@ export class DuplicateService { }; } - duplicate(node : ITreeNode): void { - const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node); + duplicate(node: ITreeNode): void { + const typeNodeInformation: TypeNodeInformation = new TypeNodeInformation(node); this.existingNames = this.store.getState().service.serviceInstance[this.currentServiceId].existingNames; - const toClone = this.store.getState().service.serviceInstance[this.currentServiceId][typeNodeInformation.hierarchyName][this.storeKey]; + const toClone = this.store.getState().service.serviceInstance[this.currentServiceId][typeNodeInformation.hierarchyName][this.storeKey]; let newObjects = {}; - for(let i = 0; i < this.numberOfDuplicates; i++) { + for (let i = 0; i < this.numberOfDuplicates; i++) { const uniqueStoreKey = this.generateUniqueStoreKey(this.currentServiceId, this.currentInstanceId, this.store.getState().service.serviceInstance[this.currentServiceId][typeNodeInformation.hierarchyName], newObjects); const clone = this.cloneVnf(toClone, this.currentInstanceId); newObjects[uniqueStoreKey] = clone; @@ -114,12 +128,12 @@ export class DuplicateService { } - cloneVnf(vnf : VnfInstance, originalName: string): VnfInstance { - let newUniqueVnf : VnfInstance = _.cloneDeep(vnf); + cloneVnf(vnf: VnfInstance, originalName: string): VnfInstance { + let newUniqueVnf: VnfInstance = _.cloneDeep(vnf); newUniqueVnf.originalName = originalName; newUniqueVnf.trackById = DefaultDataGeneratorService.createRandomTrackById(); - if (!_.isNil(vnf.instanceName)){ + if (!_.isNil(vnf.instanceName)) { newUniqueVnf.instanceName = this.ensureUniqueNameOrGenerateOne(vnf.instanceName); } @@ -127,10 +141,10 @@ export class DuplicateService { const vfModuleModel: VfModuleMap = vnf.vfModules[vf_module_model_name]; for (let vfModule in vfModuleModel) { newUniqueVnf.vfModules[vf_module_model_name][vfModule].trackById = DefaultDataGeneratorService.createRandomTrackById(); - if (!_.isNil(vfModuleModel[vfModule].instanceName)){ + if (!_.isNil(vfModuleModel[vfModule].instanceName)) { newUniqueVnf.vfModules[vf_module_model_name][vfModule].instanceName = this.ensureUniqueNameOrGenerateOne(vfModuleModel[vfModule].instanceName); } - if (!_.isNil(vfModuleModel[vfModule].volumeGroupName)){ + if (!_.isNil(vfModuleModel[vfModule].volumeGroupName)) { newUniqueVnf.vfModules[vf_module_model_name][vfModule].volumeGroupName = this.ensureUniqueNameOrGenerateOne(vfModuleModel[vfModule].volumeGroupName); } } @@ -138,7 +152,7 @@ export class DuplicateService { return newUniqueVnf; } - ensureUniqueNameOrGenerateOne(instanceName){ + ensureUniqueNameOrGenerateOne(instanceName) { let uniqueInstanceName = instanceName; if (this.isAlreadyExists(instanceName, this.existingNames)) { uniqueInstanceName = this.generateNextUniqueName(instanceName, this.existingNames); @@ -148,33 +162,33 @@ export class DuplicateService { } - isAlreadyExists(name : string, existingNames : {[key: string] : any}){ + isAlreadyExists(name: string, existingNames: { [key: string]: any }) { return _.has(existingNames, name.toLowerCase()); } - generateNextUniqueName(name : string, existingNames : {[key: string] : any}) :string{ + generateNextUniqueName(name: string, existingNames: { [key: string]: any }): string { let suffix = "000"; let counter = 1; - if (name.match(/^.*_[\d]{3}$/)){ + if (name.match(/^.*_[\d]{3}$/)) { name = name.substring(0, name.length - 4); } - while(true){ - let paddingNumber : string = this.getNumberAsPaddingString(counter, suffix); + while (true) { + let paddingNumber: string = this.getNumberAsPaddingString(counter, suffix); let candidateUniqueName = name + '_' + paddingNumber; - if(!this.isAlreadyExists(candidateUniqueName, existingNames)){ + if (!this.isAlreadyExists(candidateUniqueName, existingNames)) { return candidateUniqueName; } counter++; } } - generateUniqueStoreKey(serviceId : string, objectName : string, existing : any, newObjects: any) : string { + generateUniqueStoreKey(serviceId: string, objectName: string, existing: any, newObjects: any): string { let counter = 1; - while(true){ - let paddingNumber : string = this.getNumberAsPaddingString(counter, this.padding); + while (true) { + let paddingNumber: string = this.getNumberAsPaddingString(counter, this.padding); const name = objectName + ':' + paddingNumber; - if(_.isNil(existing[name]) && _.isNil(newObjects[name])){ + if (_.isNil(existing[name]) && _.isNil(newObjects[name])) { return name; } counter++; diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.spec.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.spec.ts index 10c13661f..089f812a7 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.spec.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.spec.ts @@ -12,6 +12,7 @@ import {DrawingBoardModes} from "../../../drawing-board.modes"; import {IframeService} from "../../../../../shared/utils/iframe.service"; import {DuplicateService} from "../../../duplicate/duplicate.service"; import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component"; +import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service"; class MockAppStore { getState() { @@ -19,27 +20,27 @@ class MockAppStore { global: { 'drawingBoardStatus': DrawingBoardModes.CREATE }, - service : { - serviceHierarchy : { - 'servicedId' : { - 'networks' : { - 'networkName' : { - 'properties' : { - 'max_instances' : 1 + service: { + serviceHierarchy: { + 'servicedId': { + 'networks': { + 'networkName': { + 'properties': { + 'max_instances': 1 } } } } }, - serviceInstance : { - 'servicedId' : { - 'existingNetworksCounterMap' : { - 'networkId' : 1 + serviceInstance: { + 'servicedId': { + 'existingNetworksCounterMap': { + 'networkId': 1 }, - 'networks' : { - 'networkName' :{ + 'networks': { + 'networkName': { 'action': 'Create', - 'originalName' : 'networkName' + 'originalName': 'networkName' } } } @@ -48,15 +49,24 @@ class MockAppStore { } } } + +class MockFeatureFlagsService extends FeatureFlagsService { + getAllFlags(): { [p: string]: boolean } { + return {}; + } +} + + describe('Network Model Info', () => { let injector; - let _dynamicInputsService : DynamicInputsService; - let _sharedTreeService : SharedTreeService; + let _dynamicInputsService: DynamicInputsService; + let _sharedTreeService: SharedTreeService; let networkModel: NetworkModelInfo; - let _dialogService : DialogService; - let _networkPopupService : NetworkPopupService; - let _duplicateService : DuplicateService; - let _iframeService : IframeService; + let _dialogService: DialogService; + let _networkPopupService: NetworkPopupService; + let _duplicateService: DuplicateService; + let _iframeService: IframeService; + let _featureFlagsService: FeatureFlagsService; beforeAll(done => (async () => { TestBed.configureTestingModule({ @@ -69,13 +79,16 @@ describe('Network Model Info', () => { IframeService, DuplicateService, {provide: NgRedux, useClass: MockAppStore}, + {provide: FeatureFlagsService, useClass: MockFeatureFlagsService}, MockNgRedux] }); await TestBed.compileComponents(); injector = getTestBed(); _sharedTreeService = injector.get(SharedTreeService); - networkModel = new NetworkModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _networkPopupService, _duplicateService, null, _iframeService, MockNgRedux.getInstance()); + _featureFlagsService = injector.get(FeatureFlagsService); + + networkModel = new NetworkModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _networkPopupService, _duplicateService, null, _iframeService, _featureFlagsService, MockNgRedux.getInstance()); })().then(done).catch(done.fail)); test('NetworkModelInfo should be defined', () => { @@ -137,39 +150,37 @@ describe('Network Model Info', () => { expect(model.type).toEqual('VL'); }); - test('showNodeIcons should return false if reachLimit of max', ()=>{ - let serviceId : string = 'servicedId'; + test('showNodeIcons should return false if reachLimit of max', () => { + let serviceId: string = 'servicedId'; let node = { - data : { - id : 'networkId', - name : 'networkName', - modelCustomizationId : 'modelCustomizationId' + data: { + id: 'networkId', + name: 'networkName', + modelCustomizationId: 'modelCustomizationId' } }; jest.spyOn(_sharedTreeService, 'getExistingInstancesWithDeleteMode').mockReturnValue(0); jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ - global : {}, - service : { - serviceHierarchy : { - 'servicedId' : { - 'networks' : { - 'networkName' : { - 'properties' : { - 'max_instances' : 1 + global: {}, + service: { + serviceHierarchy: { + 'servicedId': { + 'networks': { + 'networkName': { + 'properties': { + 'max_instances': 1 } } } } }, - serviceInstance : { - 'servicedId' : { - 'existingNetworksCounterMap' : { - 'modelCustomizationId' : 1 + serviceInstance: { + 'servicedId': { + 'existingNetworksCounterMap': { + 'modelCustomizationId': 1 }, - 'networks' : { - 'networkName' :{ - - } + 'networks': { + 'networkName': {} } } } @@ -177,41 +188,39 @@ describe('Network Model Info', () => { }); let result = networkModel.showNodeIcons(node, serviceId); - expect(result).toEqual(new AvailableNodeIcons(true , false)); + expect(result).toEqual(new AvailableNodeIcons(true, false)); }); - test('showNodeIcons should return true if not reachLimit of max', ()=>{ - let serviceId : string = 'servicedId'; + test('showNodeIcons should return true if not reachLimit of max', () => { + let serviceId: string = 'servicedId'; let node = { - data : { - id : 'networkId', - name : 'networkName' + data: { + id: 'networkId', + name: 'networkName' } }; jest.spyOn(_sharedTreeService, 'getExistingInstancesWithDeleteMode').mockReturnValue(0); jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ - global : {}, - service : { - serviceHierarchy : { - 'servicedId' : { - 'networks' : { - 'networkName' : { - 'properties' : { - 'max_instances' : 2 + global: {}, + service: { + serviceHierarchy: { + 'servicedId': { + 'networks': { + 'networkName': { + 'properties': { + 'max_instances': 2 } } } } }, - serviceInstance : { - 'servicedId' : { - 'existingNetworksCounterMap' : { - 'networkId' : 1 + serviceInstance: { + 'servicedId': { + 'existingNetworksCounterMap': { + 'networkId': 1 }, - 'networks' : { - 'networkName' :{ - - } + 'networks': { + 'networkName': {} } } } @@ -219,34 +228,34 @@ describe('Network Model Info', () => { }); let result = networkModel.showNodeIcons(node, serviceId); - expect(result).toEqual(new AvailableNodeIcons(true , false)); + expect(result).toEqual(new AvailableNodeIcons(true, false)); }); - test('getNodeCount should return number of nodes', ()=>{ - let serviceId : string = 'servicedId'; + test('getNodeCount should return number of nodes', () => { + let serviceId: string = 'servicedId'; jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ - global : {}, - service : { - serviceHierarchy : { - 'servicedId' : { - 'networks' : { - 'networkName' : { - 'properties' : { - 'max_instances' : 1 + global: {}, + service: { + serviceHierarchy: { + 'servicedId': { + 'networks': { + 'networkName': { + 'properties': { + 'max_instances': 1 } } } } }, - serviceInstance : { - 'servicedId' : { - 'existingNetworksCounterMap' : { - 'modelCustomizationId' : 1 + serviceInstance: { + 'servicedId': { + 'existingNetworksCounterMap': { + 'modelCustomizationId': 1 }, - 'networks' : { - 'networkName' :{ + 'networks': { + 'networkName': { 'action': 'Create', - 'originalName' : 'networkName' + 'originalName': 'networkName' } } } @@ -255,24 +264,24 @@ describe('Network Model Info', () => { }); let node = { - data : { - id : 'networkId', - name : 'networkName', + data: { + id: 'networkId', + name: 'networkName', action: 'Create', - modelCustomizationId : "modelCustomizationId", + modelCustomizationId: "modelCustomizationId", modelUniqueId: "modelCustomizationId" } }; - let result = networkModel.getNodeCount(node , serviceId); + let result = networkModel.getNodeCount(node, serviceId); expect(result).toEqual(1); node.data.modelCustomizationId = 'networkId_notExist'; node.data.modelUniqueId = 'networkId_notExist'; - result = networkModel.getNodeCount(node , serviceId); + result = networkModel.getNodeCount(node, serviceId); expect(result).toEqual(0); }); - test('getMenuAction: showAuditInfoNetwork', ()=>{ + test('getMenuAction: showAuditInfoNetwork', () => { jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({ global: { @@ -281,7 +290,7 @@ describe('Network Model Info', () => { }); jest.spyOn(_sharedTreeService, 'isRetryMode').mockReturnValue(true); let node = { - data : { + data: { "modelId": "6b528779-44a3-4472-bdff-9cd15ec93450", "action": "Create", "isFailed": true, @@ -300,7 +309,7 @@ describe('Network Model Info', () => { test('Info for network should be correct', () => { const model = getNetworkModel(); const instance = getNetworkInstance(); - let actualNetworkInfo = networkModel.getInfo(model,instance); + let actualNetworkInfo = networkModel.getInfo(model, instance); let expectedNetworkInfo = [ ModelInformationItem.createInstance('Network role', "network role 1, network role 2"), ModelInformationItem.createInstance("Route target id", null), @@ -309,26 +318,27 @@ describe('Network Model Info', () => { expect(actualNetworkInfo).toEqual(expectedNetworkInfo); }); - function getNetworkModel(){ + function getNetworkModel() { return { - "customizationUuid":"94fdd893-4a36-4d70-b16a-ec29c54c184f", - "name":"ExtVL", - "version":"37.0", - "description":"ECOMP generic virtual link (network) base type for all other service-level and global networks", - "uuid":"ddc3f20c-08b5-40fd-af72-c6d14636b986", - "invariantUuid":"379f816b-a7aa-422f-be30-17114ff50b7c", - "max":1, - "min":0, - "isEcompGeneratedNaming":false, - "type":"VL", - "modelCustomizationName":"ExtVL 0", - "roles":["network role 1"," network role 2"], - "properties":{ - "network_role":"network role 1, network role 2", + "customizationUuid": "94fdd893-4a36-4d70-b16a-ec29c54c184f", + "name": "ExtVL", + "version": "37.0", + "description": "ECOMP generic virtual link (network) base type for all other service-level and global networks", + "uuid": "ddc3f20c-08b5-40fd-af72-c6d14636b986", + "invariantUuid": "379f816b-a7aa-422f-be30-17114ff50b7c", + "max": 1, + "min": 0, + "isEcompGeneratedNaming": false, + "type": "VL", + "modelCustomizationName": "ExtVL 0", + "roles": ["network role 1", " network role 2"], + "properties": { + "network_role": "network role 1, network role 2", "network_assignments": "{is_external_network=false, ipv4_subnet_default_assignment={min_subnets_count=1}, ecomp_generated_network_assignment=false, ipv6_subnet_default_assignment={min_subnets_count=1}}", - "exVL_naming":"{ecomp_generated_naming=true}","network_flows":"{is_network_policy=false, is_bound_to_vpn=false}", - "network_homing":"{ecomp_selected_instance_node_target=false}" + "exVL_naming": "{ecomp_generated_naming=true}", + "network_flows": "{is_network_policy=false, is_bound_to_vpn=false}", + "network_homing": "{ecomp_selected_instance_node_target=false}" } }; @@ -370,9 +380,7 @@ describe('Network Model Info', () => { } - - - function getServiceHierarchy(){ + function getServiceHierarchy() { return { "service": { "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450", diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.ts index 3ed40cd5f..3ba4a2c4b 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/network/network.model.info.ts @@ -30,6 +30,7 @@ import { import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config"; import {ComponentInfoType} from "../../../component-info/component-info-model"; import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component"; +import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service"; export class NetworkModelInfo implements ILevelNodeInfo { constructor(private _dynamicInputsService: DynamicInputsService, @@ -39,6 +40,7 @@ export class NetworkModelInfo implements ILevelNodeInfo { private _duplicateService: DuplicateService, private modalService: SdcUiServices.ModalService, private _iframeService: IframeService, + private _featureFlagsService: FeatureFlagsService, private _store: NgRedux) { } @@ -70,7 +72,7 @@ export class NetworkModelInfo implements ILevelNodeInfo { ************************************************************/ getModel = (networkModelId: string, instance: NetworkInstance, serviceHierarchy): NetworkModel => { const originalModelName = instance.originalName ? instance.originalName : networkModelId; - return new NetworkModel(serviceHierarchy[this.name][originalModelName]); + return new NetworkModel(serviceHierarchy[this.name][originalModelName], this._featureFlagsService.getAllFlags()); }; @@ -164,8 +166,8 @@ export class NetworkModelInfo implements ILevelNodeInfo { counter -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'networks'); const properties = this._store.getState().service.serviceHierarchy[serviceModelId].networks[node.data.name].properties; - const maxInstances: number = !_.isNil(properties) ? (properties.max_instances || 1) : 1; - const isReachedLimit = !(maxInstances > counter); + const flags = FeatureFlagsService.getAllFlags(this._store); + const isReachedLimit: boolean = this._sharedTreeService.isReachedToMaxInstances(properties, counter, flags); const showAddIcon = this._sharedTreeService.shouldShowAddIcon() && !isReachedLimit; return new AvailableNodeIcons(showAddIcon, isReachedLimit) diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts index eb9902f7c..225d84b4c 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.spec.ts @@ -28,6 +28,12 @@ class MockAppStore { } } +class MockFeatureFlagsService extends FeatureFlagsService{ + getAllFlags(): { [p: string]: boolean } { + return {}; + } +} + describe('VFModule Model Info', () => { let injector; let _dynamicInputsService : DynamicInputsService; @@ -38,6 +44,8 @@ describe('VFModule Model Info', () => { let _vfModuleUpgradePopupService : VfModuleUpgradePopupService; let _iframeService : IframeService; let _componentInfoService : ComponentInfoService; + let _featureFlagsService : FeatureFlagsService; + beforeAll(done => (async () => { TestBed.configureTestingModule({ @@ -54,7 +62,7 @@ describe('VFModule Model Info', () => { AaiService, HttpClient, HttpHandler, - FeatureFlagsService, + {provide: FeatureFlagsService, useClass: MockFeatureFlagsService}, ComponentInfoService ] }); @@ -63,7 +71,8 @@ describe('VFModule Model Info', () => { injector = getTestBed(); _sharedTreeService = injector.get(SharedTreeService); _componentInfoService = injector.get(ComponentInfoService) - vfModuleModel = new VFModuleModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _vfModulePopupService, _vfModuleUpgradePopupService, _iframeService, MockNgRedux.getInstance(),_componentInfoService); + _featureFlagsService = injector.get(FeatureFlagsService); + vfModuleModel = new VFModuleModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _vfModulePopupService, _vfModuleUpgradePopupService, _iframeService,_featureFlagsService, MockNgRedux.getInstance(),_componentInfoService); })().then(done).catch(done.fail)); diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts index 5e14586c5..e182b8a6f 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vfModule/vfModule.model.info.ts @@ -40,6 +40,7 @@ export class VFModuleModelInfo implements ILevelNodeInfo { private _vfModulePopupService: VfModulePopuopService, private _vfModuleUpgradePopupService: VfModuleUpgradePopupService, private _iframeService: IframeService, + private _featureFlagsService: FeatureFlagsService, private _store: NgRedux, private _componentInfoService: ComponentInfoService) { } @@ -306,7 +307,6 @@ export class VFModuleModelInfo implements ILevelNodeInfo { maxNodes = vnfModules[node.data.name].properties.maxCountInstances || 1; } return !(maxNodes > currentNodeCount); - } getMenuAction(node: ITreeNode, serviceModelId: string): { [methodName: string]: { method: Function, visible: Function, enable: Function } } { diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.spec.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.spec.ts index 3af42884d..d89280f0a 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.spec.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.spec.ts @@ -23,6 +23,11 @@ import {AaiService} from "../../../../../shared/services/aaiService/aai.service" import {HttpClient, HttpHandler} from "@angular/common/http"; import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service"; import {VfModuleUpgradePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service"; +class MockFeatureFlagsService extends FeatureFlagsService{ + getAllFlags(): { [p: string]: boolean } { + return {}; + } +} describe('Vnf Model Info', () => { let injector; @@ -38,6 +43,7 @@ describe('Vnf Model Info', () => { let _duplicateService : DuplicateService; let _iframeService : IframeService; let _componentInfoService : ComponentInfoService; + let _featureFlagsService : FeatureFlagsService; let _store : NgRedux; let vnfModel: VnfModelInfo; @@ -57,7 +63,7 @@ describe('Vnf Model Info', () => { AaiService, HttpClient, HttpHandler, - FeatureFlagsService, + {provide: FeatureFlagsService, useClass: MockFeatureFlagsService}, ComponentInfoService, IframeService] }).compileComponents(); @@ -65,7 +71,7 @@ describe('Vnf Model Info', () => { injector = getTestBed(); _sharedTreeService = injector.get(SharedTreeService); _store = injector.get(NgRedux); - _componentInfoService = injector.get(ComponentInfoService); + _featureFlagsService = injector.get(FeatureFlagsService); vnfModel = new VnfModelInfo( _dynamicInputsService, @@ -79,6 +85,7 @@ describe('Vnf Model Info', () => { null, _iframeService, _componentInfoService, + _featureFlagsService, _store); diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.ts index 05d4af18d..c1255f57c 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vnf/vnf.model.info.ts @@ -39,6 +39,7 @@ import {ComponentInfoType} from "../../../component-info/component-info-model"; import {ComponentInfoService} from "../../../component-info/component-info.service"; import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component"; import {VfModuleUpgradePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service"; +import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service"; export class VnfModelInfo implements ILevelNodeInfo { constructor(private _dynamicInputsService: DynamicInputsService, @@ -47,11 +48,12 @@ export class VnfModelInfo implements ILevelNodeInfo { private _dialogService: DialogService, private _vnfPopupService: VnfPopupService, private _vfModulePopupService: VfModulePopuopService, - private _vfModuleUpgradePopupService : VfModuleUpgradePopupService, + private _vfModuleUpgradePopupService: VfModuleUpgradePopupService, private _duplicateService: DuplicateService, private modalService: SdcUiServices.ModalService, private _iframeService: IframeService, private _componentInfoService: ComponentInfoService, + private _featureFlagsService: FeatureFlagsService, private _store: NgRedux) { } @@ -87,7 +89,7 @@ export class VnfModelInfo implements ILevelNodeInfo { ************************************************************/ getModel = (vnfModelId: string, instance: VnfInstance, serviceHierarchy): VNFModel => { const originalModelName = instance.originalName ? instance.originalName : vnfModelId; - return new VNFModel(serviceHierarchy[this.name][originalModelName]); + return new VNFModel(serviceHierarchy[this.name][originalModelName], this._featureFlagsService.getAllFlags()); }; @@ -104,7 +106,7 @@ export class VnfModelInfo implements ILevelNodeInfo { node.typeName = this.typeName; node.menuActions = this.getMenuAction(node, model.uuid); node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed; - node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage: ""; + node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : ""; node = this._sharedTreeService.addingStatusProperty(node); return node; }; @@ -113,7 +115,7 @@ export class VnfModelInfo implements ILevelNodeInfo { * return next level object (VFModule) ************************************************************/ getNextLevelObject = (): VFModuleModelInfo => { - return new VFModuleModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._vfModulePopupService, this._vfModuleUpgradePopupService, this._iframeService, this._store, this._componentInfoService); + return new VFModuleModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._vfModulePopupService, this._vfModuleUpgradePopupService, this._iframeService, this._featureFlagsService, this._store, this._componentInfoService); }; /*********************************************************** @@ -181,8 +183,8 @@ export class VnfModelInfo implements ILevelNodeInfo { counter -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'vnfs'); const properties = this._store.getState().service.serviceHierarchy[serviceModelId].vnfs[node.data.name].properties; - const maxInstances: number = !_.isNil(properties) ? (properties.max_instances || 1) : 1; - const isReachedLimit = !(maxInstances > counter); + const flags = FeatureFlagsService.getAllFlags(this._store); + const isReachedLimit: boolean = this._sharedTreeService.isReachedToMaxInstances(properties, counter, flags); const showAddIcon = this._sharedTreeService.shouldShowAddIcon() && !isReachedLimit; return new AvailableNodeIcons(showAddIcon, isReachedLimit) } @@ -211,9 +213,9 @@ export class VnfModelInfo implements ILevelNodeInfo { }, showAuditInfo: { method: (node, serviceModelId) => { - const instance = this._store.getState().service.serviceInstance[serviceModelId].vnfs[node.data.vnfStoreKey]; - this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VNF', this); - }, + const instance = this._store.getState().service.serviceInstance[serviceModelId].vnfs[node.data.vnfStoreKey]; + this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VNF', this); + }, visible: (node) => this._sharedTreeService.shouldShowAuditInfo(node), enable: (node) => this._sharedTreeService.shouldShowAuditInfo(node) }, @@ -324,8 +326,8 @@ export class VnfModelInfo implements ILevelNodeInfo { getInfo(model, instance): ModelInformationItem[] { const modelInformation = !_.isEmpty(model) ? [ - ModelInformationItem.createInstance("Min instances", !_.isNull(model.min)? String(model.min): null), - ModelInformationItem.createInstance("Max instances", !_.isNull(model.max)? String(model.max): null) + ModelInformationItem.createInstance("Min instances", !_.isNull(model.min) ? String(model.min) : null), + ModelInformationItem.createInstance("Max instances", !_.isNull(model.max) ? String(model.max) : null) ] : []; const instanceInfo = !_.isEmpty(instance) ? [ diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vrf/vrf.model.info.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vrf/vrf.model.info.ts index 4c779a313..3dbc60adb 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vrf/vrf.model.info.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/models/vrf/vrf.model.info.ts @@ -26,12 +26,14 @@ import { undoDeleteActionVrfInstance } from "../../../../../shared/storeUtil/utils/vrf/vrf.actions"; import * as _ from "lodash"; +import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service"; export class VrfModelInfo implements ILevelNodeInfo { constructor(private _store: NgRedux, private _sharedTreeService: SharedTreeService, private _dialogService: DialogService, private _iframeService: IframeService, + private _featureFlagsService : FeatureFlagsService, private _networkStepService: NetworkStepService, private _vpnStepService: VpnStepService) { } @@ -70,7 +72,7 @@ export class VrfModelInfo implements ILevelNodeInfo { return new VpnModelInfo(this._store, this._sharedTreeService); } else { if (nextLevelType === 'networks') { - return new NetworkModelInfo(null, this._sharedTreeService, null, null, null, null, null, this._store); + return new NetworkModelInfo(null, this._sharedTreeService, null, null, null, null, null,this._featureFlagsService, this._store); } } }; diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToModelTree/objectToModelTree.service.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToModelTree/objectToModelTree.service.ts index c101f44e9..75ae1e149 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToModelTree/objectToModelTree.service.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToModelTree/objectToModelTree.service.ts @@ -3,11 +3,13 @@ import {ILevelNodeInfo} from "../models/basic.model.info"; import {ObjectToTreeService} from "../objectToTree.service"; import * as _ from "lodash"; import {IModelTreeNodeModel} from "../../../objectsToTree/objectToModelTree/modelTreeNode.model"; +import {FeatureFlagsService} from "../../../../shared/services/featureFlag/feature-flags.service"; @Injectable() export class ObjectToModelTreeService { numberOfPlusButton: number; - constructor(private _objectToTreeService: ObjectToTreeService) { + + constructor(private _objectToTreeService: ObjectToTreeService, private _featureFlagsService: FeatureFlagsService) { } /*********************************************************** @@ -18,9 +20,10 @@ export class ObjectToModelTreeService { let _this = this; const firstLevelOptions: ILevelNodeInfo[] = _this._objectToTreeService.getFirstLevelOptions(); let nodes = []; + let flags = this._featureFlagsService.getAllFlags(); for (let option of firstLevelOptions) { _.forOwn(serviceModel[option.name], function (item, key) { - nodes.push(_this.addFirstLevelModel(serviceModel.service.uuid, key, item, item.type, serviceModel, option)); + nodes.push(_this.addFirstLevelModel(serviceModel.service.uuid, key, item, item.type, serviceModel, option, flags)); }); } @@ -30,10 +33,10 @@ export class ObjectToModelTreeService { return nodes; } - calculateNumberOfNodesWithPlusIcon(serviceModel, nodes) : void { - this.numberOfPlusButton = nodes.reduce((sum, node)=>{ - let showNodeIconResult = node.showNodeIcons({data : node}, serviceModel.service.uuid); - return (!_.isNil(showNodeIconResult) && showNodeIconResult.addIcon && !showNodeIconResult.vIcon) ? sum + 1 : sum; + calculateNumberOfNodesWithPlusIcon(serviceModel, nodes): void { + this.numberOfPlusButton = nodes.reduce((sum, node) => { + let showNodeIconResult = node.showNodeIcons({data: node}, serviceModel.service.uuid); + return (!_.isNil(showNodeIconResult) && showNodeIconResult.addIcon && !showNodeIconResult.vIcon) ? sum + 1 : sum; }, 0); } @@ -47,9 +50,9 @@ export class ObjectToModelTreeService { * @param parentModel - current parent Model object * @param levelNodeInfo - current level node information ************************************************************/ - private addFirstLevelModel(serviceId: string, name, currentModel, type, parentModel, levelNodeInfo: ILevelNodeInfo) { - let node = ObjectToModelTreeService.convertItemToTreeNode(serviceId, name, currentModel, type, null, levelNodeInfo); - node.children = this.addNextLevelNodes(serviceId, currentModel, parentModel, levelNodeInfo, node); + private addFirstLevelModel(serviceId: string, name, currentModel, type, parentModel, levelNodeInfo: ILevelNodeInfo, flags?: { [key: string]: boolean }) { + let node = ObjectToModelTreeService.convertItemToTreeNode(serviceId, name, currentModel, type, null, levelNodeInfo, flags); + node.children = this.addNextLevelNodes(serviceId, currentModel, parentModel, levelNodeInfo, node, flags); return node; } @@ -61,13 +64,13 @@ export class ObjectToModelTreeService { * @param levelNodeInfo - current level node information * @param parentNode - parent node. ************************************************************/ - addNextLevelNodes(serviceId: string, currentModel, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode): any[] { + addNextLevelNodes(serviceId: string, currentModel, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode, flags?: { [key: string]: boolean }): any[] { if (!_.isNil(levelNodeInfo.childNames) && levelNodeInfo.childNames.length > 0) { levelNodeInfo.childNames.forEach(function (childName) { if (!_.isNil(currentModel[childName])) { let nextLevelNodeInfo = levelNodeInfo.getNextLevelObject.apply(this, [childName]); parentNode.children = Object.keys(currentModel[childName]).map((key) => - ObjectToModelTreeService.convertItemToTreeNode(serviceId, key, currentModel[childName][key], childName, currentModel, nextLevelNodeInfo)); + ObjectToModelTreeService.convertItemToTreeNode(serviceId, key, currentModel[childName][key], childName, currentModel, nextLevelNodeInfo, flags)); } }) } @@ -84,17 +87,18 @@ export class ObjectToModelTreeService { * @param parentModel - current parent model * @param levelNodeInfo - current levelNodeInfo object ************************************************************/ - static convertItemToTreeNode(serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo) { - let node : IModelTreeNodeModel = { + static convertItemToTreeNode(serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo, flags?: { [key: string]: boolean }) { + const type: string = levelNodeInfo.getType(); + let node: IModelTreeNodeModel = { id: currentModel.customizationUuid || currentModel.uuid, - modelCustomizationId : currentModel.customizationUuid, - modelVersionId: currentModel.uuid, - modelUniqueId : currentModel.customizationUuid || currentModel.uuid, + modelCustomizationId: currentModel.customizationUuid, + modelVersionId: currentModel.uuid, + modelUniqueId: currentModel.customizationUuid || currentModel.uuid, name: name, tooltip: levelNodeInfo.getTooltip(), - type: levelNodeInfo.getType(), + type, count: currentModel.count || 0, - max: currentModel.max || 1, + max: ObjectToModelTreeService.getMax(currentModel, type, flags), children: [], disabled: false, dynamicInputs: levelNodeInfo.updateDynamicInputsDataFromModel(currentModel), @@ -105,15 +109,24 @@ export class ObjectToModelTreeService { return node; } + static getMax(currentModel, type, flags: { [key: string]: boolean }) { + if (flags && !!flags['FLAG_2002_UNLIMITED_MAX'] && (type === 'VF' || type === 'Network' || type === 'VFmodule')) { + return !_.isNil(currentModel.max) ? currentModel.max : null; + } else { + return currentModel.max || 1 + } + } - static addExtraFunctionality(node, serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo){ + + static addExtraFunctionality(node, serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo) { node.onAddClick = (node, serviceId) => levelNodeInfo.onClickAdd(node, serviceId); node.getNodeCount = (node, serviceId) => levelNodeInfo.getNodeCount(node, serviceId); node.getMenuAction = (node, serviceId) => levelNodeInfo.getMenuAction(node, serviceId); node.showNodeIcons = (node, serviceId) => levelNodeInfo.showNodeIcons(node, serviceId); node.typeName = levelNodeInfo.typeName; node.getModel = levelNodeInfo.getModel.bind(levelNodeInfo); - node.getInfo = !_.isNil(levelNodeInfo.getInfo) ? levelNodeInfo.getInfo.bind(levelNodeInfo) : ()=>{}; + node.getInfo = !_.isNil(levelNodeInfo.getInfo) ? levelNodeInfo.getInfo.bind(levelNodeInfo) : () => { + }; node.componentInfoType = levelNodeInfo.componentInfoType; return node; } diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToTree.service.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToTree.service.ts index 443741ff9..1e6825130 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToTree.service.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/objectToTree.service.ts @@ -25,6 +25,7 @@ import {VrfModelInfo} from "./models/vrf/vrf.model.info"; import {NetworkStepService} from "./models/vrf/vrfModal/networkStep/network.step.service"; import {VpnStepService} from "./models/vrf/vrfModal/vpnStep/vpn.step.service"; import { VfModuleUpgradePopupService } from "../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service"; +import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service"; @Injectable() export class ObjectToTreeService { @@ -44,6 +45,7 @@ export class ObjectToTreeService { private _networkStepService : NetworkStepService, private _vpnStepService : VpnStepService, private _aaiService : AaiService, + private _featureFlagsService: FeatureFlagsService, private _store : NgRedux) { } @@ -54,10 +56,10 @@ export class ObjectToTreeService { * return all first optional first level of the model tree ************************************************************/ getFirstLevelOptions(): ILevelNodeInfo[] { - return [new VnfModelInfo(this._dynamicInputsService, this._sharedTreeService, this._defaultDataGeneratorService, this._dialogService, this._vnfPopupService, this._vfModulePopupService, this._vfModuleUpgradePopupService,this._duplicateService, this._modalService, this._iframeService, this._componentInfoService, this._store) - , new NetworkModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._networkPopupService, this._duplicateService, this._modalService, this._iframeService, this._store), + return [new VnfModelInfo(this._dynamicInputsService, this._sharedTreeService, this._defaultDataGeneratorService, this._dialogService, this._vnfPopupService, this._vfModulePopupService, this._vfModuleUpgradePopupService,this._duplicateService, this._modalService, this._iframeService, this._componentInfoService, this._featureFlagsService, this._store) + , new NetworkModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._networkPopupService, this._duplicateService, this._modalService, this._iframeService, this._featureFlagsService, this._store), new PnfModelInfo(), - new VrfModelInfo(this._store, this._sharedTreeService, this._dialogService, this._iframeService, this._networkStepService, this._vpnStepService), + new VrfModelInfo(this._store, this._sharedTreeService, this._dialogService, this._iframeService, this._featureFlagsService, this._networkStepService, this._vpnStepService), new CollectionResourceModelInfo(this._store, this._sharedTreeService), new ConfigurationModelInfo(this._dynamicInputsService, this._sharedTreeService), new VnfGroupingModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._vnfGroupPopupService, this._iframeService, this._aaiService, this._store)]; diff --git a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts index c56cc4999..b8eddbbf7 100644 --- a/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts +++ b/vid-webpack-master/src/app/drawingBoard/service-planning/objectsToTree/shared.tree.service.ts @@ -13,6 +13,7 @@ import {ModelInformationItem} from "../../../shared/components/model-information import {undoUpgradeService, upgradeService} from "../../../shared/storeUtil/utils/service/service.actions"; import {VNFMethods} from "../../../shared/storeUtil/utils/vnf/vnf.actions"; import {FeatureFlagsService, Features} from "../../../shared/services/featureFlag/feature-flags.service"; +import {Utils} from "../../../shared/utils/utils"; @Injectable() export class SharedTreeService { @@ -239,6 +240,16 @@ export class SharedTreeService { const mode = this._store.getState().global.drawingBoardStatus; return mode === DrawingBoardModes.EDIT || mode=== DrawingBoardModes.CREATE; } + + + isReachedToMaxInstances(properties, counter, flags): boolean{ + let maxInstances = Utils.getMaxFirstLevel(properties, flags); + if(_.isNil(maxInstances)){ + return false; + }else { + return !(maxInstances > counter); + } + } /************************************************ return number of instances with action Delete @type: vnfs networks, vngGroups (not vfModule) diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/basic.popup.service.ts b/vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/basic.popup.service.ts index 5d4d16567..c18b20d7e 100644 --- a/vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/basic.popup.service.ts +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/basic.popup.service.ts @@ -10,6 +10,7 @@ import * as _ from 'lodash'; import {VfModule} from "../../../models/vfModule"; import {VNFModel} from "../../../models/vnfModel"; import {VnfGroupModel} from "../../../models/vnfGroupModel"; +import {FeatureFlagsService} from "../../../services/featureFlag/feature-flags.service"; @Injectable() export class BasicPopupService { @@ -29,17 +30,18 @@ export class BasicPopupService { } getModelFromResponse(result: any, modelType: string, modelName: string) { + let flags = FeatureFlagsService.getAllFlags(this._store); let rawModel = result[modelType][modelName]; if (!rawModel) return; switch (modelType){ case 'vnfs' : { - return new VNFModel(rawModel); + return new VNFModel(rawModel, flags); } case 'vfModules' : { return new VfModule(rawModel); } case 'networks' : { - return new NetworkModel(rawModel); + return new NetworkModel(rawModel, flags); } case 'vnfGroups' : { return new VnfGroupModel(rawModel); diff --git a/vid-webpack-master/src/app/shared/models/networkModel.ts b/vid-webpack-master/src/app/shared/models/networkModel.ts index 03f118eb7..b4879a59d 100644 --- a/vid-webpack-master/src/app/shared/models/networkModel.ts +++ b/vid-webpack-master/src/app/shared/models/networkModel.ts @@ -2,29 +2,30 @@ import { Level1Model, Level1ModelProperties, Level1ModelResponseInterface } from "./nodeModel"; -import {VfcInstanceGroupMap} from "./vfcInstanceGroupMap"; +import {Utils} from "../utils/utils"; -export interface NetworkProperties extends Level1ModelProperties{ +export interface NetworkProperties extends Level1ModelProperties { ecomp_generated_naming: string; network_role: string; } -export interface NetworkModelResponseInterface extends Level1ModelResponseInterface{ +export interface NetworkModelResponseInterface extends Level1ModelResponseInterface { properties: NetworkProperties; } -export class NetworkModel extends Level1Model{ +export class NetworkModel extends Level1Model { roles: string[] = []; properties: NetworkProperties; - constructor(networkJson?: NetworkModelResponseInterface){ + constructor(networkJson?: NetworkModelResponseInterface, flags?: { [key: string]: boolean }) { super(networkJson); - if(networkJson && networkJson.properties){ + if (networkJson && networkJson.properties) { this.properties = networkJson.properties; // expecting network_role to be a comma-saparated list this.roles = networkJson.properties.network_role ? networkJson.properties.network_role.split(',') : []; + this.max = Utils.getMaxFirstLevel(this.properties, flags); } } diff --git a/vid-webpack-master/src/app/shared/models/vnfModel.ts b/vid-webpack-master/src/app/shared/models/vnfModel.ts index 8389606b6..220dc0fc5 100644 --- a/vid-webpack-master/src/app/shared/models/vnfModel.ts +++ b/vid-webpack-master/src/app/shared/models/vnfModel.ts @@ -3,25 +3,24 @@ import { Level1ModelProperties, Level1ModelResponseInterface } from "./nodeModel"; +import {Utils} from "../utils/utils"; - - -export interface VnfProperties extends Level1ModelProperties{ +export interface VnfProperties extends Level1ModelProperties { ecomp_generated_naming: string; } -export interface VNFModelResponseInterface extends Level1ModelResponseInterface{ +export interface VNFModelResponseInterface extends Level1ModelResponseInterface { properties: VnfProperties; } -export class VNFModel extends Level1Model{ +export class VNFModel extends Level1Model { properties: VnfProperties; - constructor(vnfJson?: VNFModelResponseInterface) { + constructor(vnfJson?: VNFModelResponseInterface, flags?: { [key: string]: boolean }) { super(vnfJson); if (vnfJson) { this.properties = vnfJson.properties; + this.max = Utils.getMaxFirstLevel(this.properties, flags); } } - } diff --git a/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts b/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts index 7e0575b68..74fcd8f87 100644 --- a/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts +++ b/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts @@ -27,6 +27,14 @@ export class FeatureFlagsService { return FeatureFlagsService.getFlagState(flag, this.store); } + public getAllFlags(): { [key: string]: boolean}{ + return this.store.getState().global.flags; + } + + public static getAllFlags(store: NgRedux): { [key: string]: boolean}{ + return store.getState().global.flags; + } + /*static method for easy refactoring of code, so no injection of FeatureFlagsService is needed*/ public static getFlagState(flag: Features, store: NgRedux):boolean { let storeStateGlobalFields = store.getState().global; diff --git a/vid-webpack-master/src/app/shared/utils/utils.ts b/vid-webpack-master/src/app/shared/utils/utils.ts index cb5e1a1c8..cd7ebdff6 100644 --- a/vid-webpack-master/src/app/shared/utils/utils.ts +++ b/vid-webpack-master/src/app/shared/utils/utils.ts @@ -2,6 +2,14 @@ import * as _ from 'lodash' export class Utils { + static getMaxFirstLevel(properties, flags: { [key: string]: boolean }) : number | null{ + if (flags && !!flags['FLAG_2002_UNLIMITED_MAX']) { + return !_.isNil(properties) && !_.isNil(properties.max_instances) ? properties.max_instances : null; + } else { + return properties.max_instances || 1; + } + } + public static clampNumber = (number, min, max) => { return Math.max(min, Math.min(number, max)); }; -- cgit 1.2.3-korg