diff options
author | Ittay Stern <ittay.stern@att.com> | 2018-08-29 17:01:32 +0300 |
---|---|---|
committer | Ittay Stern <ittay.stern@att.com> | 2019-02-18 18:35:30 +0200 |
commit | 6f900cc45d7dd7f97430812b86b5c1d1693c8ae3 (patch) | |
tree | 936005c364dc5a7264d6304d4777c3d83494db22 /vid-webpack-master/src/app/shared/storeUtil/utils | |
parent | 67d99f816cc583643c35193197594cf78d8ce60a (diff) |
merge from ecomp a88f0072 - Modern UI
Issue-ID: VID-378
Change-Id: Ibcb23dd27f550cf32ce2fe0239f0f496ae014ff6
Signed-off-by: Ittay Stern <ittay.stern@att.com>
Diffstat (limited to 'vid-webpack-master/src/app/shared/storeUtil/utils')
26 files changed, 3511 insertions, 0 deletions
diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.action.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.action.spec.ts new file mode 100644 index 000000000..a65249a3b --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.action.spec.ts @@ -0,0 +1,157 @@ +import { + GeneralActions, UpdateAicZonesAction, + UpdateLcpRegionsAndTenantsAction, + UpdateProductFamiliesAction, + UpdateSubscribersAction, UpdateUserIdAction +} from "./general.actions"; +import {SelectOption} from "../../../models/selectOption"; + + +describe('general actions', () => { + test('#UPDATE_LCP_REGIONS_AND_TENANTS : action', () => { + const action: UpdateLcpRegionsAndTenantsAction = <UpdateLcpRegionsAndTenantsAction>{ + type: GeneralActions.UPDATE_LCP_REGIONS_AND_TENANTS, + lcpRegionsAndTenants: { + "lcpRegionList": [], + "lcpRegionsTenantsMap": {} + } + }; + + expect(action.type).toEqual(GeneralActions.UPDATE_LCP_REGIONS_AND_TENANTS); + expect(action.lcpRegionsAndTenants.lcpRegionList).toEqual([]); + expect(action.lcpRegionsAndTenants.lcpRegionsTenantsMap).toEqual({}); + }); + + test('#UPDATE_SUBSCRIBERS : action', () => { + const action: UpdateSubscribersAction = <UpdateSubscribersAction>{ + type: GeneralActions.UPDATE_SUBSCRIBERS, + subscribers: [ + { + "id": "ERICA5779-Subscriber-2", + "name": "ERICA5779-Subscriber-2", + "isPermitted": false + }, + { + "id": "ERICA5779-Subscriber-3", + "name": "ERICA5779-Subscriber-3", + "isPermitted": false + }, + { + "id": "ERICA5779-Subscriber-4", + "name": "ERICA5779-Subscriber-5", + "isPermitted": false + }, + { + "id": "ERICA5779-TestSub-PWT-101", + "name": "ERICA5779-TestSub-PWT-101", + "isPermitted": false + }, + { + "id": "ERICA5779-TestSub-PWT-102", + "name": "ERICA5779-TestSub-PWT-102", + "isPermitted": false + }, + { + "id": "ERICA5779-TestSub-PWT-103", + "name": "ERICA5779-TestSub-PWT-103", + "isPermitted": false + }, + { + "id": "31739f3e-526b-11e6-beb8-9e71128cae77", + "name": "CRAIG/ROBERTS", + "isPermitted": false + }, + { + "id": "DHV1707-TestSubscriber-2", + "name": "DALE BRIDGES", + "isPermitted": false + }, + { + "id": "jimmy-example", + "name": "JimmyExampleCust-20161102", + "isPermitted": false + }, + { + "id": "jimmy-example2", + "name": "JimmyExampleCust-20161103", + "isPermitted": false + }, + { + "id": "CAR_2020_ER", + "name": "CAR_2020_ER", + "isPermitted": true + }, + { + "id": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", + "name": "Emanuel", + "isPermitted": false + }, + { + "id": "21014aa2-526b-11e6-beb8-9e71128cae77", + "name": "JULIO ERICKSON", + "isPermitted": false + }, + { + "id": "DHV1707-TestSubscriber-1", + "name": "LLOYD BRIDGES", + "isPermitted": false + }, + { + "id": "e433710f-9217-458d-a79d-1c7aff376d89", + "name": "SILVIA ROBBINS", + "isPermitted": true + } + ] + }; + + expect(action.type).toEqual(GeneralActions.UPDATE_SUBSCRIBERS); + expect(action.subscribers).toHaveLength(15); + }); + + test('#UPDATE_PRODUCT_FAMILIES : action', () => { + const action: UpdateProductFamiliesAction = <UpdateProductFamiliesAction>{ + type: GeneralActions.UPDATE_PRODUCT_FAMILIES, + productFamilies: [ + new SelectOption({ + id : 'id', + name : 'name', + isPermitted : false + }) + ] + }; + + expect(action.type).toEqual(GeneralActions.UPDATE_PRODUCT_FAMILIES); + expect(action.productFamilies).toHaveLength(1); + }); + + + test('#UpdateAicZonesAction : action', () => { + const action: UpdateAicZonesAction = <UpdateAicZonesAction>{ + type: GeneralActions.UPDATE_AIC_ZONES, + aicZones: [ + new SelectOption({ + id : 'id', + name : 'name', + isPermitted : false + }) + ] + }; + + expect(action.type).toEqual(GeneralActions.UPDATE_AIC_ZONES); + expect(action.aicZones).toHaveLength(1); + }); + + test('#UpdateUserIdAction : action', () => { + const action: UpdateUserIdAction = <UpdateUserIdAction>{ + type: GeneralActions.UPDATE_USER_ID, + userId: "userId" + }; + + expect(action.type).toEqual(GeneralActions.UPDATE_USER_ID); + expect(action.userId).toBe("userId"); + }); + +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.actions.ts new file mode 100644 index 000000000..7a10eba0a --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.actions.ts @@ -0,0 +1,150 @@ +import {Action, ActionCreator} from "redux"; +import {LcpRegionsAndTenants} from "../../../models/lcpRegionsAndTenants"; +import {SelectOptionInterface} from "../../../models/selectOption"; +import {ServiceType} from "../../../models/serviceType"; +import {ITreeNode} from "angular-tree-component/dist/defs/api"; + +export enum GeneralActions { + UPDATE_LCP_REGIONS_AND_TENANTS = "UPDATE_LCP_REGIONS_AND_TENANTS", + UPDATE_SUBSCRIBERS = "UPDATE_SUBSCRIBERS", + UPDATE_PRODUCT_FAMILIES = "UPDATE_PRODUCT_FAMILIES", + UPDATE_SERVICE_TYPES = "UPDATE_SERVICE_TYPES", + UPDATE_AIC_ZONES = "UPDATE_AIC_ZONES", + UPDATE_USER_ID = "UPDATE_USER_ID", + UPDATE_NETWORK_FUNCTION = "UPDATE_NETWORK_FUNCTION", + UPDATE_CATEGORY_PARAMETERS = "UPDATE_CATEGORY_PARAMETERS", + REMOVE_INSTANCE = 'REMOVE_INSTANCE', + CHANGE_INSTANCE_COUNTER = 'CHANGE_INSTANCE_COUNTER', + DUPLICATE_BULK_INSTANCES = 'DUPLICATE_BULK_INSTANCES' +} +export interface UpdateLcpRegionsAndTenantsAction extends Action { + lcpRegionsAndTenants?: LcpRegionsAndTenants; +} + +export interface RemoveInstanceAction extends Action { + modelName?: string; + serviceModelId: string; + storeKey : string; + node : ITreeNode; +} + +export interface UpdateSubscribersAction extends Action { + subscribers?: SelectOptionInterface[]; +} + +export interface UpdateProductFamiliesAction extends Action { + productFamilies?: SelectOptionInterface[]; +} + +export interface UpdateAicZonesAction extends Action { + aicZones?: SelectOptionInterface[]; +} + +export interface UpdateServiceTypesAction extends Action { + serviceTypes?: ServiceType[]; + subscriberId: string; +} +export interface UpdateUserIdAction extends Action { + userId: string; +} + +export interface UpdateNetworkCollectionFunction extends Action { + networksAccordingToNetworkCollection: any; + network_function: any; +} + +export interface UpdateCategoryParametersAction extends Action { + categoryParameters?: Object; +} + +export interface ChangeInstanceCounterAction extends Action{ + serviceUUID : string; + UUID : string; + changeBy : number; + node : ITreeNode; +} + +export interface DuplicateBulkInstancesAction extends Action { + serviceId?: string; + modelName?: string; + originalName? : string; + objects? : {}; + existingNames: {[key: string] : any}; + node : ITreeNode; +} + +export interface UpdateServiceTypesAction extends Action { + serviceTypes?: ServiceType[]; + subscriberId: string; +} + +export const updateLcpRegionsAndTenants: ActionCreator<UpdateLcpRegionsAndTenantsAction> = lcpRegionsAndTenants => ({ + type: GeneralActions.UPDATE_LCP_REGIONS_AND_TENANTS, + lcpRegionsAndTenants: lcpRegionsAndTenants +}); + +export const updateSubscribers: ActionCreator<UpdateSubscribersAction> = subscribers => ({ + type: GeneralActions.UPDATE_SUBSCRIBERS, + subscribers: subscribers +}); + +export const updateProductFamilies: ActionCreator<UpdateProductFamiliesAction> = productFamilies => ({ + type: GeneralActions.UPDATE_PRODUCT_FAMILIES, + productFamilies: productFamilies +}); + +export const updateAicZones: ActionCreator<UpdateAicZonesAction> = aicZones => ({ + type: GeneralActions.UPDATE_AIC_ZONES, + aicZones: aicZones +}); + +export const updateUserId: ActionCreator<UpdateUserIdAction> = userId => ({ + type: GeneralActions.UPDATE_USER_ID, + userId: userId +}); + +export const updateNetworkCollectionFunction: ActionCreator<UpdateNetworkCollectionFunction> = (ncf, networksAccordingToNetworkCollection) => ({ + type: GeneralActions.UPDATE_NETWORK_FUNCTION, + networksAccordingToNetworkCollection: networksAccordingToNetworkCollection["results"], + network_function: ncf +}); + +export const updateCategoryParameters: ActionCreator<UpdateCategoryParametersAction> = categoryParameters => ({ + type: GeneralActions.UPDATE_CATEGORY_PARAMETERS, + categoryParameters: categoryParameters +}); + +export const removeInstance: ActionCreator<RemoveInstanceAction> = (modelName, serviceModelId, storeKey, node : ITreeNode) => ({ + type: GeneralActions.REMOVE_INSTANCE, + modelName: modelName, + serviceModelId: serviceModelId, + storeKey: storeKey, + node : node +}); + + +export const changeInstanceCounter: ActionCreator<ChangeInstanceCounterAction> = (UUID, serviceUUID , changeBy, node) => ({ + type: GeneralActions.CHANGE_INSTANCE_COUNTER, + UUID: UUID, + serviceUUID: serviceUUID, + changeBy : changeBy || 1, + node : node +}); + + +export const duplicateBulkInstances: ActionCreator<DuplicateBulkInstancesAction> = (serviceId, objects, existingNames, node) => ({ + type: GeneralActions.DUPLICATE_BULK_INSTANCES, + serviceId: serviceId, + objects : objects, + existingNames: existingNames, + node : node +}); + + +export const updateServiceTypes: ActionCreator<UpdateServiceTypesAction> = (serviceTypes, subscriberId) => ({ + type: GeneralActions.UPDATE_SERVICE_TYPES, + serviceTypes: serviceTypes, + subscriberId: subscriberId +}); + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.reducers.spec.ts new file mode 100644 index 000000000..ed456314e --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.reducers.spec.ts @@ -0,0 +1,376 @@ +import {LcpRegion} from "../../../models/lcpRegion"; +import {Tenant} from "../../../models/tenant"; +import {generalReducer} from "./general.reducers"; +import { + ChangeInstanceCounterAction, + RemoveInstanceAction, + DuplicateBulkInstancesAction, + GeneralActions, + UpdateAicZonesAction, + UpdateCategoryParametersAction, + UpdateProductFamiliesAction, + UpdateServiceTypesAction, + UpdateSubscribersAction, + UpdateUserIdAction, UpdateNetworkCollectionFunction, +} from "./general.actions"; +import {SelectOption} from "../../../models/selectOption"; +import {ServiceType} from "../../../models/serviceType"; +import {ITreeNode} from "angular-tree-component/dist/defs/api"; +import {VnfInstance} from "../../../models/vnfInstance"; + +describe('generalReducer', () => { + test('#UPDATE_LCP_REGIONS_AND_TENANTS : should update lcp region and tenants', () => { + let lcpRegionsAndTenantsObj = [ + { + lcpRegionList : [ + new LcpRegion( + 'cloudRegionID', + 'cloudRegionID (cloudOwner)', + true, + 'cloudOwner' + ) + ], + lcpRegionsTenantsMap : { + "lcpRegion" : [new Tenant({ + "tenantID" : "tenantID", + "tenantName" : "tenantName", + "is-permitted" : true + })] + } + } + ]; + let lcpRegionsAndTenantsState = generalReducer(<any>{serviceInstance : {}}, + <any>{ + type: GeneralActions.UPDATE_LCP_REGIONS_AND_TENANTS, + lcpRegionsAndTenants : lcpRegionsAndTenantsObj + })['lcpRegionsAndTenants']; + + expect(lcpRegionsAndTenantsState).toBeDefined(); + }); + + test('#UPDATE_SUBSCRIBERS : should update subscribers', () => { + let subscribersList = [ + new SelectOption({ + id : 'id', + name : 'name', + isPermitted : false + }) + ]; + let subscribersState = generalReducer(<any> + { + serviceInstance : {} + }, + <UpdateSubscribersAction>{ + type: GeneralActions.UPDATE_SUBSCRIBERS, + subscribers : subscribersList + })['subscribers']; + + expect(subscribersState).toBeDefined(); + expect(subscribersState[0].id).toEqual(subscribersList[0].id); + expect(subscribersState[0].isPermitted).toEqual(subscribersList[0].isPermitted); + expect(subscribersState[0].name).toEqual(subscribersList[0].name); + }); + + test('#UPDATE_PRODUCT_FAMILIES : should update product families', () => { + let productFamiliesObj = [ + new SelectOption({ + id : 'id', + name : 'name', + isPermitted : false + }) + ]; + let productFamiliesState = generalReducer(<any>{serviceInstance : {}}, + <UpdateProductFamiliesAction>{ + type: GeneralActions.UPDATE_PRODUCT_FAMILIES, + productFamilies : productFamiliesObj + })['productFamilies']; + + expect(productFamiliesState).toBeDefined(); + expect(productFamiliesState[0].id).toEqual(productFamiliesObj[0].id); + expect(productFamiliesState[0].isPermitted).toEqual(productFamiliesObj[0].isPermitted); + expect(productFamiliesState[0].name).toEqual(productFamiliesObj[0].name); + }); + + test('#UPDATE_AIC_ZONES : should update aic zones', () => { + let aicZonesObj = [ + new SelectOption({ + id : 'id', + name : 'name', + isPermitted : false + }) + ]; + let aicZonesState = generalReducer(<any>{serviceInstance : {}}, + <UpdateAicZonesAction>{ + type: GeneralActions.UPDATE_AIC_ZONES, + aicZones : aicZonesObj + })['aicZones']; + + expect(aicZonesState).toBeDefined(); + expect(aicZonesState[0].id).toEqual(aicZonesObj[0].id); + expect(aicZonesState[0].isPermitted).toEqual(aicZonesObj[0].isPermitted); + expect(aicZonesState[0].name).toEqual(aicZonesObj[0].name); + }); + + test('#UPDATE_SERVICE_TYPES : should update service types', () => { + const subscriberId = 'subscriberId'; + let serviceTypesList : ServiceType[] = [ + new ServiceType('id',{ + 'service-type' : 'name', + 'is-permitted' : true + }) + ]; + let serviceTypesState = generalReducer(<any> + { + serviceTypes : { + } + }, + <UpdateServiceTypesAction>{ + type: GeneralActions.UPDATE_SERVICE_TYPES, + subscriberId : subscriberId, + serviceTypes : serviceTypesList + })['serviceTypes'][subscriberId]; + + expect(serviceTypesState).toBeDefined(); + expect(serviceTypesState[0].id).toEqual(serviceTypesList[0].id); + expect(serviceTypesState[0].isPermitted).toEqual(serviceTypesList[0].isPermitted); + expect(serviceTypesState[0].name).toEqual(serviceTypesList[0].name); + }); + + test('#UPDATE_CATEGORY_PARAMETERS : should update category parameters', () => { + let list = [ + new SelectOption({ + id : 'id', + name : 'name', + isPermitted : false + }) + ]; + + const categoryParametersObj = { + owningEntityList : list, + projectList : list, + lineOfBusinessList : list, + platformList : list + }; + + let categoryParametersState = generalReducer(<any>{serviceInstance : {}}, + <UpdateCategoryParametersAction>{ + type: GeneralActions.UPDATE_CATEGORY_PARAMETERS, + categoryParameters : categoryParametersObj + })['categoryParameters']; + + expect(categoryParametersState).toBeDefined(); + expect(categoryParametersState['owningEntityList'][0].id).toEqual(list[0].id); + expect(categoryParametersState['owningEntityList'][0].isPermitted).toEqual(list[0].isPermitted); + expect(categoryParametersState['owningEntityList'][0].name).toEqual(list[0].name); + + expect(categoryParametersState['projectList'][0].id).toEqual(list[0].id); + expect(categoryParametersState['projectList'][0].isPermitted).toEqual(list[0].isPermitted); + expect(categoryParametersState['projectList'][0].name).toEqual(list[0].name); + + expect(categoryParametersState['lineOfBusinessList'][0].id).toEqual(list[0].id); + expect(categoryParametersState['lineOfBusinessList'][0].isPermitted).toEqual(list[0].isPermitted); + expect(categoryParametersState['lineOfBusinessList'][0].name).toEqual(list[0].name); + + expect(categoryParametersState['platformList'][0].id).toEqual(list[0].id); + expect(categoryParametersState['platformList'][0].isPermitted).toEqual(list[0].isPermitted); + expect(categoryParametersState['platformList'][0].name).toEqual(list[0].name); + }); + + test('#UPDATE_USER_ID : should update user id', () => { + const userId = 'userId'; + let userState = generalReducer(<any>{serviceInstance : {}}, + <UpdateUserIdAction>{ + type: GeneralActions.UPDATE_USER_ID, + userId : userId + })['userId']; + + expect(userState).toBeDefined(); + expect(userState).toEqual(userId); + }); + + test('#DELETE_VNF_INSTANCE : should delete existing vnf', () => { + let state = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'modelName' : {} + } + } + }}, + <RemoveInstanceAction>{ + type: GeneralActions.REMOVE_INSTANCE, + modelName : 'modelName', + serviceModelId : 'serviceModelId', + storeKey : 'modelName', + node : { + data : { + type : 'VF' + } + } + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance[ 'serviceModelId'].vnfs['modelName']).not.toBeDefined(); + }); + + test('#DELETE_VNF_INSTANCE : should delete existing network', () => { + let state = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + 'networks' : { + 'modelName' : {} + } + } + }}, + <RemoveInstanceAction>{ + type: GeneralActions.REMOVE_INSTANCE, + modelName : 'modelName', + serviceModelId : 'serviceModelId', + storeKey : 'modelName', + node : { + data : { + type : 'VL' + } + } + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].networks['modelName']).not.toBeDefined(); + }); + + test('#CHANGE_VNF_INSTANCE_COUNTER : should init existingVNFCounterMap to 1', () => { + let state = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfName' : { } + }, + existingVNFCounterMap : { + + } + } + }}, + <ChangeInstanceCounterAction>{ + type: GeneralActions.CHANGE_INSTANCE_COUNTER, + serviceUUID : 'serviceModelId', + node : {data : {type : 'VF'}}, + UUID : 'vnfUUID', + changeBy : 1 + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].existingVNFCounterMap['vnfUUID']).toEqual(1); + }); + + test('#CHANGE_VNF_INSTANCE_COUNTER : should increase existingVNFCounterMap to 2 if VNF exist', () => { + let state = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfName' : { } + }, + existingVNFCounterMap : { + 'vnfUUID' : 1 + } + } + }}, + <ChangeInstanceCounterAction>{ + type: GeneralActions.CHANGE_INSTANCE_COUNTER, + serviceUUID : 'serviceModelId', + UUID : 'vnfUUID', + node : {data : {type : 'VF'}}, + changeBy : 1 + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].existingVNFCounterMap['vnfUUID']).toEqual(2); + }); + + test('#CHANGE_VNF_INSTANCE_COUNTER : should remove existingVNFCounterMap to 0 remove VNF', () => { + + let state = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfName' : { } + }, + existingVNFCounterMap : { + 'vnfUUID' : 1 + } + } + }}, + <ChangeInstanceCounterAction>{ + type: GeneralActions.CHANGE_INSTANCE_COUNTER, + serviceUUID : 'serviceModelId', + UUID : 'vnfUUID', + node : {data : {type : 'VF'}}, + changeBy : -1 + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].existingVNFCounterMap['vnfUUID']).toEqual(0); + }); + + test('#DUPLICATE_BULK_INSTANCES : should duplicate existing VNF/Network', ()=>{ + let existingNames = { + 'vnfOriginalName' : 1 + }; + + let vnfInstance: VnfInstance = new VnfInstance(); + vnfInstance.originalName = 'vnfOriginalName'; + vnfInstance.vnfStoreKey = 'vnfStoreKey'; + + let cloneObjects = { + 'vnfOriginalName' : vnfInstance, + 'vnfOriginalName:0001' : vnfInstance, + 'vnfOriginalName:0002' : vnfInstance, + 'vnfOriginalName:0003' : vnfInstance + }; + + let node : ITreeNode = <any>{ + data : { + serviceId : 'serviceModelId', + vnfStoreKey : 'vnfStoreKey', + type : 'VF' + } + }; + + let vnfsState = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + }, + existingVNFCounterMap : {} + } + }}, + <DuplicateBulkInstancesAction>{ + type: GeneralActions.DUPLICATE_BULK_INSTANCES, + serviceId: 'serviceModelId', + modelName: 'modelName', + originalName : 'modelName', + objects : cloneObjects, + existingNames: existingNames, + node : node + }).serviceInstance['serviceModelId'].vnfs; + + expect(vnfsState).toBeDefined(); + expect(Object.keys(vnfsState).length).toEqual(4); + }); + + test('#UPDATE_NETWORK_FUNCTION : should update network functions', ()=>{ + let state = generalReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + }, + existingVNFCounterMap : {} + } + }}, + <UpdateNetworkCollectionFunction>{ + type: GeneralActions.UPDATE_NETWORK_FUNCTION, + network_function : { + results : [] + }, + networksAccordingToNetworkCollection : "networksAccordingToNetworkCollection" + }); + + expect(state).toBeDefined(); + expect(state['networkFunctions']).toBeDefined(); + }); +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.reducers.ts new file mode 100644 index 000000000..8ee47331f --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/general/general.reducers.ts @@ -0,0 +1,147 @@ +import {Action} from "redux"; +import { + ChangeInstanceCounterAction, RemoveInstanceAction, DuplicateBulkInstancesAction, + GeneralActions, + UpdateAicZonesAction, UpdateCategoryParametersAction, + UpdateLcpRegionsAndTenantsAction, UpdateNetworkCollectionFunction, + UpdateProductFamiliesAction, UpdateServiceTypesAction, + UpdateSubscribersAction, UpdateUserIdAction +} from "./general.actions"; +import {TypeNodeInformation} from "../../../../drawingBoard/service-planning/typeNodeInformation.model"; +import * as _ from "lodash"; +import {ITreeNode} from "angular-tree-component/dist/defs/api"; +import {ServiceInstance} from "../../../models/serviceInstance"; +import {ServiceState} from "../main.reducer"; + +export function generalReducer(state: ServiceState, action: Action) : ServiceState { + switch (action.type) { + case GeneralActions.UPDATE_LCP_REGIONS_AND_TENANTS: { + Object.assign(state, (<UpdateLcpRegionsAndTenantsAction>action)); + return Object.assign({}, state); + } + case GeneralActions.UPDATE_SUBSCRIBERS: { + Object.assign(state, (<UpdateSubscribersAction>action)); + return Object.assign({}, state); + } + case GeneralActions.UPDATE_AIC_ZONES: { + Object.assign(state, (<UpdateAicZonesAction>action)); + return Object.assign({}, state); + } + case GeneralActions.UPDATE_PRODUCT_FAMILIES: { + Object.assign(state, (<UpdateProductFamiliesAction>action)); + return Object.assign({}, state); + } + case GeneralActions.UPDATE_NETWORK_FUNCTION: { + const networkFunctionReduxObj = state['networkFunctions'] == undefined ? {} : state['networkFunctions']; + networkFunctionReduxObj[(<UpdateNetworkCollectionFunction>action).network_function] = (<UpdateNetworkCollectionFunction>action).networksAccordingToNetworkCollection; + Object.assign(state, {'networkFunctions': networkFunctionReduxObj}); + return Object.assign({}, state); + } + case GeneralActions.UPDATE_SERVICE_TYPES: { + state.serviceTypes[(<UpdateServiceTypesAction>action).subscriberId] = (<UpdateServiceTypesAction>action).serviceTypes; + return Object.assign({}, state); + } + case GeneralActions.UPDATE_CATEGORY_PARAMETERS: { + Object.assign(state, (<UpdateCategoryParametersAction>action)); + return Object.assign({}, state); + } + case GeneralActions.UPDATE_USER_ID: { + const updateUserId: UpdateUserIdAction = <UpdateUserIdAction>action; + let newState = _.cloneDeep(state); + newState['userId'] = updateUserId.userId; + return newState; + } + case GeneralActions.REMOVE_INSTANCE: { + const actionData = (<RemoveInstanceAction>action); + if (state.serviceInstance[actionData.serviceModelId]) { + const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(actionData.node); + updateIsMissingDataOnDelete(state, actionData.serviceModelId, actionData.storeKey, actionData.node); + updateUniqueNames(state.serviceInstance[actionData.serviceModelId][typeNodeInformation.hierarchyName][actionData.storeKey].instanceName, null, state.serviceInstance[actionData.serviceModelId]); + if(actionData.node.data.type === 'VF'){ + _.forOwn(state.serviceInstance[actionData.serviceModelId][typeNodeInformation.hierarchyName][actionData.storeKey].vfModules, (vfModuleMap) => { + _.forOwn(vfModuleMap, (vfModuleInstance) => { + updateUniqueNames(vfModuleInstance.instanceName, null, state.serviceInstance[actionData.serviceModelId]); + }) + }); + } + delete state.serviceInstance[actionData.serviceModelId][typeNodeInformation.hierarchyName][actionData.storeKey]; + } + return Object.assign({}, state); + } + + case GeneralActions.CHANGE_INSTANCE_COUNTER : { + const changeInstanceCounterAction = <ChangeInstanceCounterAction>action; + const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(changeInstanceCounterAction.node); + let newState = _.cloneDeep(state); + + let existing: number = getExistingCounter(newState, changeInstanceCounterAction.serviceUUID, changeInstanceCounterAction.UUID, typeNodeInformation); + newState.serviceInstance[changeInstanceCounterAction.serviceUUID][typeNodeInformation.existingMappingCounterName][changeInstanceCounterAction.UUID] = existing ? existing + changeInstanceCounterAction.changeBy : changeInstanceCounterAction.changeBy; + return newState; + } + + case GeneralActions.DUPLICATE_BULK_INSTANCES : { + const createInstanceAction = <DuplicateBulkInstancesAction>action; + const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(createInstanceAction.node); + const serviceId = createInstanceAction.serviceId; + const objects = createInstanceAction.objects; + + let newState = _.cloneDeep(state); + newState.serviceInstance[serviceId].existingNames = createInstanceAction.existingNames; + newState.serviceInstance[serviceId][typeNodeInformation.hierarchyName] = Object.assign({}, newState.serviceInstance[serviceId][typeNodeInformation.hierarchyName], objects); + return newState; + } + } +} + +const getExistingCounter = (state: any, serviceModelId: string, modelId: string, typeNodeInformation : TypeNodeInformation ) : number => { + const serviceExistingCounterMap = state.serviceInstance[serviceModelId][typeNodeInformation.existingMappingCounterName]; + if(serviceExistingCounterMap && !_.isNil(serviceExistingCounterMap[modelId])){ + return serviceExistingCounterMap[modelId]; + }else { + return null; + } +}; + +const updateIsMissingDataOnDelete = (state: any, serviceModelId: string, storeKey: string, node: ITreeNode): void => { + const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node); + let vnf = state.serviceInstance[serviceModelId][typeNodeInformation.hierarchyName][storeKey]; + if(node.children){ + _.forOwn(vnf.vfModules, (vfModules, vfModulesKey) => { + updateIsMissingDataOnDeleteVFModule(state, serviceModelId, storeKey, vfModulesKey); + }); + } + + + let isMissingData: boolean = state.serviceInstance[serviceModelId][typeNodeInformation.hierarchyName][storeKey].isMissingData; + updateServiceValidationCounter(state, isMissingData, false, serviceModelId); +}; + +const updateUniqueNames = (oldName : string, newName : string, serviceInstance : ServiceInstance) : void => { + let existingNames = serviceInstance.existingNames; + if (!_.isNil(oldName) && oldName.toLowerCase() in existingNames) { + delete existingNames[oldName.toLowerCase()]; + } + if(!_.isNil(newName)) { + existingNames[newName.toLowerCase()] = ""; + } +}; + +const updateIsMissingDataOnDeleteVFModule = (state: any, serviceModelId: string, vnfStoreKey: string, vfModuleName): void => { + const vfModules = state.serviceInstance[serviceModelId].vnfs[vnfStoreKey].vfModules[vfModuleName]; + + _.forOwn(vfModules, (vfModuleInstance) => { + let isMissingData: boolean = vfModuleInstance.isMissingData; + updateServiceValidationCounter(state, isMissingData, false, serviceModelId); + }); +}; + +const updateServiceValidationCounter = (newState: any, oldValidationState: boolean, newValidationState: boolean, serviceUuid: string) => { + if (oldValidationState && !newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter--; + } else if (!oldValidationState && newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter++; + } +}; + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.actions.ts new file mode 100644 index 000000000..609ec69f4 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.actions.ts @@ -0,0 +1,37 @@ +import {Action, ActionCreator} from "redux"; + +export enum GlobalActions { + UPDATE_NAME = 'UPDATE_NAME', + UPDATE_FLAGS = 'UPDATE_FLAGS', + UPDATE_DRAWING_BOARD_STATUS = 'UPDATE_DRAWING_BOARD_STATUS' +} + +export interface UpdateGlobalAction extends Action { + name?: string; +} + +export interface UpdateFlagsAction extends Action { + flags?: any; +} + +export interface UpdateDrawingBoardStatusAction extends Action{ + drawingBoardStatus?: any; +} + +export const updateName: ActionCreator<UpdateGlobalAction> = + (name) => ({ + type: GlobalActions.UPDATE_NAME, + name: name + }); + +export const updateFlags: ActionCreator<UpdateFlagsAction> = + (flags) => ({ + type: GlobalActions.UPDATE_FLAGS, + flags: flags + }); + +export const updateDrawingBoardStatus: ActionCreator<UpdateDrawingBoardStatusAction> = + (drawingBoardStatus) => ({ + type: GlobalActions.UPDATE_DRAWING_BOARD_STATUS, + drawingBoardStatus: drawingBoardStatus + }); diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.reducers.spec.ts new file mode 100644 index 000000000..4fc80863a --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.reducers.spec.ts @@ -0,0 +1,48 @@ +import {GlobalActions, UpdateFlagsAction, UpdateGlobalAction, UpdateDrawingBoardStatusAction} from "./global.actions"; +import {globalReducer} from "./global.reducers"; + + +describe('globalReducer', () => { + + test('#UPDATE_FLAGS : should update global flags', () => { + const flags = { + 'A' : 'A', + 'B' : 'B', + 'C' : 'C', + 'D' : 'D' + }; + let flagsState = globalReducer(<any>{global : {}}, + <UpdateFlagsAction>{ + type: GlobalActions.UPDATE_FLAGS, + flags : flags + }).flags; + + expect(flagsState).toBeDefined(); + expect(<any>flagsState).toEqual(<any>flags); + }); + + test('#UPDATE_NAME : should update global name', () => { + const name = 'name'; + let globalState = globalReducer(<any>{global : {}}, + <UpdateGlobalAction>{ + type: GlobalActions.UPDATE_NAME, + name : name + }); + expect(globalState).toBeDefined(); + expect(globalState.name).toEqual(name); + }); + + test('#UPDATE_DRAWING_BOARD_STATUS : should update global drawing board status', ()=> { + const drawingBoardStatus = 'EDIT'; + let globalDrawingBoardState = globalReducer(<any>{global : {}}, + <UpdateDrawingBoardStatusAction>{ + type: GlobalActions.UPDATE_DRAWING_BOARD_STATUS, + drawingBoardStatus : drawingBoardStatus + }); + expect(globalDrawingBoardState).toBeDefined(); + expect(globalDrawingBoardState.drawingBoardStatus).toEqual(drawingBoardStatus); + }); +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.reducers.ts new file mode 100644 index 000000000..f9e083414 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/global/global.reducers.ts @@ -0,0 +1,29 @@ +import {Action} from 'redux'; +import {GlobalActions, UpdateFlagsAction, UpdateGlobalAction, UpdateDrawingBoardStatusAction} from "./global.actions"; + +export interface GlobalState { + name : string; + flags : { [key: string]: boolean }; + drawingBoardStatus : string; +} + +const initialState: GlobalState = { + name : null, + flags : null, + drawingBoardStatus : null +}; + +export const globalReducer = + function (state: GlobalState = initialState, action: Action): GlobalState { + switch (action.type) { + case GlobalActions.UPDATE_NAME: + return Object.assign(state, state, (<UpdateGlobalAction>action)); + case GlobalActions.UPDATE_FLAGS: + Object.assign(state, (<UpdateFlagsAction>action)); + return Object.assign({}, state); + case GlobalActions.UPDATE_DRAWING_BOARD_STATUS: + return Object.assign(state, state, (<UpdateDrawingBoardStatusAction>action)); + default: + return state; + } + }; diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/main.reducer.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/main.reducer.ts new file mode 100644 index 000000000..2166c81a0 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/main.reducer.ts @@ -0,0 +1,67 @@ +import {LcpRegionsAndTenants} from "../../models/lcpRegionsAndTenants"; +import {CategoryParams} from "../../models/categoryParams"; +import {Action} from "redux"; +import {ServiceActions} from "./service/service.actions"; +import {GeneralActions} from "./general/general.actions"; +import {NetworkActions} from "./network/network.actions"; +import {VfModuleActions} from "./vfModule/vfModule.actions"; +import {VNFActions} from "./vnf/vnf.actions"; +import {vnfReducer} from "./vnf/vnf.reducers"; +import {generalReducer} from "./general/general.reducers"; +import {serviceReducer} from "./service/service.reducers"; +import {networkReducer} from "./network/network.reducers"; +import {vfModuleReducer} from "./vfModule/vfModule.reducers"; +import {ServiceInstance} from "../../models/serviceInstance"; +import {SelectOptionInterface} from "../../models/selectOption"; +import {ServiceType} from "../../models/serviceType"; +import {VnfGroupActions} from "./vnfGroup/vnfGroup.actions"; +import {vnfGroupReducer} from "./vnfGroup/vnfGroup.reducers"; +import {RelatedVnfActions} from "./relatedVnfMember/relatedVnfMember.actions"; +import {relatedVnfMemeberReducer} from "./relatedVnfMember/relatedVnfMember.reducers"; + +export let initialState: ServiceState = { + serviceHierarchy: {}, + serviceInstance: {}, + lcpRegionsAndTenants: new LcpRegionsAndTenants(), + subscribers: null, + productFamilies: null, + serviceTypes: {}, + aicZones: null, + categoryParameters: new CategoryParams() +}; + + +export interface ServiceState { + serviceHierarchy: any; + serviceInstance: { [uuid: string]: ServiceInstance; }; + lcpRegionsAndTenants: LcpRegionsAndTenants; + subscribers: SelectOptionInterface[]; + productFamilies: any; + serviceTypes: { [subscriberId: string]: ServiceType[]; }; + aicZones: SelectOptionInterface[]; + categoryParameters: CategoryParams; +} + +export const MainReducer = function (state: ServiceState = initialState, action: Action): ServiceState { + console.info("action name", action.type); + if(Object.values(ServiceActions).includes(action.type)){ + return serviceReducer(state, action); + }else if (Object.values(GeneralActions).includes(action.type)){ + return generalReducer(state, action); + }else if (Object.values(NetworkActions).includes(action.type)){ + return networkReducer(state, action); + }else if (Object.values(VfModuleActions).includes(action.type)){ + return vfModuleReducer(state, action); + }else if (Object.values(VNFActions).includes(action.type)){ + return vnfReducer(state, action); + }else if (Object.values(VnfGroupActions).includes(action.type)){ + return vnfGroupReducer(state, action); + }else if(Object.values(RelatedVnfActions).includes(action.type)){ + return relatedVnfMemeberReducer(state, action); + } else { + return Object.assign({}, state); + } +}; + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.actions.ts new file mode 100644 index 000000000..c90d8eb3d --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.actions.ts @@ -0,0 +1,94 @@ +import {Action, ActionCreator} from "redux"; +import {NetworkInstance} from "../../../models/networkInstance"; + +export enum NetworkActions { + UPDATE_NETWORK_INSTANCE = "UPDATE_NETWORK_INSTANCE", + UPDATE_NETWORK_FUNCTION = 'UPDATE_NETWORK_FUNCTION', + CREATE_NETWORK_INSTANCE = 'CREATE_NETWORK_INSTANCE', + DELETE_ACTION_NETWORK_INSTANCE = "DELETE_ACTION_NETWORK_INSTANCE", + UNDO_DELETE_ACTION_NETWORK_INSTANCE = "UNDO_DELETE_ACTION_NETWORK_INSTANCE", + UPDATE_NETWORK_POSITION = "UPDATE_NETWORK_POSITION" + +} + + +export interface UpdateNetworkPosition extends Action { + node: any, + instanceId : string, + networkStoreKey?: string; +} + +export interface UpdateNetworkInstanceAction extends Action { + networkInstance?: NetworkInstance; + networkModelName?: string; + serviceUuid?: string; + networkStoreKey?:string; +} + +export interface UpdateNetworkCollectionFunction extends Action { + networksAccordingToNetworkCollection: any; + network_function: any; +} + +export interface CreateNetworkInstanceAction extends Action { + networkInstance?: NetworkInstance; + networkModelName?: string; + serviceUuid?: string; + networkStoreKey?:string; +} + +export interface DeleteActionNetworkInstanceAction extends Action { + networkStoreKey: string; + serviceId?: string; +} + +export interface UndoDeleteActionNetworkInstanceAction extends Action { + networkStoreKey: string; + serviceId?: string; +} + +export const updateNetworkInstance: ActionCreator<UpdateNetworkInstanceAction> = (networkInstance, networkfModelName, serviceUuid, networkStoreKey) => ({ + type: NetworkActions.UPDATE_NETWORK_INSTANCE, + networkInstance: networkInstance, + networkModelName: networkfModelName, + serviceUuid: serviceUuid, + networkStoreKey : networkStoreKey +}); + + +export const updateNetworkCollectionFunction: ActionCreator<UpdateNetworkCollectionFunction> = (ncf, networksAccordingToNetworkCollection) => ({ + type: NetworkActions.UPDATE_NETWORK_FUNCTION, + networksAccordingToNetworkCollection: networksAccordingToNetworkCollection["results"], + network_function: ncf +}); + +export const createNetworkInstance: ActionCreator<CreateNetworkInstanceAction> = (networkInstance, networkModelName, serviceUuid, networkStoreKey) => ({ + type: NetworkActions.CREATE_NETWORK_INSTANCE, + networkInstance: networkInstance, + networkModelName: networkModelName, + serviceUuid: serviceUuid, + networkStoreKey : networkStoreKey +}); + + +export const deleteActionNetworkInstance: ActionCreator<DeleteActionNetworkInstanceAction> = (networkStoreKey, serviceId) => ({ + type: NetworkActions.DELETE_ACTION_NETWORK_INSTANCE, + networkStoreKey: networkStoreKey, + serviceId: serviceId +}); + +export const undoDeleteActionNetworkInstance: ActionCreator<UndoDeleteActionNetworkInstanceAction> = (networkStoreKey, serviceId) => ({ + type: NetworkActions.UNDO_DELETE_ACTION_NETWORK_INSTANCE, + networkStoreKey: networkStoreKey, + serviceId: serviceId +}); + + +export const updateNetworkPosition: ActionCreator<UpdateNetworkPosition> = (node, instanceId, networkStoreKey) => ({ + type: NetworkActions.UPDATE_NETWORK_POSITION, + node: node, + instanceId: instanceId, + networkStoreKey : networkStoreKey +}); + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.reducers.spec.ts new file mode 100644 index 000000000..ba41ad6e6 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.reducers.spec.ts @@ -0,0 +1,114 @@ +import {networkReducer} from "./network.reducers"; +import { + CreateNetworkInstanceAction, DeleteActionNetworkInstanceAction, + NetworkActions, UndoDeleteActionNetworkInstanceAction, + UpdateNetworkCollectionFunction, + UpdateNetworkInstanceAction +} from "./network.actions"; +import {NetworkInstance} from "../../../models/networkInstance"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + + +describe('networkReducer', () => { + test('#CREATE_SERVICE_INSTANCE', () => { + let networkInstance: NetworkInstance = new NetworkInstance(); + networkInstance.isMissingData = false; + networkInstance.instanceName = 'instanceName'; + let networkState = networkReducer(<any>{serviceInstance : { + 'serviceModelId' : { + networks : { + 'networkStoreKey' : { + isMissingData : true + } + } + } + }}, + <UpdateNetworkInstanceAction>{ + type: NetworkActions.UPDATE_NETWORK_INSTANCE, + networkInstance : new NetworkInstance(), + networkStoreKey : 'networkStoreKey', + networkModelName : 'networkModelName', + serviceUuid : 'serviceModelId' + }).serviceInstance['serviceModelId'].networks['networkStoreKey']; + + expect(networkState).toBeDefined(); + expect(networkState.isMissingData).toBeFalsy(); + }); + + test('#CREATE_NETWORK_INSTANCE', () => { + let networkInstance: NetworkInstance = new NetworkInstance(); + networkInstance.isMissingData = false; + networkInstance.instanceName = 'instanceName'; + let networkState = networkReducer(<any>{serviceInstance : { + 'serviceModelId' : { + networks : {} + } + }}, + <CreateNetworkInstanceAction>{ + type: NetworkActions.CREATE_NETWORK_INSTANCE, + networkInstance : new NetworkInstance(), + networkStoreKey : null, + networkModelName : 'networkModelName', + serviceUuid : 'serviceModelId' + }).serviceInstance['serviceModelId'].networks['networkModelName']; + + expect(networkState).toBeDefined(); + expect(networkState.isMissingData).toBeFalsy(); + }); + + test('#UPDATE_NETWORK_FUNCTION', () => { + let state = networkReducer(<any>{serviceInstance : {}}, + <UpdateNetworkCollectionFunction>{ + type: NetworkActions.UPDATE_NETWORK_FUNCTION, + networksAccordingToNetworkCollection: 'networksAccordingToNetworkCollection', + network_function: 'network_function' + }); + + expect(state).toBeDefined(); + }); + + test('#DELETE_ACTION_NETWORK_INSTANCE', () => { + let networkState = networkReducer(<any>{serviceInstance : { + 'serviceModelId' : { + networks : { + 'networkStoreKey' : { + isMissingData : true, + action : 'None' + } + } + } + }}, + <DeleteActionNetworkInstanceAction>{ + type: NetworkActions.DELETE_ACTION_NETWORK_INSTANCE, + networkStoreKey: 'networkStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].networks['networkStoreKey']; + + expect(networkState).toBeDefined(); + expect(networkState.action).toEqual(ServiceInstanceActions.None_Delete); + }); + + test('#UNDO_DELETE_ACTION_NETWORK_INSTANCE', () => { + let networkState = networkReducer(<any>{serviceInstance : { + 'serviceModelId' : { + networks : { + 'networkStoreKey' : { + isMissingData : true, + action : 'Update_Delete' + } + } + } + }}, + <UndoDeleteActionNetworkInstanceAction>{ + type: NetworkActions.UNDO_DELETE_ACTION_NETWORK_INSTANCE, + networkStoreKey: 'networkStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].networks['networkStoreKey']; + + expect(networkState).toBeDefined(); + expect(networkState.action).toEqual(ServiceInstanceActions.Update); + }); +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.reducers.ts new file mode 100644 index 000000000..bcbbea57d --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/network/network.reducers.ts @@ -0,0 +1,102 @@ +import {Action} from "redux"; +import * as _ from "lodash"; +import {NetworkInstance} from "../../../models/networkInstance"; +import { + CreateNetworkInstanceAction, DeleteActionNetworkInstanceAction, + NetworkActions, UndoDeleteActionNetworkInstanceAction, + UpdateNetworkCollectionFunction, + UpdateNetworkInstanceAction +} from "./network.actions"; +import {ServiceInstance} from "../../../models/serviceInstance"; +import {calculateNextUniqueModelName} from "../vnf/vnf.reducers"; +import {ServiceState} from "../main.reducer"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + + +export function networkReducer(state: ServiceState , action: Action) : ServiceState { + switch (action.type) { + case NetworkActions.CREATE_NETWORK_INSTANCE: { + const updateNetworkInstanceAction = <CreateNetworkInstanceAction>action; + const serviceUuid = updateNetworkInstanceAction.serviceUuid; + let networkModelName = updateNetworkInstanceAction.networkModelName; + + + let newState = _.cloneDeep(state); + + updateNetworkInstanceAction.networkInstance.originalName = networkModelName; + updateNetworkInstanceAction.networkModelName = calculateNextUniqueModelName(networkModelName, serviceUuid, newState, 'networks'); + + let networkInstance: NetworkInstance = newState.serviceInstance[serviceUuid].networks[networkModelName]; + networkInstance = new NetworkInstance(); + updateNetworkInstanceAction.networkInstance.networkStoreKey = updateNetworkInstanceAction.networkModelName; + updateNetworkInstanceAction.networkInstance.originalName = networkModelName; + networkInstance.originalName = updateNetworkInstanceAction.networkInstance.originalName; + networkInstance.networkStoreKey = updateNetworkInstanceAction.networkInstance.networkStoreKey; + updateServiceValidationCounter(newState, networkInstance['isMissingData'], updateNetworkInstanceAction.networkInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].networks[updateNetworkInstanceAction.networkModelName] = Object.assign(networkInstance, updateNetworkInstanceAction.networkInstance); + return newState; + } + case NetworkActions.UPDATE_NETWORK_INSTANCE: { + const updateNetworkInstanceAction = <UpdateNetworkInstanceAction>action; + const serviceUuid = updateNetworkInstanceAction.serviceUuid; + let networkStoreKey = updateNetworkInstanceAction.networkStoreKey; + + let newState = _.cloneDeep(state); + let networkInstance: NetworkInstance = newState.serviceInstance[serviceUuid].networks[networkStoreKey]; + updateUniqueNames(networkInstance? networkInstance.instanceName : null, updateNetworkInstanceAction.networkInstance.instanceName, newState.serviceInstance[serviceUuid]); + + networkInstance = networkInstance || new NetworkInstance(); + updateServiceValidationCounter(newState, networkInstance['isMissingData'], updateNetworkInstanceAction.networkInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].networks[networkStoreKey] = Object.assign(networkInstance, updateNetworkInstanceAction.networkInstance); + return newState; + } + case NetworkActions.UPDATE_NETWORK_FUNCTION: { + let networkFunctionReduxObj = state['networkFunctions'] == undefined ? {} : state['networkFunctions']; + networkFunctionReduxObj[(<UpdateNetworkCollectionFunction>action).network_function] = (<UpdateNetworkCollectionFunction>action).networksAccordingToNetworkCollection; + Object.assign(state, {'networkFunctions': networkFunctionReduxObj}); + return Object.assign({}, state); + } + case NetworkActions.DELETE_ACTION_NETWORK_INSTANCE : { + let newState = _.cloneDeep(state); + let network = newState.serviceInstance[(<DeleteActionNetworkInstanceAction>action).serviceId].networks[(<DeleteActionNetworkInstanceAction>action).networkStoreKey]; + let oldAction = network.action; + if(oldAction === ServiceInstanceActions.None_Delete || oldAction === ServiceInstanceActions.Update_Delete) return newState; + newState.serviceInstance[(<DeleteActionNetworkInstanceAction>action).serviceId].networks[(<DeleteActionNetworkInstanceAction>action).networkStoreKey].action = (oldAction + '_Delete') as ServiceInstanceActions; + updateServiceValidationCounter(newState, network['isMissingData'], false , (<DeleteActionNetworkInstanceAction>action).serviceId); + + return newState; + } + + case NetworkActions.UNDO_DELETE_ACTION_NETWORK_INSTANCE : { + let newState = _.cloneDeep(state); + let network = newState.serviceInstance[(<UndoDeleteActionNetworkInstanceAction>action).serviceId].networks[(<UndoDeleteActionNetworkInstanceAction>action).networkStoreKey]; + let oldState = network.action; + newState.serviceInstance[(<UndoDeleteActionNetworkInstanceAction>action).serviceId].networks[(<UndoDeleteActionNetworkInstanceAction>action).networkStoreKey].action = (oldState.split('_')[0]) as ServiceInstanceActions; + updateServiceValidationCounter(newState, network['isMissingData'], false , (<DeleteActionNetworkInstanceAction>action).serviceId); + return newState; + } + } +} + +const updateUniqueNames = (oldName : string, newName : string, serviceInstance : ServiceInstance) : void => { + let existingNames = serviceInstance.existingNames; + if (!_.isNil(oldName) && oldName.toLowerCase() in existingNames) { + delete existingNames[oldName.toLowerCase()]; + } + if(!_.isNil(newName)) { + existingNames[newName.toLowerCase()] = ""; + } +}; + + +const updateServiceValidationCounter = (newState: any, oldValidationState: boolean, newValidationState: boolean, serviceUuid: string) => { + if (oldValidationState && !newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter--; + } else if (!oldValidationState && newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter++; + } +}; + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions.ts new file mode 100644 index 000000000..faa7a52d3 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions.ts @@ -0,0 +1,68 @@ +import {Action, ActionCreator} from "redux"; + +export enum RelatedVnfActions { + CREATE_RELATED_VNF_MEMBER_INSTANCE = "CREATE_RELATED_VNF_MEMBER_INSTANCE", + REMOVE_RELATED_VNF_MEMBER_INSTANCE = "REMOVE_RELATED_VNF_MEMBER_INSTANCE", + DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE = "DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE", + UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE = "UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE" +} + +export interface RemoveRelatedVnfMemebrInstance extends Action { + vnfGroupStoreKey: string; + relatedVnfMemeberStoreKey: string; + serviceId?: string; +} + +export interface DeleteRelatedVnfMemebrInstanceAction extends Action { + vnfGroupStoreKey: string; + relatedVnfMemeberStoreKey: string; + serviceId?: string; +} + +export interface DeleteActionRelatedVnfMemeberInstanceAction extends Action { + vnfGroupStoreKey: string; + relatedVnfMemeberStoreKey: string; + serviceId?: string; +} + +export interface UndoDeleteActionRelatedVnfMemeberInstanceAction extends Action { + vnfGroupStoreKey: string; + relatedVnfMemeberStoreKey: string; + serviceId?: string; +} + +export interface CreateRelatedVnfMemeberInstanceAction extends Action { + relatedVnfMember: any; + vnfGroupStoreKey: string; + serviceId?: string; +} + + +export const removeRelatedVnfMemberInstance: ActionCreator<RemoveRelatedVnfMemebrInstance> = (vnfGroupStoreKey, relatedVnfMemeberStoreKey, serviceId) => ({ + type: RelatedVnfActions.REMOVE_RELATED_VNF_MEMBER_INSTANCE, + vnfGroupStoreKey: vnfGroupStoreKey, + relatedVnfMemeberStoreKey: relatedVnfMemeberStoreKey, + serviceId: serviceId +}); + +export const deleteActionRelatedVnfMemberInstance: ActionCreator<DeleteActionRelatedVnfMemeberInstanceAction> = (vnfGroupStoreKey, relatedVnfMemeberStoreKey, serviceId) => ({ + type: RelatedVnfActions.DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE, + vnfGroupStoreKey: vnfGroupStoreKey, + relatedVnfMemeberStoreKey: relatedVnfMemeberStoreKey, + serviceId: serviceId +}); + +export const undoDeleteActionRelatedVnfMemberInstance: ActionCreator<UndoDeleteActionRelatedVnfMemeberInstanceAction> = (vnfGroupStoreKey, relatedVnfMemeberStoreKey, serviceId) => ({ + type: RelatedVnfActions.UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE, + vnfGroupStoreKey: vnfGroupStoreKey, + relatedVnfMemeberStoreKey: relatedVnfMemeberStoreKey, + serviceId: serviceId +}); + + +export const createRelatedVnfMemberInstance: ActionCreator<CreateRelatedVnfMemeberInstanceAction> = (vnfGroupStoreKey, serviceId, relatedVnfMember) => ({ + type: RelatedVnfActions.CREATE_RELATED_VNF_MEMBER_INSTANCE, + relatedVnfMember: relatedVnfMember, + vnfGroupStoreKey: vnfGroupStoreKey, + serviceId: serviceId +}); diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.reducers.spec.ts new file mode 100644 index 000000000..347957480 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.reducers.spec.ts @@ -0,0 +1,153 @@ +import {relatedVnfMemeberReducer} from "./relatedVnfMember.reducers"; +import { + CreateRelatedVnfMemeberInstanceAction, + DeleteActionRelatedVnfMemeberInstanceAction, + RelatedVnfActions, + UndoDeleteActionRelatedVnfMemeberInstanceAction +} from "./relatedVnfMember.actions"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + + +describe('relatedVnfMemberReducer', () => { + + test('#DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE should change action to delete',() => { + const serviceUuid: string = 'serviceUuid'; + const actionName: ServiceInstanceActions = ServiceInstanceActions.None; + + let service = relatedVnfMemeberReducer(<any>{ + serviceInstance: { + 'serviceUuid': { + 'vnfGroups' : { + 'vnfGroupStoreKey' : { + 'vnfs' : { + 'vnfStoreKey1' : { + 'action' : actionName + } + } + } + + } + } + } + }, <DeleteActionRelatedVnfMemeberInstanceAction>{ + type: RelatedVnfActions.DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE, + vnfGroupStoreKey: 'vnfGroupStoreKey', + relatedVnfMemeberStoreKey : 'vnfStoreKey1', + serviceId : 'serviceUuid' + }); + + expect(service.serviceInstance[serviceUuid].vnfGroups['vnfGroupStoreKey']['vnfs']['vnfStoreKey1'].action).toEqual('None_Delete'); + }); + + test('#UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE should undo change action to delete', () => { + const serviceUuid: string = 'serviceUuid'; + const actionName: ServiceInstanceActions = ServiceInstanceActions.None_Delete; + + let service = relatedVnfMemeberReducer(<any>{ + serviceInstance: { + 'serviceUuid': { + 'vnfGroups' : { + 'vnfGroupStoreKey' : { + 'vnfs' : { + 'vnfStoreKey1' : { + 'action' : actionName + } + } + } + + } + } + } + }, <UndoDeleteActionRelatedVnfMemeberInstanceAction>{ + type: RelatedVnfActions.UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE, + vnfGroupStoreKey: 'vnfGroupStoreKey', + relatedVnfMemeberStoreKey : 'vnfStoreKey1', + serviceId : 'serviceUuid' + }); + + expect(service.serviceInstance[serviceUuid].vnfGroups['vnfGroupStoreKey']['vnfs']['vnfStoreKey1'].action).toEqual('None'); + }); + + test('#REMOVE_RELATED_VNF_MEMBER_INSTANCE should remove instance', () => { + const serviceUuid: string = 'serviceUuid'; + const actionName: ServiceInstanceActions = ServiceInstanceActions.None_Delete; + + let service = relatedVnfMemeberReducer(<any>{ + serviceInstance: { + 'serviceUuid': { + 'vnfGroups' : { + 'vnfGroupStoreKey' : { + 'vnfs' : { + 'vnfStoreKey1' : { + 'action' : actionName + } + } + } + + } + } + } + }, <UndoDeleteActionRelatedVnfMemeberInstanceAction>{ + type: RelatedVnfActions.UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE, + vnfGroupStoreKey: 'vnfGroupStoreKey', + relatedVnfMemeberStoreKey : 'vnfStoreKey1', + serviceId : 'serviceUuid' + }); + + expect(service.serviceInstance[serviceUuid].vnfGroups['vnfGroupStoreKey']['vnfs']['vnfStoreKey1'].action).toEqual('None'); + }); + + test('#CREATE_RELATED_VNF_MEMBER_INSTANCE should add new relatedVNF instance', () => { + const serviceUuid: string = 'serviceUuid'; + const actionName: ServiceInstanceActions = ServiceInstanceActions.None_Delete; + let relatedVnfMember = { + "instanceName":"VNF1_INSTANCE_NAME", + "instanceId":"VNF1_INSTANCE_ID", + "orchStatus":null, + "productFamilyId":null, + "lcpCloudRegionId":"mtn23b", + "tenantId":"3e9a20a3e89e45f884e09df0cc2d2d2a", + "tenantName":"APPC-24595-T-IST-02C", + "modelInfo":{ + "modelInvariantId":"vnf-instance-model-invariant-id", + "modelVersionId":"7a6ee536-f052-46fa-aa7e-2fca9d674c44", + "modelVersion":"2.0", + "modelName":"vf_vEPDG", + "modelType":"vnf" + }, + "instanceType":"VNF1_INSTANCE_TYPE", + "provStatus":null, + "inMaint":false, + "uuid":"7a6ee536-f052-46fa-aa7e-2fca9d674c44", + "originalName":null, + "legacyRegion":null, + "lineOfBusiness":null, + "platformName":null, + "trackById":"7a6ee536-f052-46fa-aa7e-2fca9d674c44:002", + "serviceInstanceId":"service-instance-id1", + "serviceInstanceName":"service-instance-name" + }; + + let service = relatedVnfMemeberReducer(<any>{ + serviceInstance: { + 'serviceUuid': { + 'vnfGroups' : { + 'vnfGroupStoreKey' : { } + } + } + } + }, <CreateRelatedVnfMemeberInstanceAction>{ + type: RelatedVnfActions.CREATE_RELATED_VNF_MEMBER_INSTANCE, + relatedVnfMember: relatedVnfMember, + vnfGroupStoreKey: 'vnfGroupStoreKey', + serviceId: serviceUuid + }); + + expect(service.serviceInstance[serviceUuid].vnfGroups['vnfGroupStoreKey']['vnfs']['VNF1_INSTANCE_ID'].action).toEqual('Create'); + expect(service.serviceInstance[serviceUuid].vnfGroups['vnfGroupStoreKey']['vnfs']['VNF1_INSTANCE_ID'].instanceId).toEqual('VNF1_INSTANCE_ID'); + }); + +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.reducers.ts new file mode 100644 index 000000000..250f934be --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.reducers.ts @@ -0,0 +1,58 @@ +import {Action} from "redux"; +import * as _ from "lodash"; +import {ServiceState} from "../main.reducer"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; +import { + CreateRelatedVnfMemeberInstanceAction, + DeleteActionRelatedVnfMemeberInstanceAction, DeleteRelatedVnfMemebrInstanceAction, + RelatedVnfActions, + UndoDeleteActionRelatedVnfMemeberInstanceAction +} from "./relatedVnfMember.actions"; + +export function relatedVnfMemeberReducer(state: ServiceState, action: Action): ServiceState { + switch (action.type) { + + case RelatedVnfActions.DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE : { + let newState = _.cloneDeep(state); + let relatedVnfMember = newState.serviceInstance[(<DeleteActionRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<DeleteActionRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'][(<DeleteActionRelatedVnfMemeberInstanceAction>action).relatedVnfMemeberStoreKey]; + let oldAction = relatedVnfMember.action; + if(oldAction === ServiceInstanceActions.None_Delete || oldAction === ServiceInstanceActions.Update_Delete) return newState; + newState.serviceInstance[(<DeleteActionRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<DeleteActionRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'][(<DeleteActionRelatedVnfMemeberInstanceAction>action).relatedVnfMemeberStoreKey].action = (oldAction + '_Delete') as ServiceInstanceActions; + return newState; + } + + case RelatedVnfActions.UNDO_DELETE_ACTION_RELATED_VNF_MEMBER_INSTANCE : { + let newState = _.cloneDeep(state); + let relatedVnfMember = newState.serviceInstance[(<UndoDeleteActionRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<UndoDeleteActionRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'][(<UndoDeleteActionRelatedVnfMemeberInstanceAction>action).relatedVnfMemeberStoreKey]; + let oldState = relatedVnfMember.action; + newState.serviceInstance[(<DeleteActionRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<DeleteActionRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'][(<DeleteActionRelatedVnfMemeberInstanceAction>action).relatedVnfMemeberStoreKey].action = (oldState.split('_')[0]) as ServiceInstanceActions; + return newState; + } + + case RelatedVnfActions.REMOVE_RELATED_VNF_MEMBER_INSTANCE : { + let newState = _.cloneDeep(state); + delete newState.serviceInstance[(<DeleteRelatedVnfMemebrInstanceAction>action).serviceId].vnfGroups[(<DeleteRelatedVnfMemebrInstanceAction>action).vnfGroupStoreKey]['vnfs'][(<DeleteRelatedVnfMemebrInstanceAction>action).relatedVnfMemeberStoreKey]; + return newState; + } + + case RelatedVnfActions.CREATE_RELATED_VNF_MEMBER_INSTANCE : { + let newState = _.cloneDeep(state); + let relatedVnfMember = (<CreateRelatedVnfMemeberInstanceAction>action).relatedVnfMember; + relatedVnfMember['action'] = 'Create'; + relatedVnfMember['vnfStoreKey'] = relatedVnfMember.instanceId; + relatedVnfMember['trackById'] = relatedVnfMember.instanceId; + relatedVnfMember['instanceName'] = relatedVnfMember.instanceName; + if(_.isNil(newState.serviceInstance[(<CreateRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<CreateRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'])){ + newState.serviceInstance[(<CreateRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<CreateRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'] = {}; + } + newState.serviceInstance[(<CreateRelatedVnfMemeberInstanceAction>action).serviceId].vnfGroups[(<CreateRelatedVnfMemeberInstanceAction>action).vnfGroupStoreKey]['vnfs'][(<CreateRelatedVnfMemeberInstanceAction>action).relatedVnfMember['instanceId']] = relatedVnfMember; + newState.serviceInstance[(<CreateRelatedVnfMemeberInstanceAction>action).serviceId].isDirty = true; + return newState; + } + } +} + + + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.actions.ts new file mode 100644 index 000000000..e4e7e494e --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.actions.ts @@ -0,0 +1,102 @@ +import {ServiceInstance} from "../../../models/serviceInstance"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; +import {Action, ActionCreator} from "redux"; + +export enum ServiceActions { + CREATE_SERVICE_INSTANCE = 'CREATE_SERVICE_INSTANCE', + UPDATE_SERVICE_INSTANCE = 'UPDATE_SERVICE_INSTANCE', + DELETE_ALL_SERVICE_INSTANCES = 'DELETE_ALL_SERVICE_INSTANCES', + UPDATE_MODEL = 'UPDATE_MODEL', + ADD_SERVICE_ACTION = 'ADD_SERVICE_ACTION', + DELETE_ACTION_SERVICE_INSTANCE = "DELETE_ACTION_SERVICE_INSTANCE", + UNDO_DELETE_ACTION_SERVICE_INSTANCE = "UNDO_DELETE_ACTION_SERVICE_INSTANCE", + CHANGE_SERVICE_IS_DIRTY = "CHANGE_SERVICE_IS_DIRTY" +} + +export interface CreateServiceInstanceAction extends Action { + serviceUuid?: string; + serviceInstance?: ServiceInstance; +} + +export interface UpdateServiceInstanceAction extends Action { + serviceUuid?: string; + serviceInstance?: ServiceInstance; +} + +export interface DeleteServiceInstanceAction extends Action { + serviceUuid?: string; +} + +export interface DeleteServiceInstanceAction extends Action { + serviceUuid?: string; +} + +export interface UpdateServiceModelAction extends Action { + serviceHierarchy?: any; +} + +export interface AddServiceAction extends Action{ + serviceUuid: string; + action: ServiceInstanceActions; +} + + +export interface DeleteActionServiceInstanceAction extends Action { + serviceId?: string; +} + +export interface UndoDeleteActionServiceInstanceAction extends Action { + serviceId?: string; +} + +export interface ChangeServiceDirty extends Action { + nodes: any[]; + serviceId : string; +} + +export const addServiceAction: ActionCreator<AddServiceAction> = (serviceUuid : string, actionName : ServiceInstanceActions) => ({ + type: ServiceActions.ADD_SERVICE_ACTION, + serviceUuid: serviceUuid, + action : actionName +}); + + +export const deleteAllServiceInstances: ActionCreator<DeleteServiceInstanceAction> = () => ({ + type: ServiceActions.DELETE_ALL_SERVICE_INSTANCES +}); + +export const createServiceInstance: ActionCreator<CreateServiceInstanceAction> = (serviceInstance, serviceUuid) => ({ + type: ServiceActions.CREATE_SERVICE_INSTANCE, + serviceInstance: serviceInstance, + serviceUuid: serviceUuid +}); + +export const updateServiceInstance: ActionCreator<UpdateServiceInstanceAction> = (serviceInstance, serviceUuid) => ({ + type: ServiceActions.UPDATE_SERVICE_INSTANCE, + serviceInstance: serviceInstance, + serviceUuid: serviceUuid +}); + +export const updateModel: ActionCreator<UpdateServiceModelAction> = serviceHierarchy => ({ + type: ServiceActions.UPDATE_MODEL, + serviceHierarchy: serviceHierarchy +}); + + +export const deleteActionServiceInstance: ActionCreator<DeleteActionServiceInstanceAction> = (vnfStoreKey, serviceId) => ({ + type: ServiceActions.DELETE_ACTION_SERVICE_INSTANCE, + serviceId: serviceId +}); + +export const undoDeleteActionServiceInstance: ActionCreator<UndoDeleteActionServiceInstanceAction> = (vnfStoreKey, serviceId) => ({ + type: ServiceActions.UNDO_DELETE_ACTION_SERVICE_INSTANCE, + serviceId: serviceId +}); + +export const changeServiceIsDirty: ActionCreator<ChangeServiceDirty> = (nodes, serviceId) => ({ + type: ServiceActions.CHANGE_SERVICE_IS_DIRTY, + nodes: nodes, + serviceId : serviceId +}); + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.reducers.spec.ts new file mode 100644 index 000000000..05fc008ad --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.reducers.spec.ts @@ -0,0 +1,499 @@ +import {ServiceInstance} from "../../../models/serviceInstance"; +import { + AddServiceAction, ChangeServiceDirty, + DeleteServiceInstanceAction, + ServiceActions, + CreateServiceInstanceAction, + UpdateServiceModelAction, UpdateServiceInstanceAction +} from "./service.actions"; +import {serviceReducer} from "./service.reducers"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + +describe('serviceReducer', () => { + + test('#UPDATE_SERVICE_INSTANCE should update exiting instance without change his child', () => { + const serviceUuid: string = 'serviceUuid'; + const actionName: ServiceInstanceActions = ServiceInstanceActions.Create; + + const elemntThatShouldNotOverideOnUpdateService = { + vnfs: { + "2017-388_ADIOD-vPE 0": { + "action": "Create", + "inMaint": false, + "rollbackOnFailure": "true", + "originalName": "2017-388_ADIOD-vPE 0", + "isMissingData": false, + "trackById": "eymgwlevh54", + "vfModules": {}, + "vnfStoreKey": "2017-388_ADIOD-vPE 0", + "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168", + "productFamilyId": "e433710f-9217-458d-a79d-1c7aff376d89", + "lcpCloudRegionId": "JANET25", + "tenantId": "092eb9e8e4b7412e8787dd091bc58e86", + "lineOfBusiness": "ONAP", + "platformName": "platform", + "modelInfo": { + "modelInvariantId": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8", + "modelVersionId": "afacccf6-397d-45d6-b5ae-94c39734b168", + "modelName": "2017-388_ADIOD-vPE", + "modelVersion": "4.0", + "modelCustomizationId": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c", + "modelCustomizationName": "2017-388_ADIOD-vPE 0", + "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168", + "modelUniqueId": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c" + }, + "instanceName": "2017-388_ADIOD-vPEAjXzainstanceName", + "legacyRegion": "some legacy region", + "instanceParams": [ + { + "vnf_config_template_version": "17.2", + "bandwidth_units": "Gbps", + "bandwidth": "10", + "AIC_CLLI": "ATLMY8GA", + "ASN": "AV_vPE", + "vnf_instance_name": "mtnj309me6" + } + ] + }, + "2017-488_ADIOD-vPE 0": { + "action": "Create", + "inMaint": false, + "rollbackOnFailure": "true", + "originalName": "2017-488_ADIOD-vPE 0", + "isMissingData": false, + "trackById": "xr6o2782z7", + "vfModules": { + "2017488_adiodvpe0..2017488AdiodVpe..ADIOD_base_vPE_BV..module-0": { + "2017488_adiodvpe0..2017488AdiodVpe..ADIOD_base_vPE_BV..module-0wmkjw": { + "isMissingData": true, + "sdncPreReload": null, + "modelInfo": { + "modelType": "VFmodule", + "modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091", + "modelVersionId": "f8360508-3f17-4414-a2ed-6bc71161e8db", + "modelName": "2017488AdiodVpe..ADIOD_base_vPE_BV..module-0", + "modelVersion": "5", + "modelCustomizationId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3", + "modelCustomizationName": "2017488AdiodVpe..ADIOD_base_vPE_BV..module-0", + "modelUniqueId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3" + }, + "instanceParams": [ + {} + ], + "trackById": "a19sjb1ez2" + } + } + }, + "vnfStoreKey": "2017-488_ADIOD-vPE 0", + "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09", + "productFamilyId": "e433710f-9217-458d-a79d-1c7aff376d89", + "lcpCloudRegionId": "JANET25", + "tenantId": "092eb9e8e4b7412e8787dd091bc58e86", + "lineOfBusiness": "ONAP", + "platformName": "platform", + "modelInfo": { + "modelInvariantId": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8", + "modelVersionId": "69e09f68-8b63-4cc9-b9ff-860960b5db09", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "5.0", + "modelCustomizationId": "1da7b585-5e61-4993-b95e-8e6606c81e45", + "modelCustomizationName": "2017-488_ADIOD-vPE 0", + "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09", + "modelUniqueId": "1da7b585-5e61-4993-b95e-8e6606c81e45" + }, + "instanceName": "2017-488_ADIOD-vPEVNFinstancename", + "legacyRegion": "some legacy region", + "instanceParams": [ + { + "vnf_config_template_version": "17.2", + "bandwidth_units": "Gbps", + "bandwidth": "10", + "AIC_CLLI": "ATLMY8GA", + "ASN": "AV_vPE", + "vnf_instance_name": "mtnj309me6" + } + ] + } + }, + existingVNFCounterMap: { + "b3c76f73-eeb5-4fb6-9d31-72a889f1811c": 1, + "1da7b585-5e61-4993-b95e-8e6606c81e45": 1 + }, + existingVnfGroupCounterMap: {}, + existingNetworksCounterMap: {}, + optionalGroupMembersMap : {}, + networks : {}, + vnfGroups : {} + }; + + + let service = serviceReducer(<any>{ + "serviceInstance": { + "6b528779-44a3-4472-bdff-9cd15ec93450": { + "action": "Create", + "isDirty": true, + "vnfs": elemntThatShouldNotOverideOnUpdateService.vnfs, + "instanceParams": [ + { + "2017488_adiodvpe0_ASN": "AV_vPE" + } + ], + "validationCounter": 1, + "existingNames": { + "ajxzainstancename": "", + "2017-488_adiod-vpevnfinstancename": "", + "2017-388_adiod-vpeajxzainstancename": "" + }, + "existingVNFCounterMap": elemntThatShouldNotOverideOnUpdateService.existingVNFCounterMap, + "existingVnfGroupCounterMap": elemntThatShouldNotOverideOnUpdateService.existingVnfGroupCounterMap, + "existingNetworksCounterMap": elemntThatShouldNotOverideOnUpdateService.existingNetworksCounterMap, + "optionalGroupMembersMap":elemntThatShouldNotOverideOnUpdateService.optionalGroupMembersMap, + "networks": elemntThatShouldNotOverideOnUpdateService.networks, + "vnfGroups": elemntThatShouldNotOverideOnUpdateService.vnfGroups, + "bulkSize": "3", + "instanceName": "AjXzainstancename", + "globalSubscriberId": "e433710f-9217-458d-a79d-1c7aff376d89", + "subscriptionServiceType": "TYLER SILVIA", + "owningEntityId": "d61e6f2d-12fa-4cc2-91df-7c244011d6fc", + "productFamilyId": "e433710f-9217-458d-a79d-1c7aff376d89", + "lcpCloudRegionId": "hvf6", + "tenantId": "bae71557c5bb4d5aac6743a4e5f1d054", + "aicZoneId": "NFT1", + "projectName": "WATKINS", + "rollbackOnFailure": "true", + "aicZoneName": "NFTJSSSS-NFT1", + "owningEntityName": "WayneHolland", + "testApi": "VNF_API", + "tenantName": "AIN Web Tool-15-D-testalexandria", + "modelInfo": { + "modelInvariantId": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0", + "modelVersionId": "6b528779-44a3-4472-bdff-9cd15ec93450", + "modelName": "action-data", + "modelVersion": "1.0", + "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450", + "modelUniqueId": "6b528779-44a3-4472-bdff-9cd15ec93450" + }, + "isALaCarte": false, + "name": "action-data", + "version": "1.0", + "description": "", + "category": "", + "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450", + "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0", + "serviceType": "", + "serviceRole": "", + "vidNotions": { + "instantiationUI": "legacy", + "modelCategory": "other", + "viewEditUI": "legacy" + }, + "isEcompGeneratedNaming": false, + "isMultiStepDesign": false + } + }, + }, <UpdateServiceInstanceAction>{ + type: ServiceActions.UPDATE_SERVICE_INSTANCE, + serviceUuid: "6b528779-44a3-4472-bdff-9cd15ec93450", + serviceInstance: <any>{ + aicZoneId: "ATL53", + aicZoneName: "AAIATLTE-ATL53", + bulkSize: 1, + category: "", + description: "", + globalSubscriberId: "e433710f-9217-458d-a79d-1c7aff376d89", + instanceName: "yoav", + instanceParams: [{}], + invariantUuid: "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0", + isALaCarte: false, + isEcompGeneratedNaming: false, + isMultiStepDesign: false, + lcpCloudRegionId: "JANET25", + modelInfo: { + modelInvariantId: "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0", + modelVersionId: "6b528779-44a3-4472-bdff-9cd15ec93450", + modelName: "action-data", + modelVersion: "1.0" + }, + name: "action-data", + owningEntityId: "d61e6f2d-12fa-4cc2-91df-7c244011d6fc", + owningEntityName: "WayneHolland", + productFamilyId: "d8a6ed93-251c-47ca-adc9-86671fd19f4c", + projectName: "WATKINS", + rollbackOnFailure: "true", + serviceRole: "", + serviceType: "", + subscriptionServiceType: "TYLER SILVIA", + tenantId: "092eb9e8e4b7412e8787dd091bc58e86", + tenantName: "USP-SIP-IC-24335-T-01", + testApi: "VNF_API", + uuid: "6b528779-44a3-4472-bdff-9cd15ec93450", + version: "1.0", + vidNotions: {instantiationUI: "legacy", modelCategory: "other", viewEditUI: "legacy"} + } + }); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"]).toBeDefined(); + + for(const element in elemntThatShouldNotOverideOnUpdateService){ + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"][element]).toEqual(elemntThatShouldNotOverideOnUpdateService[element]); + } + + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].aicZoneId).toEqual("ATL53"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].owningEntityId).toEqual("d61e6f2d-12fa-4cc2-91df-7c244011d6fc"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].owningEntityName).toEqual("WayneHolland"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].productFamilyId).toEqual("d8a6ed93-251c-47ca-adc9-86671fd19f4c"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].projectName).toEqual("WATKINS"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].rollbackOnFailure).toEqual("true"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].subscriptionServiceType).toEqual("TYLER SILVIA"); + expect(service.serviceInstance["6b528779-44a3-4472-bdff-9cd15ec93450"].tenantId).toEqual("092eb9e8e4b7412e8787dd091bc58e86"); + + }); + + test('#ADD_SERVICE_ACTION should add action to the service', () => { + const serviceUuid: string = 'serviceUuid'; + const actionName: ServiceInstanceActions = ServiceInstanceActions.Create; + + let service = serviceReducer(<any>{ + serviceInstance: { + 'serviceUuid': {} + } + }, <AddServiceAction>{ + type: ServiceActions.ADD_SERVICE_ACTION, + serviceUuid: 'serviceUuid', + action: actionName + }); + expect(service.serviceInstance[serviceUuid]['action']).toEqual(actionName); + }); + + test('#UPDATE_SERVICE_INSTANCE', () => { + const serviceUuid: string = 'serviceUuid'; + + let serviceInstanceObject: ServiceInstance = <any>{ + isDirty: false, + instanceName: 'instanceName', + isEcompGeneratedNaming: false, + globalSubscriberId: 'globalSubscriberId', + productFamilyId: 'productFamilyId', + subscriptionServiceType: 'subscriptionServiceType', + lcpCloudRegionId: 'lcpCloudRegionId', + tenantId: 'tenantId', + tenantName: 'tenantName', + aicZoneId: 'aicZoneId', + aicZoneName: 'aicZoneName', + projectName: 'projectName', + owningEntityId: 'owningEntityId', + owningEntityName: 'owningEntityName', + existingVnfGroupCounterMap: {}, + existingVNFCounterMap: {}, + existingNetworksCounterMap: {}, + pause: false, + bulkSize: 1, + vnfs: {}, + vnfGroups: {}, + networks: {}, + instanceParams: [], + rollbackOnFailure: false, + subscriberName: 'subscriberName', + validationCounter: 0, + existingNames: {}, + action: ServiceInstanceActions.Create + }; + + let serviceState = serviceReducer(<any>{serviceInstance: {}}, + <CreateServiceInstanceAction>{ + type: ServiceActions.CREATE_SERVICE_INSTANCE, + serviceUuid: serviceUuid, + serviceInstance: serviceInstanceObject + }).serviceInstance[serviceUuid]; + + expect(serviceState.instanceName).toEqual(serviceInstanceObject.instanceName); + expect(serviceState.isEcompGeneratedNaming).toEqual(serviceInstanceObject.isEcompGeneratedNaming); + expect(serviceState.globalSubscriberId).toEqual(serviceInstanceObject.globalSubscriberId); + expect(serviceState.productFamilyId).toEqual(serviceInstanceObject.productFamilyId); + expect(serviceState.subscriptionServiceType).toEqual(serviceInstanceObject.subscriptionServiceType); + expect(serviceState.lcpCloudRegionId).toEqual(serviceInstanceObject.lcpCloudRegionId); + expect(serviceState.tenantId).toEqual(serviceInstanceObject.tenantId); + expect(serviceState.tenantName).toEqual(serviceInstanceObject.tenantName); + expect(serviceState.aicZoneId).toEqual(serviceInstanceObject.aicZoneId); + expect(serviceState.aicZoneName).toEqual(serviceInstanceObject.aicZoneName); + expect(serviceState.projectName).toEqual(serviceInstanceObject.projectName); + expect(serviceState.owningEntityId).toEqual(serviceInstanceObject.owningEntityId); + expect(serviceState.owningEntityName).toEqual(serviceInstanceObject.owningEntityName); + expect(serviceState.pause).toEqual(serviceInstanceObject.pause); + expect(serviceState.bulkSize).toEqual(serviceInstanceObject.bulkSize); + expect(serviceState.vnfs).toEqual(serviceInstanceObject.vnfs); + expect(serviceState.instanceParams).toEqual(serviceInstanceObject.instanceParams); + expect(serviceState.rollbackOnFailure).toEqual(serviceInstanceObject.rollbackOnFailure); + expect(serviceState.subscriberName).toEqual(serviceInstanceObject.subscriberName); + }); + + + test('#DELETE_ALL_SERVICE_INSTANCES should delete all services', () => { + const state = serviceReducer(<any>{ + serviceInstance: { + 'service-1': {}, + 'service-2': {} + } + }, + <CreateServiceInstanceAction>{ + type: ServiceActions.DELETE_ALL_SERVICE_INSTANCES + }); + + expect(state.serviceInstance['service-1']).toBeUndefined(); + expect(state.serviceInstance['service-2']).toBeUndefined(); + }); + + test('#DELETE_SERVICE_INSTANCE should delete service', () => { + const state = serviceReducer(<any>{ + serviceInstance: { + 'service-1': {} + } + }, + <DeleteServiceInstanceAction>{ + type: ServiceActions.DELETE_ALL_SERVICE_INSTANCES + }); + + expect(state.serviceInstance['service-1']).toBeUndefined(); + }); + + test('#UPDATE_MODEL should update service model ', () => { + const state = serviceReducer(<any>{ + serviceHierarchy: {} + }, + <UpdateServiceModelAction>{ + type: ServiceActions.UPDATE_MODEL, + serviceHierarchy: { + service: { + uuid: 'uuid-1' + } + } + }); + + expect(state.serviceHierarchy['uuid-1'].service).toBeDefined(); + }); + + test('#UPDATE_MODEL should update service model with vnfGroups ', () => { + const state = serviceReducer(<any>{ + serviceHierarchy: {} + }, + <UpdateServiceModelAction>{ + type: ServiceActions.UPDATE_MODEL, + serviceHierarchy: { + service: { + uuid: 'uuid-1' + }, + vnfs: {}, + vnfGroups: { + 'vnfGrouop_1': { + uuid: 'vnfGroup_uuid_1', + name: 'vnfGroup_name_1', + type: 'Group' + }, + 'vnfGrouop_2': { + uuid: 'vnfGroup_uuid_2', + name: 'vnfGroup_name_2', + type: 'Group' + } + } + } + }); + + expect(state.serviceHierarchy['uuid-1']).toBeDefined(); + expect(state.serviceHierarchy['uuid-1'].vnfGroups['vnfGrouop_1']).toBeDefined(); + expect(state.serviceHierarchy['uuid-1'].vnfGroups['vnfGrouop_2']).toBeDefined(); + }); + + test('#CHANGE_SERVICE_IS_DIRTY should update service isDirty flag : service is not dirty ', () => { + const state = serviceReducer(<any>{ + serviceInstance: { + 'serviceId': { + action: ServiceInstanceActions.None, + 'vnfs': { + 'vnf1': { + action: ServiceInstanceActions.None + }, + 'vnf2': { + action: ServiceInstanceActions.None + } + } + + } + } + }, + <ChangeServiceDirty>{ + type: ServiceActions.CHANGE_SERVICE_IS_DIRTY, + nodes: [ + { + action: ServiceInstanceActions.None + }, + { + action: ServiceInstanceActions.None + }], + serviceId: 'serviceId' + + }); + + expect(state.serviceInstance['serviceId'].isDirty).toBeFalsy(); + }); + + test('#CHANGE_SERVICE_IS_DIRTY should update service isDirty flag : service is dirty should return true', () => { + const state = serviceReducer(<any>{ + serviceInstance: { + 'serviceId': { + action: ServiceInstanceActions.Create + + } + } + }, + <ChangeServiceDirty>{ + type: ServiceActions.CHANGE_SERVICE_IS_DIRTY, + nodes: [ + { + action: ServiceInstanceActions.None + }, + { + action: ServiceInstanceActions.None + }], + serviceId: 'serviceId' + + }); + + expect(state.serviceInstance['serviceId'].isDirty).toBeTruthy(); + }); + + test('#CHANGE_SERVICE_IS_DIRTY should update service isDirty flag : vnf is dirty ', () => { + const state = serviceReducer(<any>{ + serviceInstance: { + 'serviceId': { + action: ServiceInstanceActions.None, + 'vnfs': { + 'vnf1': { + action: ServiceInstanceActions.None + }, + 'vnf2': { + action: ServiceInstanceActions.Create + } + } + + } + } + }, + <ChangeServiceDirty>{ + type: ServiceActions.CHANGE_SERVICE_IS_DIRTY, + nodes: [ + { + action: ServiceInstanceActions.None + }, + { + action: ServiceInstanceActions.Create + }], + serviceId: 'serviceId' + + }); + + expect(state.serviceInstance['serviceId'].isDirty).toBeTruthy(); + }); + +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.reducers.ts new file mode 100644 index 000000000..9d21d359c --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/service/service.reducers.ts @@ -0,0 +1,107 @@ +import {Action} from "redux"; +import { + AddServiceAction, + ChangeServiceDirty, + ServiceActions, + CreateServiceInstanceAction, + UpdateServiceModelAction, UpdateServiceInstanceAction +} from "./service.actions"; +import {ServiceInstance} from "../../../models/serviceInstance"; +import {ServiceState} from "../main.reducer"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; +import * as _ from "lodash"; + +export function serviceReducer(state: ServiceState, action: Action) : ServiceState{ + switch (action.type) { + case ServiceActions.UPDATE_SERVICE_INSTANCE : { + let newState = _.cloneDeep(state); + const updateServiceInstanceAction = <UpdateServiceInstanceAction>action; + const uuid = updateServiceInstanceAction.serviceUuid; + const serviceInstance = updateServiceInstanceAction.serviceInstance; + + + updateUniqueNames(serviceInstance.instanceName, updateServiceInstanceAction.serviceInstance.instanceName, newState.serviceInstance[uuid]); + + newState.serviceInstance[uuid] = _.merge(newState.serviceInstance[uuid], serviceInstance); + return newState; + } + case ServiceActions.CREATE_SERVICE_INSTANCE : { + const updateServiceInstanceAction = <CreateServiceInstanceAction>action; + const uuid = updateServiceInstanceAction.serviceUuid; + let newState = _.cloneDeep(state); + + const serviceInstance: ServiceInstance = new ServiceInstance(); + const currentInstaceName = state.serviceInstance[uuid] ? serviceInstance.instanceName : null; + + newState.serviceInstance[uuid] = Object.assign(serviceInstance, updateServiceInstanceAction.serviceInstance); + if (!_.isNil(updateServiceInstanceAction.serviceInstance)) { + updateUniqueNames(currentInstaceName, updateServiceInstanceAction.serviceInstance.instanceName, newState.serviceInstance[uuid]); + } + return newState; + } + case ServiceActions.DELETE_ALL_SERVICE_INSTANCES: { + if (state.serviceInstance) { + let newState = _.cloneDeep(state); + newState.serviceInstance = {}; + return Object.assign({}, state, newState); + } + return Object.assign({}, state); + } + case ServiceActions.UPDATE_MODEL: { + let uuid = (<UpdateServiceModelAction>action).serviceHierarchy.service.uuid; + state.serviceHierarchy[uuid] = _.cloneDeep((<UpdateServiceModelAction>action).serviceHierarchy); + return Object.assign({}, state); + } + case ServiceActions.ADD_SERVICE_ACTION: { + const uuid: string = (<AddServiceAction>action).serviceUuid; + const actionToAdd: ServiceInstanceActions = (<AddServiceAction>action).action; + state.serviceInstance[uuid].action = actionToAdd; + return Object.assign({}, state); + } + case ServiceActions.CHANGE_SERVICE_IS_DIRTY : { + let newState = _.cloneDeep(state); + let serviceInstanceAction: ServiceInstanceActions = newState.serviceInstance[(<ChangeServiceDirty>action).serviceId].action; + + if(serviceInstanceAction !== ServiceInstanceActions.None){ + newState.serviceInstance[(<ChangeServiceDirty>action).serviceId].isDirty = true; + return newState; + } + + const nodes = (<ChangeServiceDirty>action).nodes; + for(let node of nodes){ + const dirty = isDirty(node); + if(dirty) { + newState.serviceInstance[(<ChangeServiceDirty>action).serviceId].isDirty = true; + return newState; + } + } + + newState.serviceInstance[(<ChangeServiceDirty>action).serviceId].isDirty = false; + return newState; + } + } +} + +const isDirty = (node) : boolean => { + if(node.action !== ServiceInstanceActions.None) return true; + if(!_.isNil(node.children) && node.children.length > 0){ + for(let child of node.children){ + const dirty: boolean = isDirty(child); + if(dirty) return true; + } + } + return false; +}; + +const updateUniqueNames = (oldName : string, newName : string, serviceInstance : ServiceInstance) : void => { + let existingNames = serviceInstance.existingNames; + if (!_.isNil(oldName) && oldName.toLowerCase() in existingNames) { + delete existingNames[oldName.toLowerCase()]; + } + if(!_.isNil(newName)) { + existingNames[newName.toLowerCase()] = ""; + } +}; + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.actions.ts new file mode 100644 index 000000000..a3f0f4009 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.actions.ts @@ -0,0 +1,105 @@ +import {Action, ActionCreator} from "redux"; + +export enum VfModuleActions { + REMOVE_VNF_MODULE_INSTANCE = 'REMOVE_VNF_MODULE_INSTANCE', + CREATE_VF_MODULE = 'CREATE_VF_MODULE', + UPDATE_VF_MODULE = 'UPDATE_VF_MODULE', + DELETE_ACTION_VF_MODULE_INSTANCE = "DELETE_ACTION_VF_MODULE_INSTANCE", + UNDO_DELETE_ACTION_VF_MODULE_INSTANCE = "UNDO_DELETE_ACTION_VF_MODULE_INSTANCE", + UPDATE_VFMODULE_POSITION = "UPDATE_VFMODULE_POSITION" +} + + +export interface UpdateVFModluePosition extends Action { + node: any, + instanceId : string, + vnfStoreKey ?: string; +} + +export interface DeleteVfModuleInstanceAction extends Action { + modelName?: string; + serviceModelId?: string; + vfName?: string; + vnfStoreKey?:string; + dynamicModelName?: string; +} + +export interface CreateVFModuleInstanceAction extends Action { + vfInstance: any; + vfId: string; + serviceUuid: string; + index : number + vnfStoreKey : string; +} + +export interface UpdateVFModuleInstanceAction extends Action { + vfInstance: any; + vfId: string; + serviceUuid: string; + dynamicModelName : string; + vnfStoreKey : string +} + + +export interface DeleteActionVfModuleInstanceAction extends Action { + dynamicModelName: string; + vnfStoreKey : string; + serviceId?: string; +} + +export interface UndoDeleteActionVfModuleInstanceAction extends Action { + dynamicModelName: string; + vnfStoreKey : string; + serviceId?: string; +} + +export const removeVfModuleInstance: ActionCreator<DeleteVfModuleInstanceAction> = (modelName, serviceModelId, vfName, vnfStoreKey, dynamicModelName) => ({ + type: VfModuleActions.REMOVE_VNF_MODULE_INSTANCE, + modelName: modelName, + serviceModelId: serviceModelId, + vfName: vfName, + vnfStoreKey : vnfStoreKey, + dynamicModelName:dynamicModelName +}); + + +export const createVFModuleInstance: ActionCreator<CreateVFModuleInstanceAction> = (vfInstance, vfId, serviceUuid, index, vnfStoreKey) => ({ + type: VfModuleActions.CREATE_VF_MODULE, + vfInstance: vfInstance, + vfId: vfId, + serviceUuid: serviceUuid, + index : index, + vnfStoreKey : vnfStoreKey +}); + +export const updateVFModuleInstance: ActionCreator<UpdateVFModuleInstanceAction> = (vfInstance, vfId, serviceUuid, dynamicModelName, vnfStoreKey) => ({ + type: VfModuleActions.UPDATE_VF_MODULE, + vfInstance: vfInstance, + vfId: vfId, + serviceUuid: serviceUuid, + dynamicModelName : dynamicModelName, + vnfStoreKey : vnfStoreKey +}); + +export const deleteActionVfModuleInstance: ActionCreator<DeleteActionVfModuleInstanceAction> = (dynamicModelName, vnfStoreKey, serviceId) => ({ + type: VfModuleActions.DELETE_ACTION_VF_MODULE_INSTANCE, + dynamicModelName: dynamicModelName, + vnfStoreKey : vnfStoreKey, + serviceId: serviceId +}); + +export const undoDeleteVfModuleInstance: ActionCreator<UndoDeleteActionVfModuleInstanceAction> = (dynamicModelName, vnfStoreKey, serviceId) => ({ + type: VfModuleActions.UNDO_DELETE_ACTION_VF_MODULE_INSTANCE, + dynamicModelName: dynamicModelName, + vnfStoreKey : vnfStoreKey, + serviceId: serviceId +}); + + +export const updateVFModulePosition: ActionCreator<UpdateVFModluePosition> = (node, instanceId, vnfStoreKey) => ({ + type: VfModuleActions.UPDATE_VFMODULE_POSITION, + node: node, + instanceId: instanceId, + vnfStoreKey : vnfStoreKey +}); + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.reducers.spec.ts new file mode 100644 index 000000000..de6d2142c --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.reducers.spec.ts @@ -0,0 +1,248 @@ +import { + CreateVFModuleInstanceAction, + DeleteActionVfModuleInstanceAction, + DeleteVfModuleInstanceAction, UndoDeleteActionVfModuleInstanceAction, UpdateVFModluePosition, + VfModuleActions +} from "./vfModule.actions"; +import {vfModuleReducer} from "./vfModule.reducers"; +import {VfModuleInstance} from "../../../models/vfModuleInstance"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + + +describe('vfModuleReducer', () => { + test('#REMOVE_VNF_MODULE_INSTANCE : should delete existing vnf module by dynamicModelName', () => { + let state = vfModuleReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vfName' : { + vfModules : { + 'modelName' : { + 'dynamicModelName1': {}, + 'dynamicModelName2': {}, + } + } + } + } + } + }}, + <DeleteVfModuleInstanceAction>{ + type: VfModuleActions.REMOVE_VNF_MODULE_INSTANCE, + modelName : 'modelName', + vfName : 'vfName', + vnfStoreKey : 'vfName', + serviceModelId : 'serviceModelId', + dynamicModelName: 'dynamicModelName1' + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].vnfs['vfName'].vfModules['modelName']['dynamicModelName2']).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].vnfs['vfName'].vfModules['modelName']['dynamicModelName1']).not.toBeDefined(); + }); + + test('#DELETE_LAST_VNF_MODULE_INSTANCE : should delete existing vnf module', () => { + let state = vfModuleReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vfName' : { + vfModules : { + 'modelName' : { + 'dynamicModelName': { + } + } + } + } + } + } + }}, + <DeleteVfModuleInstanceAction>{ + type: VfModuleActions.REMOVE_VNF_MODULE_INSTANCE, + modelName : 'modelName', + vfName : 'vfName', + vnfStoreKey : 'vfName', + serviceModelId : 'serviceModelId', + dynamicModelName: 'dynamicModelName' + }); + + expect(state).toBeDefined(); + expect(state.serviceInstance['serviceModelId'].vnfs['vfName'].vfModules['modelName']).not.toBeDefined(); + }); + + test('#CREATE_VF_MODULE: should create new vfModule to existing VNF', ()=>{ + let vfModuleInstance : VfModuleInstance = new VfModuleInstance(); + vfModuleInstance.instanceName = 'instanceName'; + vfModuleInstance.isMissingData = false; + vfModuleInstance.volumeGroupName = 'volumeGroupName'; + let vfModule = vfModuleReducer(<any>{serviceInstance : { + 'serviceUuid' : { + vnfs : { + 'vnfStoreKey' : { + 'vfModules' : { + } + } + } + } + }}, + <CreateVFModuleInstanceAction>{ + type: VfModuleActions.CREATE_VF_MODULE, + vfId : 'vfId', + vfInstance : new VfModuleInstance(), + vnfStoreKey : 'vnfStoreKey', + serviceUuid : 'serviceUuid', + index : 1 + }).serviceInstance['serviceUuid'].vnfs['vnfStoreKey'].vfModules; + + let firstVfModuleName = Object.keys(vfModule)[0]; + expect(vfModule[firstVfModuleName]).toBeDefined(); + expect(vfModule[firstVfModuleName].isMissingData).toBeFalsy(); + }); + + test('#UPDATE_VF_MODULE: should update existing VFModule', ()=>{ + let vfModuleInstance : VfModuleInstance = new VfModuleInstance(); + vfModuleInstance.instanceName = 'instanceName'; + vfModuleInstance.isMissingData = false; + vfModuleInstance.volumeGroupName = 'volumeGroupName'; + let vfModule = vfModuleReducer(<any>{ + serviceHierarchy : { + 'serviceModelId' : {} + }, + serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vfName' : { + vfModules : { + 'modelName' : { + 'dynamicModelName1': { + isMissingData : true + }, + 'dynamicModelName2': {}, + } + } + } + } + } + }}, + <CreateVFModuleInstanceAction>{ + type: VfModuleActions.UPDATE_VF_MODULE, + vfId : 'modelName', + vfInstance : new VfModuleInstance(), + vnfStoreKey : 'vfName', + dynamicModelName : 'dynamicModelName1', + serviceUuid : 'serviceModelId', + index : 1 + }).serviceInstance['serviceModelId'].vnfs['vfName'].vfModules; + + let firstVfModuleName = Object.keys(vfModule)[0]; + expect(vfModule[firstVfModuleName]).toBeDefined(); + expect(vfModule[firstVfModuleName].isMissingData).toBeFalsy(); + }); + + + test('#UPDATE_VFMODULE_POSITION: should update position', ()=>{ + let vfModule = vfModuleReducer(<any>{ + serviceHierarchy : { + 'serviceModelId' : {} + }, + serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vfName' : { + vfModules : { + 'modelName' : { + 'dynamicModelName': { + isMissingData : true + } + } + } + } + } + } + }}, + <UpdateVFModluePosition>{ + type: VfModuleActions.UPDATE_VFMODULE_POSITION, + node: { + position : 1, + dynamicModelName : "dynamicModelName", + modelName : "modelName" + }, + instanceId : "serviceModelId", + vnfStoreKey : "vfName" + + }).serviceInstance['serviceModelId'].vnfs['vfName'].vfModules["modelName"]["dynamicModelName"]; + + expect(vfModule.position).toEqual(1); + }); + + + test('#DELETE_ACTION_VF_MODULE_INSTANCE', ()=>{ + let vfModule = vfModuleReducer(<any>{ + serviceHierarchy : { + 'serviceModelId' : {} + }, + serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfStoreKey' : { + vfModules : { + 'modelName' : { + 'dynamicModelName1': { + isMissingData : true, + action : 'None' + }, + 'dynamicModelName2': {}, + } + } + } + } + } + }}, + <DeleteActionVfModuleInstanceAction>{ + type: VfModuleActions.DELETE_ACTION_VF_MODULE_INSTANCE, + dynamicModelName: 'dynamicModelName1', + vnfStoreKey : 'vnfStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs['vnfStoreKey'].vfModules['modelName']['dynamicModelName1']; + + console.log(vfModule.action); + expect(vfModule).toBeDefined(); + expect(vfModule.isMissingData).toBeTruthy(); + expect(vfModule.action).toEqual(ServiceInstanceActions.None_Delete); + }); + + test('#UNDO_DELETE_ACTION_VF_MODULE_INSTANCE', ()=>{ + let vfModule = vfModuleReducer(<any>{ + serviceHierarchy : { + 'serviceModelId' : {} + }, + serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfStoreKey' : { + vfModules : { + 'modelName' : { + 'dynamicModelName1': { + isMissingData : true, + action : 'None_Delete' + }, + 'dynamicModelName2': {}, + } + } + } + } + } + }}, + <UndoDeleteActionVfModuleInstanceAction>{ + type: VfModuleActions.UNDO_DELETE_ACTION_VF_MODULE_INSTANCE, + dynamicModelName: 'dynamicModelName1', + vnfStoreKey : 'vnfStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs['vnfStoreKey'].vfModules['modelName']['dynamicModelName1']; + + console.log(vfModule.action); + expect(vfModule).toBeDefined(); + expect(vfModule.action).toEqual(ServiceInstanceActions.None); + }); + +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.reducers.ts new file mode 100644 index 000000000..f3636ff41 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vfModule/vfModule.reducers.ts @@ -0,0 +1,165 @@ +import {Action} from "redux"; +import * as _ from "lodash"; +import { + CreateVFModuleInstanceAction, DeleteActionVfModuleInstanceAction, + DeleteVfModuleInstanceAction, UndoDeleteActionVfModuleInstanceAction, UpdateVFModluePosition, + UpdateVFModuleInstanceAction, + VfModuleActions +} from "./vfModule.actions"; +import {ServiceInstance} from "../../../models/serviceInstance"; +import {VfModuleMap} from "../../../models/vfModulesMap"; +import {ServiceState} from "../main.reducer"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + + +export function vfModuleReducer(state: ServiceState , action: Action) : ServiceState{ + switch (action.type) { + case VfModuleActions.CREATE_VF_MODULE: { + const updateVFModuleInstanceAction = <CreateVFModuleInstanceAction>action; + const vfInstance = updateVFModuleInstanceAction.vfInstance; + const serviceUuid = updateVFModuleInstanceAction.serviceUuid; + const vfModuleId = updateVFModuleInstanceAction.vfId; + const vnfStoreKey = updateVFModuleInstanceAction.vnfStoreKey; + + let newState = Object.assign({}, state); + + let vfModulesMap = newState.serviceInstance[serviceUuid].vnfs[vnfStoreKey].vfModules[vfModuleId] || new VfModuleMap(); + let randomId = generateId(); + vfModulesMap[vfModuleId + randomId] = vfInstance; + updateUniqueNames(null, vfInstance.instanceName, newState.serviceInstance[serviceUuid]); + updateUniqueNames(null, vfInstance.volumeGroupName, newState.serviceInstance[serviceUuid]); + updateServiceValidationCounter(newState, false, vfInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].vnfs[vnfStoreKey].vfModules[vfModuleId] = vfModulesMap; + return newState; + } + case VfModuleActions.UPDATE_VF_MODULE: { + const updateVFModuleInstanceAction = <UpdateVFModuleInstanceAction>action; + const vfInstance = updateVFModuleInstanceAction.vfInstance; + const serviceUuid = updateVFModuleInstanceAction.serviceUuid; + const vfModuleId = updateVFModuleInstanceAction.vfId; + const newState = _.cloneDeep(state); + const vnfs = newState.serviceHierarchy[serviceUuid].vnfs; + let vnfId = getVfModuleParentVnfId(vnfs, vfModuleId); + const vnfStoreKey = updateVFModuleInstanceAction.vnfStoreKey; + if (!_.isNil(vnfStoreKey)) { + vnfId = vnfStoreKey; + } + let vfModulesMap = newState.serviceInstance[serviceUuid].vnfs[vnfId].vfModules[vfModuleId] || new VfModuleMap(); + updateServiceValidationCounter(newState, vfModulesMap[updateVFModuleInstanceAction.dynamicModelName]['isMissingData'], vfInstance.isMissingData, serviceUuid); + updateUniqueNames(vfModulesMap[updateVFModuleInstanceAction.dynamicModelName].instanceName, vfInstance.instanceName, newState.serviceInstance[serviceUuid]); + updateUniqueNames(vfModulesMap[updateVFModuleInstanceAction.dynamicModelName].volumeGroupName, vfInstance.volumeGroupName, newState.serviceInstance[serviceUuid]); + vfModulesMap[updateVFModuleInstanceAction.dynamicModelName] = vfInstance; + newState.serviceInstance[serviceUuid].vnfs[vnfId].vfModules[vfModuleId] = vfModulesMap; + return newState; + } + case VfModuleActions.REMOVE_VNF_MODULE_INSTANCE: { + const actionData = (<DeleteVfModuleInstanceAction>action); + if (state.serviceInstance[actionData.serviceModelId]) { + let vfModulesMap = state.serviceInstance[actionData.serviceModelId].vnfs[actionData.vnfStoreKey].vfModules; + updateIsMissingDataOnDeleteVFModule(state, actionData.serviceModelId, actionData.vnfStoreKey, actionData.modelName); + updateUniqueNames(vfModulesMap[actionData.modelName][actionData.dynamicModelName].instanceName, null, state.serviceInstance[actionData.serviceModelId] ); + updateUniqueNames(vfModulesMap[actionData.modelName][actionData.dynamicModelName].volumeGroupName, null, state.serviceInstance[actionData.serviceModelId] ); + delete vfModulesMap[actionData.modelName][actionData.dynamicModelName]; + if(_.isEmpty(vfModulesMap[actionData.modelName])){ + delete vfModulesMap[actionData.modelName]; + } + } + return Object.assign({}, state); + } + case VfModuleActions.DELETE_ACTION_VF_MODULE_INSTANCE : { + let newState = _.cloneDeep(state); + let vfModules = newState.serviceInstance[(<DeleteActionVfModuleInstanceAction>action).serviceId].vnfs[(<DeleteActionVfModuleInstanceAction>action).vnfStoreKey].vfModules; + + for(let key in vfModules){ + let firstKey = Object.keys(vfModules[key])[0]; + if(firstKey === (<DeleteActionVfModuleInstanceAction>action).dynamicModelName){ + let oldAction = newState.serviceInstance[(<DeleteActionVfModuleInstanceAction>action).serviceId].vnfs[(<DeleteActionVfModuleInstanceAction>action).vnfStoreKey].vfModules[key][firstKey].action; + if(oldAction === ServiceInstanceActions.None_Delete || oldAction === ServiceInstanceActions.Update_Delete) return newState; + newState.serviceInstance[(<DeleteActionVfModuleInstanceAction>action).serviceId].vnfs[(<DeleteActionVfModuleInstanceAction>action).vnfStoreKey].vfModules[key][firstKey].action = (oldAction + '_Delete') as ServiceInstanceActions; + updateIsMissingDataOnDeleteVFModule(newState, (<UndoDeleteActionVfModuleInstanceAction>action).serviceId, (<UndoDeleteActionVfModuleInstanceAction>action).vnfStoreKey, key); + return newState; + } + } + return newState; + } + case VfModuleActions.UNDO_DELETE_ACTION_VF_MODULE_INSTANCE : { + let newState = _.cloneDeep(state); + let vfModules = newState.serviceInstance[(<DeleteActionVfModuleInstanceAction>action).serviceId].vnfs[(<DeleteActionVfModuleInstanceAction>action).vnfStoreKey].vfModules; + + for(let key in vfModules){ + let firstKey = Object.keys(vfModules[key])[0]; + if(firstKey === (<UndoDeleteActionVfModuleInstanceAction>action).dynamicModelName){ + let oldAction = newState.serviceInstance[(<UndoDeleteActionVfModuleInstanceAction>action).serviceId].vnfs[(<UndoDeleteActionVfModuleInstanceAction>action).vnfStoreKey].vfModules[key][firstKey].action; + newState.serviceInstance[(<UndoDeleteActionVfModuleInstanceAction>action).serviceId].vnfs[(<UndoDeleteActionVfModuleInstanceAction>action).vnfStoreKey].vfModules[key][firstKey].action = (oldAction.split('_')[0]) as ServiceInstanceActions; + updateIsMissingDataOnDeleteVFModule(newState, (<UndoDeleteActionVfModuleInstanceAction>action).serviceId, (<UndoDeleteActionVfModuleInstanceAction>action).vnfStoreKey, key); + return newState; + } + } + return newState; + } + + case VfModuleActions.UPDATE_VFMODULE_POSITION : { + const updateVFModluePosition = <UpdateVFModluePosition>action; + const serviceUuid = updateVFModluePosition.instanceId; + const dynamicModelName = updateVFModluePosition.node.dynamicModelName; + const modelName = updateVFModluePosition.node.modelName; + const newState = _.cloneDeep(state); + + newState.serviceInstance[serviceUuid].vnfs[updateVFModluePosition.vnfStoreKey].vfModules[modelName][dynamicModelName].position = updateVFModluePosition.node.position; + return newState; + } + } +} + +const updateIsMissingDataOnDeleteVFModule = (state: any, serviceModelId: string, vnfStoreKey: string, vfModuleName): void => { + const vfModules = state.serviceInstance[serviceModelId].vnfs[vnfStoreKey].vfModules[vfModuleName]; + + _.forOwn(vfModules, (vfModuleInstance) => { + let isMissingData: boolean = vfModuleInstance.isMissingData; + updateServiceValidationCounter(state, isMissingData, false, serviceModelId); + }); +}; + + +const updateUniqueNames = (oldName : string, newName : string, serviceInstance : ServiceInstance) : void => { + let existingNames = serviceInstance.existingNames; + if (!_.isNil(oldName) && oldName.toLowerCase() in existingNames) { + delete existingNames[oldName.toLowerCase()]; + } + if(!_.isNil(newName)) { + existingNames[newName.toLowerCase()] = ""; + } +}; + +const updateServiceValidationCounter = (newState: any, oldValidationState: boolean, newValidationState: boolean, serviceUuid: string) => { + if (oldValidationState && !newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter--; + } else if (!oldValidationState && newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter++; + } +}; + +const generateId = () => { + return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); +}; +const getVfModuleParentVnfId = (vnfs: object, vfModuleId: string) => { + let vnfId = undefined; + _.forOwn(vnfs, (value, key) => { + if (vnfs[key].vfModules && vnfs[key].vfModules[vfModuleId]) { + vnfId = vnfs[key].modelCustomizationName; + return false; + } + }); + return vnfId; +}; + + + + + + + + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.actions.ts new file mode 100644 index 000000000..b84284490 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.actions.ts @@ -0,0 +1,99 @@ +import {Action, ActionCreator} from "redux"; +import {VnfInstance} from "../../../models/vnfInstance"; + +export enum VNFActions { + CREATE_VNF_INSTANCE = "CREATE_VNF_INSTANCE", + UPDATE_VNF_INSTANCE = "UPDATE_VNF_INSTANCE", + REMOVE_VNF_INSTANCE = "REMOVE_VNF_INSTANCE", + DELETE_ACTION_VNF_INSTANCE = "DELETE_VNF_INSTANCE", + UNDO_DELETE_ACTION_VNF_INSTANCE = "UNDO_DELETE_VNF_INSTANCE", + UPDATE_VNF_POSITION = "UPDATE_VNF_POISTION" +} + + +export interface CreateVnfInstanceAction extends Action { + vnfInstance?: VnfInstance; + vnfModelName?: string; + serviceUuid?: string; + vnfStoreKey?:string; +} + +export interface UpdateVnfPosition extends Action { + node: any, + instanceId : string, + vnfStoreKey?: string; +} + +export interface UpdateVnfInstanceAction extends Action { + vnfInstance?: VnfInstance; + vnfModelName?: string; + serviceUuid?: string; + vnfStoreKey?:string; +} + + + +export interface DeleteActionVnfInstanceAction extends Action { + vnfStoreKey: string; + serviceId?: string; +} + +export interface UndoDeleteActionVnfInstanceAction extends Action { + vnfStoreKey: string; + serviceId?: string; +} + +export interface RemoveVnfInstanceAction extends Action { + vnfStoreKey: string; + serviceId?: string; +} + +export const createVNFInstance: ActionCreator<CreateVnfInstanceAction> = (vnfInstance, vnfModelName, serviceUuid, vnfStoreKey) => ({ + type: VNFActions.CREATE_VNF_INSTANCE, + vnfInstance: vnfInstance, + vnfModelName: vnfModelName, + serviceUuid: serviceUuid, + vnfStoreKey : vnfStoreKey +}); + + +export const updateVNFInstance: ActionCreator<UpdateVnfInstanceAction> = (vnfInstance, vnfModelName, serviceUuid, vnfStoreKey) => ({ + type: VNFActions.UPDATE_VNF_INSTANCE, + vnfInstance: vnfInstance, + vnfModelName: vnfModelName, + serviceUuid: serviceUuid, + vnfStoreKey : vnfStoreKey +}); + + +export const deleteActionVnfInstance: ActionCreator<DeleteActionVnfInstanceAction> = (vnfStoreKey, serviceId) => ({ + type: VNFActions.DELETE_ACTION_VNF_INSTANCE, + vnfStoreKey: vnfStoreKey, + serviceId: serviceId +}); + +export const undoDeleteActionVnfInstance: ActionCreator<UndoDeleteActionVnfInstanceAction> = (vnfStoreKey, serviceId) => ({ + type: VNFActions.UNDO_DELETE_ACTION_VNF_INSTANCE, + vnfStoreKey: vnfStoreKey, + serviceId: serviceId +}); + +export const removeVnfInstance: ActionCreator<RemoveVnfInstanceAction> = (vnfStoreKey, serviceId) => ({ + type: VNFActions.REMOVE_VNF_INSTANCE, + vnfStoreKey: vnfStoreKey, + serviceId: serviceId +}); + +export const updateVnfPosition: ActionCreator<UpdateVnfPosition> = (node, instanceId, vnfStoreKey) => ({ + type: VNFActions.UPDATE_VNF_POSITION, + node: node, + instanceId: instanceId, + vnfStoreKey : vnfStoreKey +}); + + + + + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.reducers.spec.ts new file mode 100644 index 000000000..3241f11d9 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.reducers.spec.ts @@ -0,0 +1,132 @@ +import {VnfInstance} from "../../../models/vnfInstance"; +import { + CreateVnfInstanceAction, + DeleteActionVnfInstanceAction, RemoveVnfInstanceAction, + UndoDeleteActionVnfInstanceAction, UpdateVnfPosition, + VNFActions +} from "./vnf.actions"; +import {vnfReducer} from "./vnf.reducers"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + +describe('networkReducer', () => { + test('#UPDATE_VNF_POSITION', () => { + let vnfInstance: VnfInstance = new VnfInstance(); + vnfInstance.isMissingData = false; + vnfInstance.instanceName = 'instanceName'; + let vnfState = vnfReducer(<any>{ + serviceInstance : { + 'serviceModelId' : { + vnfs : { + "vnfStoreKey" : { + + } + } + } + }}, + <UpdateVnfPosition>{ + type: VNFActions.UPDATE_VNF_POSITION, + node : <any>{ + position : 1 + }, + vnfStoreKey : 'vnfStoreKey', + instanceId : 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs['vnfStoreKey']; + + expect(vnfState).toBeDefined(); + expect(vnfState.position).toEqual(1); + }); + + test('#CREATE_NETWORK_INSTANCE', () => { + let vnfInstance: VnfInstance = new VnfInstance(); + vnfInstance.isMissingData = false; + vnfInstance.instanceName = 'instanceName'; + let vnfState = vnfReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + + } + } + }}, + <CreateVnfInstanceAction>{ + type: VNFActions.CREATE_VNF_INSTANCE, + vnfInstance : vnfInstance, + vnfStoreKey : null, + vnfModelName : 'vnfModelName', + serviceUuid : 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs['vnfModelName']; + + expect(vnfState).toBeDefined(); + expect(vnfState.isMissingData).toBeFalsy(); + }); + + test('#DELETE_ACTION_VNF_INSTANCE', () => { + let vnfState = vnfReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfStoreKey' : { + isMissingData : true, + action : 'None' + } + } + } + }}, + <DeleteActionVnfInstanceAction>{ + type: VNFActions.DELETE_ACTION_VNF_INSTANCE, + vnfStoreKey: 'vnfStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs['vnfStoreKey']; + + expect(vnfState).toBeDefined(); + expect(vnfState.action).toEqual(ServiceInstanceActions.None_Delete); + }); + + test('#UNDO_DELETE_ACTION_VNF_INSTANCE', () => { + let vnfState = vnfReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfStoreKey' : { + isMissingData : true, + action : 'Update_Delete' + } + } + } + }}, + <UndoDeleteActionVnfInstanceAction>{ + type: VNFActions.UNDO_DELETE_ACTION_VNF_INSTANCE, + vnfStoreKey: 'vnfStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs['vnfStoreKey']; + + expect(vnfState).toBeDefined(); + expect(vnfState.action).toEqual(ServiceInstanceActions.Update); + }); + + test('#REMOVE_VNF_INSTANCE', () => { + let vnfs = vnfReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfs : { + 'vnfStoreKey' : { + isMissingData : true, + action : 'Update_Delete' + }, + 'vnfStoreKey_1' : { + isMissingData : true, + action : 'Update_Delete' + } + } + } + }}, + <RemoveVnfInstanceAction>{ + type: VNFActions.REMOVE_VNF_INSTANCE, + vnfStoreKey: 'vnfStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfs; + + expect(vnfs).toBeDefined(); + expect(vnfs['vnfStoreKey']).toBeUndefined(); + }); + +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.reducers.ts new file mode 100644 index 000000000..cc24d8dc3 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vnf/vnf.reducers.ts @@ -0,0 +1,124 @@ +import {Action} from "redux"; +import {VnfInstance} from "../../../models/vnfInstance"; +import { + CreateVnfInstanceAction, + DeleteActionVnfInstanceAction, RemoveVnfInstanceAction, UndoDeleteActionVnfInstanceAction, + UpdateVnfInstanceAction, UpdateVnfPosition, + VNFActions +} from "./vnf.actions"; +import * as _ from "lodash"; +import {ServiceInstance} from "../../../models/serviceInstance"; +import {ServiceState} from "../main.reducer"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + +export function vnfReducer(state: ServiceState, action: Action): ServiceState { + switch (action.type) { + case VNFActions.CREATE_VNF_INSTANCE: { + const updateVnfInstanceAction = <CreateVnfInstanceAction>action; + const serviceUuid = updateVnfInstanceAction.serviceUuid; + let vnfModelName = updateVnfInstanceAction.vnfModelName; + let newState = _.cloneDeep(state); + + updateVnfInstanceAction.vnfInstance.originalName = vnfModelName; + updateVnfInstanceAction.vnfModelName = calculateNextUniqueModelName(vnfModelName, serviceUuid, newState, 'vnfs'); + + let vnfInstance: VnfInstance = newState.serviceInstance[serviceUuid].vnfs[vnfModelName]; + vnfInstance = new VnfInstance(); + updateVnfInstanceAction.vnfInstance.vnfStoreKey = updateVnfInstanceAction.vnfModelName; + updateVnfInstanceAction.vnfInstance.originalName = vnfModelName; + vnfInstance.originalName = updateVnfInstanceAction.vnfInstance.originalName; + vnfInstance.vnfStoreKey = updateVnfInstanceAction.vnfInstance.vnfStoreKey; + updateServiceValidationCounter(newState, vnfInstance['isMissingData'], updateVnfInstanceAction.vnfInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].vnfs[updateVnfInstanceAction.vnfModelName] = Object.assign(vnfInstance, updateVnfInstanceAction.vnfInstance); + return newState; + } + + case VNFActions.UPDATE_VNF_INSTANCE: { + const updateVnfInstanceAction = <UpdateVnfInstanceAction>action; + const serviceUuid = updateVnfInstanceAction.serviceUuid; + let vnfStoreKey = updateVnfInstanceAction.vnfStoreKey; + + + let newState = _.cloneDeep(state); + let vnfInstance: VnfInstance = newState.serviceInstance[serviceUuid].vnfs[vnfStoreKey]; + updateUniqueNames(vnfInstance ? vnfInstance.instanceName : null, updateVnfInstanceAction.vnfInstance.instanceName, newState.serviceInstance[serviceUuid]); + + vnfInstance = vnfInstance || new VnfInstance(); + updateServiceValidationCounter(newState, vnfInstance['isMissingData'], updateVnfInstanceAction.vnfInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].vnfs[vnfStoreKey] = Object.assign(vnfInstance, updateVnfInstanceAction.vnfInstance); + return newState; + } + + case VNFActions.DELETE_ACTION_VNF_INSTANCE : { + let newState = _.cloneDeep(state); + let vnf = newState.serviceInstance[(<DeleteActionVnfInstanceAction>action).serviceId].vnfs[(<DeleteActionVnfInstanceAction>action).vnfStoreKey]; + let oldAction = vnf.action; + if(oldAction === ServiceInstanceActions.None_Delete || oldAction === ServiceInstanceActions.Update_Delete) return newState; + newState.serviceInstance[(<DeleteActionVnfInstanceAction>action).serviceId].vnfs[(<DeleteActionVnfInstanceAction>action).vnfStoreKey].action = (oldAction + '_Delete') as ServiceInstanceActions; + updateServiceValidationCounter(newState, vnf['isMissingData'], false, (<RemoveVnfInstanceAction>action).serviceId); + return newState; + } + + case VNFActions.UNDO_DELETE_ACTION_VNF_INSTANCE : { + let newState = _.cloneDeep(state); + let vnf = newState.serviceInstance[(<UndoDeleteActionVnfInstanceAction>action).serviceId].vnfs[(<UndoDeleteActionVnfInstanceAction>action).vnfStoreKey]; + let oldState = vnf.action; + newState.serviceInstance[(<UndoDeleteActionVnfInstanceAction>action).serviceId].vnfs[(<UndoDeleteActionVnfInstanceAction>action).vnfStoreKey].action = (oldState.split('_')[0]) as ServiceInstanceActions; + updateServiceValidationCounter(newState, vnf['isMissingData'], false, (<UndoDeleteActionVnfInstanceAction>action).serviceId); + return newState; + } + + case VNFActions.REMOVE_VNF_INSTANCE : { + let newState = _.cloneDeep(state); + let vnfInstance = newState.serviceInstance[(<RemoveVnfInstanceAction>action).serviceId].vnfs[(<RemoveVnfInstanceAction>action).vnfStoreKey]; + updateServiceValidationCounter(newState, vnfInstance['isMissingData'], false, (<RemoveVnfInstanceAction>action).serviceId); + delete newState.serviceInstance[(<RemoveVnfInstanceAction>action).serviceId].vnfs[(<RemoveVnfInstanceAction>action).vnfStoreKey]; + return newState; + } + + case VNFActions.UPDATE_VNF_POSITION : { + let newState = _.cloneDeep(state); + newState.serviceInstance[(<UpdateVnfPosition>action).instanceId].vnfs[(<UpdateVnfPosition>action).vnfStoreKey].position = (<UpdateVnfPosition>action).node.position; + return newState; + } + } +} + +const updateServiceValidationCounter = (newState: any, oldValidationState: boolean, newValidationState: boolean, serviceUuid: string) => { + if (oldValidationState && !newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter--; + } else if (!oldValidationState && newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter++; + } +}; + + +const updateUniqueNames = (oldName: string, newName: string, serviceInstance: ServiceInstance): void => { + let existingNames = serviceInstance.existingNames; + if (!_.isNil(oldName) && oldName.toLowerCase() in existingNames) { + delete existingNames[oldName.toLowerCase()]; + } + if (!_.isNil(newName)) { + existingNames[newName.toLowerCase()] = ""; + } +}; + + +export const calculateNextUniqueModelName = (vnfModelName: string, serviceId: string, state: any, levelName: string): string => { + let counter: number = null; + while (true) { + let pattern = !_.isNil(counter) ? ("_" + counter) : ""; + if (!_.isNil(state.serviceInstance[serviceId][levelName][vnfModelName + pattern])) { + counter = counter ? (counter + 1) : 1; + } else { + return vnfModelName + pattern; + } + } +}; + + + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.actions.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.actions.ts new file mode 100644 index 000000000..4ed377b7d --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.actions.ts @@ -0,0 +1,82 @@ +import {Action, ActionCreator} from "redux"; +import {VnfGroupInstance} from "../../../models/vnfGroupInstance"; +import {VnfMember} from "../../../models/VnfMember"; + +export enum VnfGroupActions { + CREATE_VNF_GROUP_INSTANCE = "CREATE_VNF_GROUP_INSTANCE", + UPDATE_VNF_GROUP_INSTANCE = "UPDATE_VNF_GROUP_INSTANCE", + DELETE_ACTION_VNF_GROUP_INSTANCE = "DELETE_VNF_GROUP_INSTANCE", + UNDO_DELETE_ACTION_VNF_GROUP_INSTANCE = "UNDO_DELETE_VNF_GROUP_INSTANCE", + SET_OPTIONAL_MEMBERS_VNF_GROUP_INSTANCE = "SET_OPTIONAL_MEMBERS_VNF_GROUP_INSTANCE" +} + + +export interface CreateVnfGroupInstanceAction extends Action { + vnfGroupInstance?: VnfGroupInstance; + vnfGroupModelName?: string; + serviceUuid?: string; + vnfGroupStoreKey?:string; +} + +export interface UpdateVnfGroupInstanceAction extends Action { + vnfGroupInstance?: VnfGroupInstance; + vnfGroupModelName?: string; + serviceUuid?: string; + vnfGroupStoreKey?:string; +} + +export interface DeleteActionVnfGroupInstanceAction extends Action { + vnfGroupStoreKey: string; + serviceId?: string; +} + +export interface UndoDeleteActionVnfGroupInstanceAction extends Action { + vnfGroupStoreKey: string; + serviceId?: string; +} + +export interface SetOptionalMembersVnfGroupInstanceAction extends Action{ + path?: string; + serviceId?: string; + vnfMembers?: VnfMember[] +} + +export const createVnfGroupInstance: ActionCreator<CreateVnfGroupInstanceAction> = (vnfGroupInstance, vnfGroupModelName, serviceUuid, vnfGroupStoreKey) => ({ + type: VnfGroupActions.CREATE_VNF_GROUP_INSTANCE, + vnfGroupInstance: vnfGroupInstance, + vnfGroupModelName: vnfGroupModelName, + serviceUuid: serviceUuid, + vnfGroupStoreKey : vnfGroupStoreKey +}); + + +export const updateVnfGroupInstance: ActionCreator<UpdateVnfGroupInstanceAction> = (vnfGroupInstance, vnfGroupModelName, serviceUuid, vnfGroupStoreKey) => ({ + type: VnfGroupActions.UPDATE_VNF_GROUP_INSTANCE, + vnfGroupInstance: vnfGroupInstance, + vnfGroupModelName: vnfGroupModelName, + serviceUuid: serviceUuid, + vnfGroupStoreKey : vnfGroupStoreKey +}); + +export const deleteActionVnfGroupInstance: ActionCreator<DeleteActionVnfGroupInstanceAction> = (vnfGroupStoreKey, serviceId) => ({ + type: VnfGroupActions.DELETE_ACTION_VNF_GROUP_INSTANCE, + vnfGroupStoreKey: vnfGroupStoreKey, + serviceId: serviceId +}); + +export const undoDeleteActionVnfGroupInstance: ActionCreator<UndoDeleteActionVnfGroupInstanceAction> = (vnfGroupStoreKey, serviceId) => ({ + type: VnfGroupActions.UNDO_DELETE_ACTION_VNF_GROUP_INSTANCE, + vnfGroupStoreKey: vnfGroupStoreKey, + serviceId: serviceId +}); + +export const setOptionalMembersVnfGroupInstance: ActionCreator<SetOptionalMembersVnfGroupInstanceAction> = ( serviceId: string, path: string, vnfMembers: VnfMember[]) => ({ + type: VnfGroupActions.SET_OPTIONAL_MEMBERS_VNF_GROUP_INSTANCE, + path: path, + serviceId: serviceId, + vnfMembers: vnfMembers +}); + + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.reducers.spec.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.reducers.spec.ts new file mode 100644 index 000000000..16c1c45cd --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.reducers.spec.ts @@ -0,0 +1,140 @@ +import {VnfGroupInstance} from "../../../models/vnfGroupInstance"; +import { + CreateVnfGroupInstanceAction, + DeleteActionVnfGroupInstanceAction, + SetOptionalMembersVnfGroupInstanceAction, + UpdateVnfGroupInstanceAction, + VnfGroupActions +} from "./vnfGroup.actions"; +import {vnfGroupReducer} from "./vnfGroup.reducers"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; +import {VnfMember} from "../../../models/VnfMember"; + + +describe('vnfGroupReducer', () => { + test('#CREATE_VNF_GROUP_INSTANCE', () => { + let vnfGroupInstance: VnfGroupInstance = new VnfGroupInstance(); + vnfGroupInstance.isMissingData = false; + vnfGroupInstance.instanceName = 'instanceName'; + let vnfGroupState = vnfGroupReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfGroups : { + + } + } + }}, + <CreateVnfGroupInstanceAction>{ + type: VnfGroupActions.CREATE_VNF_GROUP_INSTANCE, + vnfGroupInstance : vnfGroupInstance, + vnfGroupStoreKey : null, + vnfGroupModelName : 'vnfGroupModelName', + serviceUuid : 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfGroups['vnfGroupModelName']; + + expect(vnfGroupState).toBeDefined(); + expect(vnfGroupState.isMissingData).toBeFalsy(); + }); + + test('#UPDATE_VNF_GROUP_INSTANCE', () => { + let vnfGroupInstance: VnfGroupInstance = new VnfGroupInstance(); + vnfGroupInstance.isMissingData = false; + vnfGroupInstance.instanceName = 'instanceName'; + let vnfGroupState = vnfGroupReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfGroups : { + 'vnfGroupStoreKey' : { + isMissingData : true + } + } + } + }}, + <UpdateVnfGroupInstanceAction>{ + type: VnfGroupActions.UPDATE_VNF_GROUP_INSTANCE, + vnfGroupInstance : new VnfGroupInstance(), + vnfGroupStoreKey : 'vnfGroupStoreKey', + vnfGroupModelName : 'vnfGroupModelName', + serviceUuid : 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfGroups['vnfGroupStoreKey']; + + expect(vnfGroupState).toBeDefined(); + expect(vnfGroupState.isMissingData).toBeFalsy(); + }); + + test('#DELETE_ACTION_VNF_GROUP_INSTANCE', () => { + let vnfGroupInstance: VnfGroupInstance = new VnfGroupInstance(); + vnfGroupInstance.isMissingData = false; + vnfGroupInstance.instanceName = 'instanceName'; + vnfGroupInstance.action = ServiceInstanceActions.None; + let vnfGroupState = vnfGroupReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfGroups : { + 'vnfGroupStoreKey' : { + isMissingData : true, + action : 'None' + } + } + } + }}, + <DeleteActionVnfGroupInstanceAction>{ + type: VnfGroupActions.DELETE_ACTION_VNF_GROUP_INSTANCE, + vnfGroupStoreKey: 'vnfGroupStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfGroups['vnfGroupStoreKey']; + + expect(vnfGroupState).toBeDefined(); + expect(vnfGroupState.action).toEqual(ServiceInstanceActions.None_Delete); + }); + + test('#UNDO_DELETE_ACTION_VNF_GROUP_INSTANCE', () => { + let vnfGroupInstance: VnfGroupInstance = new VnfGroupInstance(); + vnfGroupInstance.isMissingData = false; + vnfGroupInstance.instanceName = 'instanceName'; + vnfGroupInstance.action = ServiceInstanceActions.None_Delete; + let vnfGroupState = vnfGroupReducer(<any>{serviceInstance : { + 'serviceModelId' : { + vnfGroups : { + 'vnfGroupStoreKey' : { + isMissingData : true, + action : 'None_Delete' + } + } + } + }}, + <DeleteActionVnfGroupInstanceAction>{ + type: VnfGroupActions.UNDO_DELETE_ACTION_VNF_GROUP_INSTANCE, + vnfGroupStoreKey: 'vnfGroupStoreKey', + serviceId: 'serviceModelId' + }).serviceInstance['serviceModelId'].vnfGroups['vnfGroupStoreKey']; + + expect(vnfGroupState).toBeDefined(); + expect(vnfGroupState.action).toEqual(ServiceInstanceActions.None); + }); + + test('#SET_OPTIONAL_MEMBERS_VNF_GROUP_INSTANCE', () => { + let vnf1: VnfMember = new VnfMember(); + vnf1.serviceInstanceId = 'aa'; + vnf1.instanceId = 'aaa'; + let vnf2: VnfMember = new VnfMember(); + vnf2.serviceInstanceId = 'bb'; + vnf2.instanceId = 'bbb'; + let optionalGroupMembersMap = vnfGroupReducer(<any>{ + serviceInstance: { + 'serviceModelId': { + optionalGroupMembersMap : {} + } + } + }, + <SetOptionalMembersVnfGroupInstanceAction>{ + type: VnfGroupActions.SET_OPTIONAL_MEMBERS_VNF_GROUP_INSTANCE, + path: 'path1', + serviceId: 'serviceModelId', + vnfMembers: [vnf1, vnf2] + }).serviceInstance['serviceModelId'].optionalGroupMembersMap; + + optionalGroupMembersMap['path1']= [vnf1, vnf2]; + expect(optionalGroupMembersMap).toEqual({'path1':[vnf1, vnf2]}); + }); +}); + + + diff --git a/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.reducers.ts b/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.reducers.ts new file mode 100644 index 000000000..2923c09b2 --- /dev/null +++ b/vid-webpack-master/src/app/shared/storeUtil/utils/vnfGroup/vnfGroup.reducers.ts @@ -0,0 +1,108 @@ +import {Action} from "redux"; +import {VnfGroupInstance} from "../../../models/vnfGroupInstance"; +import * as _ from "lodash"; +import {ServiceInstance} from "../../../models/serviceInstance"; +import {ServiceState} from "../main.reducer"; +import { + CreateVnfGroupInstanceAction, + DeleteActionVnfGroupInstanceAction, SetOptionalMembersVnfGroupInstanceAction, + UpdateVnfGroupInstanceAction, + VnfGroupActions +} from "./vnfGroup.actions"; +import {ServiceInstanceActions} from "../../../models/serviceInstanceActions"; + +export function vnfGroupReducer(state: ServiceState, action: Action): ServiceState { + switch (action.type) { + case VnfGroupActions.CREATE_VNF_GROUP_INSTANCE: { + const updateVnfGroupInstanceAction = <CreateVnfGroupInstanceAction>action; + const serviceUuid = updateVnfGroupInstanceAction.serviceUuid; + let vnfGroupModelName = updateVnfGroupInstanceAction.vnfGroupModelName; + let newState = _.cloneDeep(state); + + updateVnfGroupInstanceAction.vnfGroupInstance.originalName = vnfGroupModelName; + updateVnfGroupInstanceAction.vnfGroupModelName = calculateNextUniqueModelName(vnfGroupModelName, serviceUuid, newState, 'vnfGroups'); + + let vnfGroupInstance: VnfGroupInstance = newState.serviceInstance[serviceUuid].vnfGroups[vnfGroupModelName]; + vnfGroupInstance = new VnfGroupInstance(); + updateVnfGroupInstanceAction.vnfGroupInstance.vnfGroupStoreKey = updateVnfGroupInstanceAction.vnfGroupModelName; + updateVnfGroupInstanceAction.vnfGroupInstance.originalName = vnfGroupModelName; + vnfGroupInstance.originalName = updateVnfGroupInstanceAction.vnfGroupInstance.originalName; + vnfGroupInstance.vnfGroupStoreKey = updateVnfGroupInstanceAction.vnfGroupInstance.vnfGroupStoreKey; + updateServiceValidationCounter(newState, vnfGroupInstance['isMissingData'], updateVnfGroupInstanceAction.vnfGroupInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].vnfGroups[updateVnfGroupInstanceAction.vnfGroupModelName] = Object.assign(vnfGroupInstance, updateVnfGroupInstanceAction.vnfGroupInstance); + return newState; + } + case VnfGroupActions.UPDATE_VNF_GROUP_INSTANCE: { + const updateVnfInstanceAction = <UpdateVnfGroupInstanceAction>action; + const serviceUuid = updateVnfInstanceAction.serviceUuid; + let vnfGroupStoreKey = updateVnfInstanceAction.vnfGroupStoreKey; + + + let newState = _.cloneDeep(state); + let vnfGroupInstance: VnfGroupInstance = newState.serviceInstance[serviceUuid].vnfGroups[vnfGroupStoreKey]; + updateUniqueNames(vnfGroupInstance ? vnfGroupInstance.instanceName : null, updateVnfInstanceAction.vnfGroupInstance.instanceName, newState.serviceInstance[serviceUuid]); + + vnfGroupInstance = vnfGroupInstance || new VnfGroupInstance(); + updateServiceValidationCounter(newState, vnfGroupInstance['isMissingData'], updateVnfInstanceAction.vnfGroupInstance['isMissingData'], serviceUuid); + + newState.serviceInstance[serviceUuid].vnfGroups[vnfGroupStoreKey] = Object.assign(vnfGroupInstance, updateVnfInstanceAction.vnfGroupInstance); + return newState; + } + case VnfGroupActions.DELETE_ACTION_VNF_GROUP_INSTANCE : { + let newState = _.cloneDeep(state); + let oldAction = newState.serviceInstance[(<DeleteActionVnfGroupInstanceAction>action).serviceId].vnfGroups[(<DeleteActionVnfGroupInstanceAction>action).vnfGroupStoreKey].action; + if(oldAction === ServiceInstanceActions.None_Delete || oldAction === ServiceInstanceActions.Update_Delete) return newState; + newState.serviceInstance[(<DeleteActionVnfGroupInstanceAction>action).serviceId].vnfGroups[(<DeleteActionVnfGroupInstanceAction>action).vnfGroupStoreKey].action = (oldAction + '_Delete') as ServiceInstanceActions; + return newState; + } + case VnfGroupActions.UNDO_DELETE_ACTION_VNF_GROUP_INSTANCE : { + let newState = _.cloneDeep(state); + let oldState = newState.serviceInstance[(<DeleteActionVnfGroupInstanceAction>action).serviceId].vnfGroups[(<DeleteActionVnfGroupInstanceAction>action).vnfGroupStoreKey].action; + newState.serviceInstance[(<DeleteActionVnfGroupInstanceAction>action).serviceId].vnfGroups[(<DeleteActionVnfGroupInstanceAction>action).vnfGroupStoreKey].action = (oldState.split('_')[0]) as ServiceInstanceActions; + return newState; + } + case VnfGroupActions.SET_OPTIONAL_MEMBERS_VNF_GROUP_INSTANCE:{ + let newState = _.cloneDeep(state); + newState.serviceInstance[(<SetOptionalMembersVnfGroupInstanceAction>action).serviceId].optionalGroupMembersMap[(<SetOptionalMembersVnfGroupInstanceAction>action).path] = (<SetOptionalMembersVnfGroupInstanceAction>action).vnfMembers; + return newState; + } + } +} + +const updateServiceValidationCounter = (newState: any, oldValidationState: boolean, newValidationState: boolean, serviceUuid: string) => { + if (oldValidationState && !newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter--; + } else if (!oldValidationState && newValidationState) { + newState.serviceInstance[serviceUuid].validationCounter++; + } +}; + + +const updateUniqueNames = (oldName: string, newName: string, serviceInstance: ServiceInstance): void => { + let existingNames = serviceInstance.existingNames; + if (!_.isNil(oldName) && oldName.toLowerCase() in existingNames) { + delete existingNames[oldName.toLowerCase()]; + } + if (!_.isNil(newName)) { + existingNames[newName.toLowerCase()] = ""; + } +}; + + +export const calculateNextUniqueModelName = (vnfGroupModelName: string, serviceId: string, state: any, levelName: string): string => { + let counter: number = null; + while (true) { + let pattern = !_.isNil(counter) ? ("_" + counter) : ""; + if (!_.isNil(state.serviceInstance[serviceId][levelName][vnfGroupModelName + pattern])) { + counter = counter ? (counter + 1) : 1; + } else { + return vnfGroupModelName + pattern; + } + } +}; + + + + + |