1 import {DynamicInputsService} from "../../dynamicInputs.service";
2 import {ILevelNodeInfo} from "../basic.model.info";
3 import * as _ from "lodash";
4 import {VNFModel} from "../../../../../shared/models/vnfModel";
5 import {SharedTreeService} from "../../shared.tree.service";
6 import {VfModuleTreeNode} from "../../../../../shared/models/vfModuleTreeNode";
7 import {VfModuleInstance} from "../../../../../shared/models/vfModuleInstance";
8 import {VfModule} from "../../../../../shared/models/vfModule";
9 import {NgRedux} from "@angular-redux/store";
10 import {ITreeNode} from "angular-tree-component/dist/defs/api";
12 GenericFormPopupComponent,
14 } from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
15 import {DialogService} from "ng2-bootstrap-modal";
16 import {VfModulePopuopService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModule/vfModule.popuop.service";
17 import {AppState} from "../../../../../shared/store/reducers";
18 import {MessageBoxData} from "../../../../../shared/components/messageBox/messageBox.data";
19 import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service";
20 import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
21 import {IframeService} from "../../../../../shared/utils/iframe.service";
23 deleteActionVfModuleInstance,
24 removeVfModuleInstance,
25 undoDeleteVfModuleInstance,
26 updateVFModulePosition
27 } from "../../../../../shared/storeUtil/utils/vfModule/vfModule.actions";
28 import {ComponentInfoService} from "../../../component-info/component-info.service";
29 import {ComponentInfoModel, ComponentInfoType} from "../../../component-info/component-info-model";
30 import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
32 export class VFModuleModelInfo implements ILevelNodeInfo {
33 constructor(private _dynamicInputsService: DynamicInputsService,
34 private _sharedTreeService: SharedTreeService,
35 private _dialogService: DialogService,
36 private _vfModulePopupService: VfModulePopuopService,
37 private _iframeService: IframeService,
38 private _store: NgRedux<AppState>,
39 private _componentInfoService: ComponentInfoService) {
42 name: string = 'vfModules';
43 type: string = 'Module';
44 typeName: string = 'M';
46 /***********************************************************
47 * return if user should provide instance name or not.
48 * get info from parent (VNF)
49 * @param currentModel - current Model object
50 * @param parentModel - current parent Model object
51 ************************************************************/
52 isEcompGeneratedNaming(currentModel, parentModel): boolean {
53 const ecompGeneratedNaming = !_.isNil(parentModel.properties) ? parentModel.properties.ecomp_generated_naming : undefined;
54 return ecompGeneratedNaming === "true";
57 /***********************************************************
58 * return model dynamic inputs
59 * @param currentModel - current Model object
60 ************************************************************/
61 updateDynamicInputsDataFromModel = (currentModel): any => {
62 let displayInputs = _.isNil(currentModel) ? [] : currentModel.inputs;
63 return _.isEmpty(displayInputs) ? [] : this._dynamicInputsService.getArbitraryInputs(displayInputs);
66 /***********************************************************
67 * return vfModule model
68 * @param vfModuleModelId - current Model id
70 * @param serviceHierarchy - serviceHierarchy
71 ************************************************************/
72 getModel = (vfModuleModelId: string, instance, serviceHierarchy): any => {
73 if (!_.isNil(serviceHierarchy)) {
74 if (!_.isNil(serviceHierarchy[this.name]) && !_.isNil(serviceHierarchy[this.name][vfModuleModelId])) {
75 return serviceHierarchy[this.name][vfModuleModelId];
81 createNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string, index: number): VfModuleTreeNode {
82 let dynamicModelName = Object.keys(instance)[index];
83 instance = instance[Object.keys(instance)[index]];
84 const isEcompGeneratedNaming: boolean = this.isEcompGeneratedNaming(currentModel, parentModel);
86 const dynamicInputs = this.updateDynamicInputsDataFromModel(currentModel);
87 let newVfModule: VfModuleTreeNode = new VfModuleTreeNode(instance, currentModel, modelName, dynamicInputs, isEcompGeneratedNaming, dynamicModelName);
89 newVfModule.missingData = this._sharedTreeService.hasMissingData(instance, newVfModule.dynamicInputs, isEcompGeneratedNaming, []);
90 newVfModule.typeName = this.typeName;
91 newVfModule.menuActions = this.getMenuAction(<any>newVfModule, currentModel.uuid);
92 newVfModule.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
93 newVfModule.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage: "";
95 newVfModule = this._sharedTreeService.addingStatusProperty(newVfModule);
99 createInstanceTreeNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string): VfModuleTreeNode | VfModuleTreeNode[] {
100 let numberOfChilds = Object.keys(instance).length;
101 if (numberOfChilds > 1) {
102 let result: VfModuleTreeNode[] = [];
103 for (let i = 0; i < numberOfChilds; i++) {
104 result.push(this.createNode(instance, currentModel, parentModel, modelName, i));
108 return this.createNode(instance, currentModel, parentModel, modelName, 0);
112 /***********************************************************
113 * return next level object (null because is last level)
114 ************************************************************/
115 getNextLevelObject(): any {
119 getTooltip = (): string => 'VFmodule';
121 getType = (): string => 'VFmodule';
123 /***********************************************************
124 * return if instance has missing data
125 * @param instance - vnf instance
126 * @param dynamicInputs
127 * @param isEcompGeneratedNaming
128 ************************************************************/
129 hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean): boolean {
130 return this._sharedTreeService.hasMissingData(instance, dynamicInputs, isEcompGeneratedNaming, []);
134 /***********************************************************
135 * return if instance has missing data
136 * @param node - VFModule node
137 * @param serviceModelId - current service id
138 ************************************************************/
139 onClickAdd(node: ITreeNode, serviceModelId: string): void {
140 const vnfStoreKey = this._sharedTreeService.getSelectedVNF() || this.getDefaultVNF(node.parent, serviceModelId);
142 this._dialogService.addDialog(GenericFormPopupComponent, {
143 type: PopupType.VF_MODULE,
145 serviceId: serviceModelId,
146 modelName: node.data.name,
147 vFModuleStoreKey: null,
148 vnfStoreKey: vnfStoreKey,
149 modelId: node.data.modelId,
150 type: node.data.type,
151 popupService: this._vfModulePopupService
157 let messageBoxData: MessageBoxData = new MessageBoxData(
158 "Select a parent", // modal title
159 "There are multiple instances on the right side that can contain this vf-module Please select the VNF instance, to add this vf-module to, on the right side and then click the + sign",
163 {text: "Close", size: "medium", closeModal: true}
165 MessageBoxService.openModal.next(messageBoxData);
169 getDefaultVNF(node: ITreeNode, serviceModelId: string): string {
170 let keys = _.keys(_.pickBy(this._store.getState().service.serviceInstance[serviceModelId].vnfs, vnf => {
171 return (vnf.originalName == node.data.name);
173 return keys.length === 1 ? this._store.getState().service.serviceInstance[serviceModelId].vnfs[keys[0]].vnfStoreKey : null;
176 /***********************************************************
177 * return number of existing instances (in all VNF's)
178 * @param node - VfModule node
179 * @param serviceModelId - current service id
180 ************************************************************/
181 getNodeCount(node: ITreeNode, serviceModelId: string): number {
182 let count: number = 0;
183 if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceModelId])) {
184 const vnfs = this._store.getState().service.serviceInstance[serviceModelId].vnfs;
186 for (let vnfKey in vnfs) {
187 count += this.countNumberOfVFModule(vnfs[vnfKey], node);
195 countNumberOfVFModule(vnf, node): number {
197 for (let vfModuleKey in vnf['vfModules']) {
198 for (let vfModule in vnf['vfModules'][vfModuleKey]) {
199 if (vnf['vfModules'][vfModuleKey][vfModule]['modelInfo'].modelCustomizationId === node.data.modelUniqueId) {
200 const vfModuleObj = vnf['vfModules'][vfModuleKey][vfModule];
201 if (!(!_.isNil(vfModuleObj) && !_.isNil(vfModuleObj.action) && vfModuleObj.action.split('_').pop() === 'Delete')) count++;
208 getCountVFModuleOfSelectedVNF(node: ITreeNode, vnfStoreKey: string, serviceModelId: string): number {
209 let count: number = 0;
210 if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceModelId])) {
211 const vnfs = this._store.getState().service.serviceInstance[serviceModelId].vnfs;
213 for (let vnfKey in vnfs) {
214 count += this.countNumberOfVFModule(vnfs[vnfKey], node);
222 /***********************************************************
223 * should show node icon
224 * @param node - current ITrees node
225 * @param serviceModelId - service id
226 ************************************************************/
227 showNodeIcons(node: ITreeNode, serviceModelId: string): AvailableNodeIcons {
228 const selectedVNF: string = this._sharedTreeService.getSelectedVNF();
230 return this.showVFModuleOnSelectedVNF(node, selectedVNF, serviceModelId);
232 const optionalSelected = this.getOptionalVNFs(serviceModelId, node.parent.data.name);
233 if (optionalSelected.length === 1) {
234 return this.showVFModuleOnSelectedVNF(node, optionalSelected[0].vnfStoreKey, serviceModelId);
236 return new AvailableNodeIcons(false, false);
242 showVFModuleOnSelectedVNF(node: ITreeNode, selectedVNF: string, serviceModelId: string): AvailableNodeIcons {
244 if (!_.isNil(this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF]) && node.parent.data.name === this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF].originalName) {
245 const existingVFModules = this.getCountVFModuleOfSelectedVNF(node, selectedVNF, serviceModelId);
246 const reachedLimit = this.isVFModuleReachedLimit(node, this._store.getState().service.serviceHierarchy, serviceModelId, existingVFModules);
247 const showAddIcon = this._sharedTreeService.shouldShowAddIcon()&& !reachedLimit;
248 return new AvailableNodeIcons(showAddIcon, reachedLimit);
250 return new AvailableNodeIcons(false, false);
254 getOptionalVNFs(serviceUUID: string, vnfOriginalModelName: string): any[] {
256 if (!_.isNil(this._store.getState().service.serviceInstance) && !_.isNil(this._store.getState().service.serviceInstance[serviceUUID])) {
257 const serviceVNFsInstances = this._store.getState().service.serviceInstance[serviceUUID].vnfs;
258 for (let vnfKey in serviceVNFsInstances) {
259 if (serviceVNFsInstances[vnfKey].originalName === vnfOriginalModelName) {
260 serviceVNFsInstances[vnfKey].vnfStoreKey = vnfKey;
261 result.push(serviceVNFsInstances[vnfKey]);
269 /************************************************
270 return number of instances with action Delete
271 @type: vnfs networks, vngGroups (only vfModule)
272 @node : node model from the left tree
273 ************************************************/
274 getExistingInstancesWithDeleteMode(node, serviceModelId: string, selectedVNF: string): number {
275 const existingInstances = this._store.getState().service.serviceInstance[serviceModelId].vnfs[selectedVNF].vfModules;
277 const modelUuid = node.data.uuid;
279 if (!_.isNil(existingInstances)) {
280 for (let instanceKey in existingInstances) {
281 let size = Object.keys(existingInstances[instanceKey]).length;
282 for (let i = 0; i < size; i++) {
283 let vfModuleDynamicKey = Object.keys(existingInstances[instanceKey])[i];
284 if (!_.isNil(existingInstances[instanceKey][vfModuleDynamicKey].action)) {
285 if (existingInstances[instanceKey][vfModuleDynamicKey]['uuid'] === modelUuid && existingInstances[instanceKey][vfModuleDynamicKey].action.split('_').pop() === 'Delete') {
296 isVFModuleReachedLimit(node: any, serviceHierarchy: any, serviceModelId: string, currentNodeCount: number): boolean {
297 let maxNodes: number = 1;
298 let vnfModules = serviceHierarchy[serviceModelId].vfModules;
299 if (vnfModules[node.data.name]) {
300 maxNodes = vnfModules[node.data.name].properties.maxCountInstances || 1;
302 return !(maxNodes > currentNodeCount);
306 getMenuAction(node: ITreeNode, serviceModelId: string): { [methodName: string]: { method: Function, visible: Function, enable: Function } } {
309 method: (node, serviceModelId) => {
310 this._iframeService.addClassOpenModal('content');
311 this._dialogService.addDialog(GenericFormPopupComponent, {
312 type: PopupType.VF_MODULE,
314 serviceId: serviceModelId,
315 modelName: node.data.modelName,
316 vFModuleStoreKey: node.data.dynamicModelName,
317 vnfStoreKey: node.parent.data.vnfStoreKey,
318 modelId: node.data.modelId,
319 type: node.data.type,
320 popupService: this._vfModulePopupService
326 visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
327 enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
330 method: (node, serviceModelId) => {
331 let instance = this._store.getState().service.serviceInstance[serviceModelId].vnfs[node.parent.data.vnfStoreKey].vfModules[node.data.modelName][node.data.modelVersionId];
332 this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VFMODULE', this);
334 visible: (node) => this._sharedTreeService.shouldShowAuditInfo(node),
335 enable: (node) => this._sharedTreeService.shouldShowAuditInfo(node)
338 method: (node, serviceModelId) => this._store.dispatch(removeVfModuleInstance(node.data.modelName, serviceModelId, node.parent.data.modelName, node.parent.data.vnfStoreKey, node.data.dynamicModelName)),
339 visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
340 enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
343 method: (node, serviceModelId) => {
344 this._store.dispatch(deleteActionVfModuleInstance(node.data.dynamicModelName, node.parent.data.vnfStoreKey, serviceModelId))
346 visible: (node) => this._sharedTreeService.shouldShowDelete(node),
347 enable: (node) => this._sharedTreeService.shouldShowDelete(node)
350 method: (node, serviceModelId) => {
351 this._store.dispatch(undoDeleteVfModuleInstance(node.data.dynamicModelName, node.parent.data.vnfStoreKey, serviceModelId))
353 visible: (node) => this._sharedTreeService.shouldShowUndoDelete(node),
354 enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && this._sharedTreeService.shouldShowDelete(node.parent) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
361 updatePosition(that , node, instanceId, parentStoreKey): void {
362 that.store.dispatch(updateVFModulePosition(node, instanceId, parentStoreKey));
366 getNodePosition(instance, deepDynamicName): number {
367 return (!_.isNil(instance) && !_.isNil(instance[deepDynamicName])) ? instance[deepDynamicName].position : null;
370 onSelectedNode(node: ITreeNode): void {
373 getInfoForVFModule(model, instance): ComponentInfoModel {
374 let modelInfoItems: ModelInformationItem[] = [];
375 if (model && !_.isNil(model.properties))
378 ModelInformationItem.createInstance("Base Module", model.properties.baseModule),
379 ModelInformationItem.createInstance("Min Instances", model.properties.minCountInstances),
380 ModelInformationItem.createInstance("Max Instances", model.properties.maxCountInstances),
381 ModelInformationItem.createInstance("Initial Instances Count", model.properties.initialCount)
384 return this._componentInfoService.addGeneralInfoItems(modelInfoItems, ComponentInfoType.VFMODULE, model, instance);