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