Initial OpenECOMP SDC commit
[sdc.git] / catalog-ui / app / scripts / directives / graphs-v2 / composition-graph / utils / match-capability-requierment-utils.ts
1 /**
2  * Created by obarda on 1/1/2017.
3  */
4 /// <reference path="../../../../references"/>
5 module Sdc.Graph.Utils {
6
7     export class MatchCapabilitiesRequirementsUtils {
8
9         constructor() {
10         }
11
12
13
14         public static linkable(requirement1:Models.Requirement, requirement2:Models.Requirement, vlCapability:Models.Capability):boolean {
15             return MatchCapabilitiesRequirementsUtils.isMatch(requirement1, vlCapability) && MatchCapabilitiesRequirementsUtils.isMatch(requirement2, vlCapability);
16         };
17
18
19         /**
20          * Shows + icon in corner of each node passed in
21          * @param filteredNodesData
22          * @param cy
23          */
24         public highlightMatchingComponents(filteredNodesData, cy:Cy.Instance) {
25             _.each(filteredNodesData, (data:any) => {
26                 let node = cy.getElementById(data.id);
27                 cy.emit('showhandle', [node]);
28             });
29         }
30
31         /**
32          * Adds opacity to each node that cannot be linked to hovered node
33          * @param filteredNodesData
34          * @param nodesData
35          * @param cy
36          * @param hoveredNodeData
37          */
38         public fadeNonMachingComponents(filteredNodesData, nodesData, cy:Cy.Instance, hoveredNodeData?) {
39             let fadeNodes = _.xorWith(nodesData, filteredNodesData, (node1, node2) => {
40                 return node1.id === node2.id;
41             });
42             if (hoveredNodeData) {
43                 _.remove(fadeNodes, hoveredNodeData);
44             }
45             cy.batch(()=> {
46                 _.each(fadeNodes, (node) => {
47                     cy.getElementById(node.id).style({'background-image-opacity': 0.4});
48                 });
49             })
50         }
51
52         /**
53          * Resets all nodes to regular opacity
54          * @param cy
55          */
56         public resetFadedNodes(cy:Cy.Instance) {
57             cy.batch(()=> {
58                 cy.nodes().style({'background-image-opacity': 1});
59             })
60         }
61
62         // -------------------------------------------ALL FUNCTIONS NEED REFACTORING---------------------------------------------------------------//
63
64         private static requirementFulfilled(fromNodeId:string, requirement:any, links:Array<Models.CompositionCiLinkBase>):boolean {
65             return _.some(links, {
66                 'relation': {
67                     'fromNode': fromNodeId,
68                     'relationships': [{
69                         'requirementOwnerId': requirement.ownerId,
70                         'requirement': requirement.name,
71                         'relationship': {
72                             'type': requirement.relationship
73                         }
74                     }
75                     ]
76                 }
77             });
78         };
79
80         private static isMatch(requirement:Models.Requirement, capability:Models.Capability):boolean {
81             if (capability.type === requirement.capability) {
82                 if (requirement.node) {
83                     if (_.includes(capability.capabilitySources, requirement.node)) {
84                         return true;
85                     }
86                 } else {
87                     return true;
88                 }
89             }
90             return false;
91         };
92
93         private getFromToMatches(requirements1:Models.RequirementsGroup,
94                                  requirements2:Models.RequirementsGroup,
95                                  capabilities:Models.CapabilitiesGroup,
96                                  links:Array<Models.CompositionCiLinkBase>,
97                                  fromId:string,
98                                  toId:string,
99                                  vlCapability?:Models.Capability):Array<Models.MatchBase> {
100             let matches:Array<Models.MatchBase> = new Array<Models.MatchBase>();
101             _.forEach(requirements1, (requirementValue:Array<Models.Requirement>, key) => {
102                 _.forEach(requirementValue, (requirement:Models.Requirement) => {
103                     if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromId, requirement, links)) {
104                         _.forEach(capabilities, (capabilityValue:Array<Models.Capability>, key) => {
105                             _.forEach(capabilityValue, (capability:Models.Capability) => {
106                                 if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) {
107                                     let match:Models.MatchReqToCapability = new Models.MatchReqToCapability(requirement, capability, true, fromId, toId);
108                                     matches.push(match);
109                                 }
110                             });
111                         });
112                         if (vlCapability) {
113                             _.forEach(requirements2, (requirement2Value:Array<Models.Requirement>, key) => {
114                                 _.forEach(requirement2Value, (requirement2:Models.Requirement) => {
115                                     if (!MatchCapabilitiesRequirementsUtils.requirementFulfilled(toId, requirement2, links) && MatchCapabilitiesRequirementsUtils.linkable(requirement, requirement2, vlCapability)) {
116                                         let match:Models.MatchReqToReq = new Models.MatchReqToReq(requirement, requirement2, true, fromId, toId);
117                                         matches.push(match);
118                                     }
119                                 });
120                             });
121                         }
122                     }
123                 });
124             });
125             return matches;
126         }
127
128         private getToFromMatches(requirements:Models.RequirementsGroup, capabilities:Models.CapabilitiesGroup, links:Array<Models.CompositionCiLinkBase>, fromId:string, toId:string):Array<Models.MatchReqToCapability> {
129             let matches:Array<Models.MatchReqToCapability> = [];
130             _.forEach(requirements, (requirementValue:Array<Models.Requirement>, key) => {
131                 _.forEach(requirementValue, (requirement:Models.Requirement) => {
132                     if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(toId, requirement, links)) {
133                         _.forEach(capabilities, (capabilityValue:Array<Models.Capability>, key) => {
134                             _.forEach(capabilityValue, (capability:Models.Capability) => {
135                                 if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) {
136                                     let match:Models.MatchReqToCapability = new Models.MatchReqToCapability(requirement, capability, false, toId, fromId);
137                                     matches.push(match);
138                                 }
139                             });
140                         });
141                     }
142                 });
143             });
144             return matches;
145         }
146
147         public getMatchedRequirementsCapabilities(fromComponentInstance:Models.ComponentsInstances.ComponentInstance,
148                                                   toComponentInstance:Models.ComponentsInstances.ComponentInstance,
149                                                   links:Array<Models.CompositionCiLinkBase>,
150                                                   vl?:Models.Components.Component):Array<Models.MatchBase> {//TODO allow for VL array
151             let linkCapability;
152             if (vl) {
153                 let linkCapabilities:Array<Models.Capability> = vl.capabilities.findValueByKey('linkable');
154                 if (linkCapabilities) {
155                     linkCapability = linkCapabilities[0];
156                 }
157             }
158             let fromToMatches:Array<Models.MatchBase> = this.getFromToMatches(fromComponentInstance.requirements,
159                 toComponentInstance.requirements,
160                 toComponentInstance.capabilities,
161                 links,
162                 fromComponentInstance.uniqueId,
163                 toComponentInstance.uniqueId,
164                 linkCapability);
165             let toFromMatches:Array<Models.MatchReqToCapability> = this.getToFromMatches(toComponentInstance.requirements,
166                 fromComponentInstance.capabilities,
167                 links,
168                 fromComponentInstance.uniqueId,
169                 toComponentInstance.uniqueId);
170
171             return fromToMatches.concat(toFromMatches);
172         }
173
174
175
176
177
178         /**
179          * Step I: Check if capabilities of component match requirements of nodeDataArray
180          * 1. Get component capabilities and loop on each capability
181          * 2. Inside the loop, perform another loop on all nodeDataArray, and fetch the requirements for each one
182          * 3. Loop on the requirements, and verify match (see in code the rules)
183          *
184          * Step II: Check if requirements of component match capabilities of nodeDataArray
185          * 1. Get component requirements and loop on each requirement
186          * 2.
187          *
188          * @param component         - this is the hovered resource of the left panel of composition screen
189          * @param nodeDataArray     - Array of resource instances that are on the canvas
190          * @param links             -getMatchedRequirementsCapabilities
191          * @param vl                -
192          * @returns {any[]|T[]}
193          */
194         public findByMatchingCapabilitiesToRequirements(component:Models.Components.Component,
195                                                         nodeDataArray:Array<Models.Graph.CompositionCiNodeBase>,
196                                                         links:Array<Models.CompositionCiLinkBase>,
197                                                         vl?:Models.Components.Component):Array<any> {//TODO allow for VL array
198             let res = [];
199
200             // STEP I
201             {
202                 let capabilities:any = component.capabilities;
203                 _.forEach(capabilities, (capabilityValue:Array<any>, capabilityKey)=> {
204                     _.forEach(capabilityValue, (capability)=> {
205                         _.forEach(nodeDataArray, (node:Models.Graph.CompositionCiNodeBase)=> {
206                             if (node && node.componentInstance) {
207                                 let requirements:any = node.componentInstance.requirements;
208                                 let fromNodeId:string = node.componentInstance.uniqueId;
209                                 _.forEach(requirements, (requirementValue:Array<any>, requirementKey)=> {
210                                     _.forEach(requirementValue, (requirement)=> {
211                                         if (requirement.name !== "dependency" && MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)
212                                             && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromNodeId, requirement, links)) {
213                                             res.push(node);
214                                         }
215                                     });
216                                 });
217                             }
218                         });
219                     });
220                 });
221             }
222
223             // STEP II
224             {
225                 let requirements:any = component.requirements;
226                 let fromNodeId:string = component.uniqueId;
227                 let linkCapability:Array<Models.Capability> = vl ? vl.capabilities.findValueByKey('linkable') : undefined;
228
229                 _.forEach(requirements, (requirementValue:Array<any>, requirementKey)=> {
230                     _.forEach(requirementValue, (requirement)=> {
231                         if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromNodeId, requirement, links)) {
232                             _.forEach(nodeDataArray, (node:any)=> {
233                                 if (node && node.componentInstance && node.category !== 'groupCp') {
234                                     let capabilities:any = node.componentInstance.capabilities;
235                                     _.forEach(capabilities, (capabilityValue:Array<any>, capabilityKey)=> {
236                                         _.forEach(capabilityValue, (capability)=> {
237                                             if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) {
238                                                 res.push(node);
239                                             }
240                                         });
241                                     });
242                                     if (linkCapability) {
243                                         let linkRequirements = node.componentInstance.requirements;
244                                         _.forEach(linkRequirements, (value:Array<any>, key)=> {
245                                             _.forEach(value, (linkRequirement)=> {
246                                                 if (!MatchCapabilitiesRequirementsUtils.requirementFulfilled(node.componentInstance.uniqueId, linkRequirement, links)
247                                                     && MatchCapabilitiesRequirementsUtils.linkable(requirement, linkRequirement, linkCapability[0])) {
248                                                     res.push(node);
249                                                 }
250                                             });
251                                         });
252                                     }
253                                 }
254                             });
255                         }
256                     });
257                 });
258             }
259
260             return _.uniq(res);
261         };
262     }
263
264     MatchCapabilitiesRequirementsUtils.$inject = [];
265 }