1 import {Injectable} from "@angular/core";
2 import {ILevelNodeInfo} from "../models/basic.model.info";
3 import {ObjectToTreeService} from "../objectToTree.service";
4 import {DefaultDataGeneratorService} from "../../../../shared/services/defaultDataServiceGenerator/default.data.generator.service";
5 import * as _ from "lodash";
6 import {ServiceInstanceActions} from "../../../../shared/models/serviceInstanceActions";
7 import {ErrorMsgService} from "../../../../shared/components/error-msg/error-msg.service";
8 import {FeatureFlagsService, Features} from "../../../../shared/services/featureFlag/feature-flags.service";
9 import {NgRedux} from "@angular-redux/store";
10 import {AppState} from "../../../../shared/store/reducers";
11 import {SharedTreeService} from "../shared.tree.service";
14 export class ObjectToInstanceTreeService {
15 constructor(private _objectToTreeService: ObjectToTreeService, private _errorMsgService: ErrorMsgService,
16 private store: NgRedux<AppState>, private _sharedTreeService: SharedTreeService) {
17 this.numberOfFailed = 0;
18 this.numberOfElements = 0;
22 /** store number of failed ******** ONLY IN RETRY MODE ******** **/
23 numberOfFailed: number = 0;
25 /** store number of existing elements **/
26 numberOfElements: number = 0;
28 /*****************************************************************
29 * return array of first level node with there child's
30 * @param serviceInstance - The service instance object from store
31 * @param serviceHierarchy - The service Hierarchy store
32 ****************************************************************/
33 convertServiceInstanceToTreeData(serviceInstance, serviceHierarchy): any[] {
34 this._errorMsgService.triggerClearError.next();
36 this.numberOfFailed = 0;
37 this.numberOfElements = 0;
39 const serviceModelId:string = serviceInstance.modelInfo.modelVersionId;
40 const firstLevelOptions: ILevelNodeInfo[] = _this._objectToTreeService.getFirstLevelOptions();
41 for (let option of firstLevelOptions) {
42 _.forOwn(serviceInstance[option.name], function (instance, modelName) {
43 nodes.push(_this.getNodeInstance(modelName, null, instance, serviceHierarchy, option, serviceModelId));
46 return this.sortElementsByPosition(nodes);
49 /*****************************************************************
50 * should increase number of failed
51 * @param node - the current node
52 ****************************************************************/
53 increaseNumberOfFailed(node) {
54 if (node && node.isFailed) {
55 this.numberOfFailed++;
56 node['errors'] = !_.isNil(node['errors']) ? node['errors'] : {};
57 node['errors']["isFailed"] = true;
58 this._errorMsgService.triggerShowError.next(this._errorMsgService.getRetryErrorObject(this.numberOfFailed));
62 /*****************************************************************
63 * should increase number of existing elements
64 * @param node - the current node
65 ****************************************************************/
66 increaseNumberOfExcitingElements() {
67 this.numberOfElements++;
70 /*****************************************************************
71 * return array of first level node with there child's
75 * @param serviceHierarchy - The service Hierarchy store
77 * @param serviceModelId
79 ****************************************************************/
80 getNodeInstance(modelName: string, parentModel: any, instance: any, serviceHierarchy, option: ILevelNodeInfo, serviceModelId: string, parentType ?: string) {
81 const instanceModel = this._sharedTreeService.modelByIdentifiers(
82 serviceHierarchy, option.name,
83 this._sharedTreeService.modelUniqueNameOrId(instance), modelName
85 const model = option.getModel(instanceModel);
87 let optionalNodes = option.createInstanceTreeNode(instance, model, parentModel, modelName, serviceModelId);
88 this.increaseNumberOfFailed(optionalNodes);
89 this.increaseNumberOfExcitingElements();
90 let nodes: any[] = _.isArray(optionalNodes) ? optionalNodes : [optionalNodes];
91 for (let node of nodes) {
92 node = this.addingExtraDataToNode(node, modelName, parentModel, instance, serviceHierarchy, option, parentType);
93 let children = this.addNextInstanceTreeNode(instance, model, option, node, serviceHierarchy, serviceModelId);
94 if (!_.isNil(children) && children.length > 0) {
95 node.children = this.sortElementsByPosition(children);
97 this.updateScalingPolicy(node);
99 return nodes.length === 1 ? nodes[0] : nodes;
102 addingExtraDataToNode(node, modelName: string, parentModel: any, instance: any, serviceHierarchy, option: ILevelNodeInfo, parentType ?: string) {
104 node.trackById = _.isNil(node.trackById) ? DefaultDataGeneratorService.createRandomTrackById() : node['trackById'];
105 node.parentType = !_.isNil(parentType) ? parentType : "";
106 node.updatePoistionFunction = option.updatePosition;
107 node.position = option.getNodePosition(instance, node.dynamicModelName);
108 node.modelTypeName = option.name;
109 node.getModel = option.getModel.bind(option);
110 node.getInfo = !_.isNil(option.getInfo) ? option.getInfo.bind(option) : ()=>{};
111 node.componentInfoType = option.componentInfoType;
117 sortElementsByPosition(nodes: any[]): any[] {
118 if (!FeatureFlagsService.getFlagState(Features.FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE, this.store)) return nodes;
119 return nodes.sort((nodeA, nodeB) => {
120 return nodeA.position - nodeB.position;
124 /*****************************************************************
125 * return next level node with there child's
126 * @param parentInstance
128 * @param levelNodeInfo
130 * @param serviceHierarchy - The service Hierarchy store
131 * @param serviceModelId
132 ****************************************************************/
133 addNextInstanceTreeNode(parentInstance, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode, serviceHierarchy, serviceModelId: string): any[] {
134 if (!_.isNil(levelNodeInfo.childNames)&& levelNodeInfo.childNames.length > 0) {
136 parentNode.children = [];
137 levelNodeInfo.childNames.forEach(function (childName) {
138 if (!_.isNil(parentInstance[childName])) {
139 let parentType = levelNodeInfo.type;
140 let nextLevelNodeInfo = levelNodeInfo.getNextLevelObject.apply(that, [childName]);
141 Object.keys(parentInstance[childName]).map((modelName) => {
142 let nextLevelInstance = parentInstance[childName][modelName];
143 let nodes: any[] | any = that.getNodeInstance(modelName, parentModel, nextLevelInstance, serviceHierarchy, nextLevelNodeInfo, serviceModelId, parentType);
144 if (_.isArray(nodes)) {
145 parentNode.children = parentNode.children.concat(nodes);
147 parentNode.children.push(nodes);
152 return this.sortElementsByPosition(parentNode.children);
154 return !_.isNil(parentNode) ? parentNode.children : null;
158 /************************************************************************************
159 * update instance scaling policy according to instance limit and existing children
161 *********************************************************************************/
162 updateScalingPolicy(node): void {
163 if(_.isNil(node)) return node;
164 node['errors'] = !_.isNil(node['errors']) ? node['errors'] : {};
165 if (!_.isNil(node['limitMembers']) && !_.isNil(node.children)) {
166 let effectiveChildren = (node.children).filter(child => [
167 ServiceInstanceActions.Create,
168 ServiceInstanceActions.None,
169 ServiceInstanceActions.Update
170 ].includes(child.action));
173 if (effectiveChildren.length > node.limitMembers) {
174 node['errors']["scalingError"] = true;
175 this._errorMsgService.triggerShowError.next(this._errorMsgService.getScalingErrorObject());
177 delete node['errors']["scalingError"];