1 import {ILevelNodeInfo} from "../basic.model.info";
2 import {DynamicInputsService} from "../../dynamicInputs.service";
3 import {ITreeNode} from "angular-tree-component/dist/defs/api";
4 import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
5 import {VnfGroupModel} from "../../../../../shared/models/vnfGroupModel";
6 import {VnfGroupTreeNode} from "../../../../../shared/models/vnfGroupTreeNode";
7 import {SharedTreeService} from "../../shared.tree.service";
8 import {VnfGroupPopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vnfGroup/vnfGroup.popup.service";
10 GenericFormPopupComponent,
12 } from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
13 import {DialogService} from 'ng2-bootstrap-modal';
14 import {AppState} from "../../../../../shared/store/reducers";
15 import {NgRedux} from "@angular-redux/store";
16 import {changeInstanceCounter, removeInstance} from "../../../../../shared/storeUtil/utils/general/general.actions";
17 import {IframeService} from "../../../../../shared/utils/iframe.service";
19 deleteActionVnfGroupInstance,
20 undoDeleteActionVnfGroupInstance
21 } from "../../../../../shared/storeUtil/utils/vnfGroup/vnfGroup.actions";
22 import {RelatedVnfMemberInfoModel} from "../relatedVnfMember/relatedVnfMember.info.model";
23 import {SearchElementsModalComponent} from "../../../../../shared/components/searchMembersModal/search-elements-modal.component";
24 import * as _ from "lodash";
25 import {MessageBoxData} from "../../../../../shared/components/messageBox/messageBox.data";
26 import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service";
27 import {ComponentInfoType} from "../../../component-info/component-info-model";
28 import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
29 import {Level1Instance} from "../../../../../shared/models/level1Instance";
30 import {AaiService} from "../../../../../shared/services/aaiService/aai.service";
31 import {Observable} from "rxjs";
32 import {createRelatedVnfMemberInstance} from "../../../../../shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions";
36 } from "../../../../../shared/components/searchMembersModal/members-table/element-table-row.model";
37 import {CustomTableColumnDefinition} from "../../../../../shared/components/searchMembersModal/members-table/elements-table.component";
39 export class VnfGroupingModelInfo implements ILevelNodeInfo {
40 constructor(private _dynamicInputsService: DynamicInputsService,
41 private _sharedTreeService: SharedTreeService,
42 private _dialogService: DialogService,
43 private _vnfGroupPopupService: VnfGroupPopupService,
44 private _iframeService: IframeService,
45 private _aaiService: AaiService,
46 private _store: NgRedux<AppState>) {
49 name: string = 'vnfGroups';
50 type: string = 'VnfGroup';
51 typeName: string = 'G';
52 childNames: string[] = ['vnfs'];
53 componentInfoType = ComponentInfoType.VNFGROUP;
56 /***********************************************************
57 * return if user should provide instance name or not.
58 * get info from parent (VNF)
59 * @param currentModel - current Model object
60 ************************************************************/
61 isEcompGeneratedNaming(currentModel): boolean {
62 const ecompGeneratedNaming = currentModel.properties.ecomp_generated_naming;
63 return ecompGeneratedNaming === "true";
66 /***********************************************************
67 * return model dynamic inputs
68 * @param currentModel - current Model object
69 ************************************************************/
70 updateDynamicInputsDataFromModel = (currentModel): any => {
71 let displayInputs = currentModel.inputs;
72 return _.isEmpty(displayInputs) ? [] : this._dynamicInputsService.getArbitraryInputs(displayInputs);
75 /***********************************************************
76 * return next level object (null because is last level)
77 ************************************************************/
78 getNextLevelObject = (): RelatedVnfMemberInfoModel => {
79 return new RelatedVnfMemberInfoModel(this._sharedTreeService, this._dynamicInputsService, this._store);
82 getTooltip = (): string => 'VnfGroup';
84 getType = (): string => 'VnfGroup';
86 createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any {
87 let node = new VnfGroupTreeNode(instance, model, storeKey);
88 node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
89 node = this._sharedTreeService.addingStatusProperty(node);
90 node.typeName = this.typeName;
91 node.menuActions = this.getMenuAction(<any>node, serviceModelId);
92 node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
93 node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
94 node.limitMembers = (!_.isNil(model.properties.quantity)) ? model.properties.quantity : null;
98 getModel(modelId: string, instance: any, serviceHierarchy): any {
99 const originalModelName = instance.originalName ? instance.originalName : modelId;
100 return new VnfGroupModel(this._sharedTreeService.modelByIdentifier(serviceHierarchy, this.name, originalModelName));
103 hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean): boolean {
104 return this._sharedTreeService.hasMissingData(instance, dynamicInputs, isEcompGeneratedNaming, []);
107 onClickAdd(node: ITreeNode, serviceModelId: string): void {
108 this._dialogService.addDialog(GenericFormPopupComponent, {
109 type: PopupType.VNF_GROUP,
111 serviceId: serviceModelId,
112 modelName: node.data.name,
113 vnfGroupStoreKey: null,
114 modelId: node.data.modelVersionId,
115 type: node.data.type,
116 popupService: this._vnfGroupPopupService
123 getNodeCount(node: ITreeNode, serviceModelId: string): number {
125 if (!_.isNil(this._store.getState().service.serviceInstance[serviceModelId])) {
126 map = this._store.getState().service.serviceInstance[serviceModelId].existingVnfGroupCounterMap || 0;
128 let count = map[node.data.modelUniqueId] || 0;
129 count -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'vnfGroups');
136 /***********************************************************
137 * should show node icon
138 * @param node - current ITrees node
139 * @param serviceModelId - service id
140 ************************************************************/
141 showNodeIcons(node: ITreeNode, serviceModelId: string): AvailableNodeIcons {
142 const showAddIcon = this._sharedTreeService.shouldShowAddIcon();
143 return new AvailableNodeIcons(showAddIcon, false);
146 getMenuAction(node: ITreeNode, serviceModelId: string): { [methodName: string]: { method: Function, visible: Function, enable: Function } } {
149 method: (node, serviceModelId) => {
150 this._iframeService.addClassOpenModal('content');
151 this._dialogService.addDialog(GenericFormPopupComponent, {
152 type: PopupType.VNF_GROUP,
154 serviceId: serviceModelId,
155 modelName: node.data.modelName,
156 vnfGroupStoreKey: node.data.vnfGroupStoreKey,
157 modelId: node.data.modelId,
158 type: node.data.type,
159 popupService: this._vnfGroupPopupService
165 visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
166 enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node)
169 method: (node, serviceModelId) => {
170 if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) {
171 let storeKey: string = node.data.vnfGroupStoreKey;
172 this._store.dispatch(removeInstance(node.data.vnfGroupStoreKey, serviceModelId, storeKey, node));
173 this._store.dispatch(changeInstanceCounter(node.data.modelUniqueId, serviceModelId, -1, node));
174 this._sharedTreeService.selectedVNF = null;
176 let messageBoxData: MessageBoxData = new MessageBoxData(
177 "Remove VNFGroup", // modal title
178 "You are about to remove this group and all its children from this service. Are you sure you want to remove it?",
183 text: "Remove Group",
185 callback: this.removeGroup.bind(this, node, serviceModelId),
188 {text: "Don’t Remove", size: "medium", closeModal: true}
191 MessageBoxService.openModal.next(messageBoxData);
194 visible: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node),
195 enable: (node) => this._sharedTreeService.shouldShowRemoveAndEdit(node)
199 method: (node, serviceModelId) => {
200 let serviceHierarchy = this._store.getState().service.serviceHierarchy[serviceModelId];
201 let serviceInstance = this._store.getState().service.serviceInstance[serviceModelId];
202 let vnfGroupModel = new VnfGroupModel(serviceHierarchy['vnfGroups'][node.data.modelName]);
203 this._dialogService.addDialog(SearchElementsModalComponent, {
206 serviceModelId : serviceModelId,
207 title: 'Add members to group',
208 description: 'Select VNF instances to associate',
209 noElementsMsg: 'No VNFs were found that can belong to this group.',
210 uniqObjectField: 'instanceId',
213 /********************************************************************************************************************************
214 iterate over all current elements:
216 1) if element is selected then update REDUX store
217 2) if element is not selected then delete member
219 @searchElementsModalComponent - all modal information (allElementsStatusMap, vnfGroupStoreKey, serviceId)
220 ********************************************************************************************************************************/
222 action: (searchElementsModalComponent) => {
223 let tmpMembers = searchElementsModalComponent._membersTableService.allElementsStatusMap;
224 for (let key in tmpMembers) {
225 if (tmpMembers[key].isSelected) {
226 this._store.dispatch(createRelatedVnfMemberInstance(node.data.vnfGroupStoreKey, serviceModelId, tmpMembers[key]));
229 searchElementsModalComponent.closeDialog();
232 getElements: (): Observable<Level1Instance[]> => {
233 return this._aaiService.getOptionalGroupMembers(serviceModelId, serviceInstance.globalSubscriberId, serviceInstance.subscriptionServiceType, (Object.values(vnfGroupModel.members))[0].sourceModelInvariant, vnfGroupModel.properties.type, vnfGroupModel.properties.role).map((result) => {
234 return this.filterUsedVnfMembers(serviceModelId, result);
237 tableHeaders : this.getTableHeaders(),
238 tableContent: this.generateRelatedMemberTableContent(),
240 title: 'Service model name',
241 dataTestId: 'sourceModelName',
242 value: (Object.values(vnfGroupModel.members))[0].sourceModelName,
243 type: SearchFieldItemType.LABEL
246 title: 'Service invariant UUID',
247 dataTestId: 'sourceModelInvariant',
248 value: (Object.values(vnfGroupModel.members))[0].sourceModelInvariant,
249 type: SearchFieldItemType.LABEL
255 visible: (node) => !_.isNil(node.data.action) ? node.data.action.split('_').pop() !== 'Delete' : true,
256 enable: (node) => !_.isNil(node.data.action) ? node.data.action.split('_').pop() !== 'Delete' : true
259 method: (node, serviceModelId) => {
260 let instance = this._store.getState().service.serviceInstance[serviceModelId].vnfGroups[node.data.vnfGroupStoreKey];
261 this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VNFGROUP', this);
263 visible: (node) => this._sharedTreeService.shouldShowAuditInfo(node),
264 enable: (node) => this._sharedTreeService.shouldShowAuditInfo(node)
267 method: (node, serviceModelId) => {
268 if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) {
269 this._store.dispatch(deleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
271 this._sharedTreeService.shouldShowDeleteInstanceWithChildrenModal(node, serviceModelId, (node, serviceModelId) => {
272 this._sharedTreeService.removeDeleteAllChild(node, serviceModelId, (node, serviceModelId) => {
273 this._store.dispatch(deleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
278 visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
279 enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
282 method: (node, serviceModelId) => {
283 if ((!_.isNil(node.data.children) && node.data.children.length === 0) || _.isNil(node.data.children)) {
284 this._store.dispatch(undoDeleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
286 this._sharedTreeService.undoDeleteAllChild(node, serviceModelId, (node, serviceModelId) => {
287 this._store.dispatch(undoDeleteActionVnfGroupInstance(node.data.vnfGroupStoreKey, serviceModelId));
291 visible: (node) => this._sharedTreeService.shouldShowUndoDelete(node),
292 enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
300 generateRelatedMemberTableContent(): ITableContent[] {
305 id: ['instanceName'],
306 value: ['instanceName']
309 value: ["instanceId"],
316 id: ['modelInfo', 'modelVersion'],
317 value: ['modelInfo', 'modelVersion']
323 id: ['modelInfo', 'modelName'],
324 value: ['modelInfo', 'modelName']
331 value: ['provStatus']
335 id: 'serviceInstance',
337 id: ['serviceInstanceName'],
338 value: ['serviceInstanceName']
340 id: ['serviceInstanceId'],
341 value: ["serviceInstanceId"],
348 id: ['lcpCloudRegionId'],
349 value: ['lcpCloudRegionId']
356 value: ['tenantName']
362 getTableHeaders() : CustomTableColumnDefinition[]{
363 const type : string = 'VNF';
365 {displayName: `${type} instance name`, key: ['instanceName']},
366 {displayName: `${type} version`, key: ['modelInfo', 'modelVersion']},
367 {displayName: `${type} model name`, key: ['modelInfo', 'modelName']},
368 {displayName: 'Prov Status', key: ['provStatus']},
369 {displayName: 'Service instance name', key: ['serviceInstanceName']},
370 {displayName: 'Cloud Region', key: ['lcpCloudRegionId']},
371 {displayName: 'Tenant Name', key: ['tenantName']}
375 filterUsedVnfMembers = (serviceModelId: string, result: Level1Instance[]): Level1Instance[] => {
376 const allMembersMap = _.keyBy(result as Level1Instance[], 'instanceId');
377 const vnfGroupsData = this._store.getState().service.serviceInstance[serviceModelId].vnfGroups;
378 const vnfMembersArr = _.flatMap(vnfGroupsData).map((vnfGroup) => vnfGroup.vnfs);
379 for (let vnf of vnfMembersArr) {
380 for (let member in vnf) {
381 delete allMembersMap[member];
384 return _.flatMap(allMembersMap);
387 removeGroup(this, node, serviceModelId) {
388 this._store.dispatch(removeInstance(node.data.modelName, serviceModelId, node.data.vnfGroupStoreKey, node));
389 this._store.dispatch(changeInstanceCounter(node.data.modelUniqueId, serviceModelId, -1, node));
390 this._sharedTreeService.selectedVNF = null;
393 updatePosition(that, node, instanceId): void {
397 getNodePosition(instance): number {
398 return !_.isNil(instance) ? instance.position : null;
401 getInfo(model, instance): ModelInformationItem[] {