diff options
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/graph/utils/match-capability-requierment-utils.ts')
-rw-r--r-- | catalog-ui/src/app/ng2/pages/composition/graph/utils/match-capability-requierment-utils.ts | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/utils/match-capability-requierment-utils.ts b/catalog-ui/src/app/ng2/pages/composition/graph/utils/match-capability-requierment-utils.ts new file mode 100644 index 0000000000..c3a1286a97 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/utils/match-capability-requierment-utils.ts @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +import { Injectable } from '@angular/core'; +import { + CapabilitiesGroup, Capability, ComponentInstance, CompositionCiLinkBase, + CompositionCiNodeBase, Match, Requirement, RequirementsGroup +} from 'app/models'; +import * as _ from 'lodash'; + +/** + * Created by obarda on 1/1/2017. + */ +@Injectable() +export class MatchCapabilitiesRequirementsUtils { + + /** + * Shows + icon in corner of each node passed in + * @param filteredNodesData + * @param cy + */ + public highlightMatchingComponents(filteredNodesData, cy: Cy.Instance) { + _.each(filteredNodesData, (data: any) => { + const node = cy.getElementById(data.id); + cy.emit('showhandle', [node]); + }); + } + + /** + * Adds opacity to each node that cannot be linked to hovered node + * @param filteredNodesData + * @param nodesData + * @param cy + * @param hoveredNodeData + */ + public fadeNonMachingComponents(filteredNodesData, nodesData, cy: Cy.Instance, hoveredNodeData?) { + const fadeNodes = _.xorWith(nodesData, filteredNodesData, (node1, node2) => { + return node1.id === node2.id; + }); + if (hoveredNodeData) { + _.remove(fadeNodes, hoveredNodeData); + } + cy.batch(() => { + _.each(fadeNodes, (node) => { + cy.getElementById(node.id).style({'background-image-opacity': 0.4}); + }); + }); + } + + /** + * Resets all nodes to regular opacity + * @param cy + */ + public resetFadedNodes(cy: Cy.Instance) { + cy.batch(() => { + cy.nodes().style({'background-image-opacity': 1}); + }); + } + + public getMatchedRequirementsCapabilities(fromComponentInstance: ComponentInstance, + toComponentInstance: ComponentInstance, + links: CompositionCiLinkBase[]): Match[] { + const fromToMatches: Match[] = this.getMatches(fromComponentInstance.requirements, + toComponentInstance.capabilities, + links, + fromComponentInstance.uniqueId, + toComponentInstance.uniqueId, true); + const toFromMatches: Match[] = this.getMatches(toComponentInstance.requirements, + fromComponentInstance.capabilities, + links, + toComponentInstance.uniqueId, + fromComponentInstance.uniqueId, false); + + return fromToMatches.concat(toFromMatches); + } + + /***** REFACTORED FUNCTIONS START HERE *****/ + + public getMatches(requirements: RequirementsGroup, capabilities: CapabilitiesGroup, links: CompositionCiLinkBase[], + fromId: string, toId: string, isFromTo: boolean): Match[] { + const matches: Match[] = []; + const unfulfilledReqs = this.getUnfulfilledRequirements(fromId, requirements, links); + _.forEach(unfulfilledReqs, (req) => { + _.forEach(_.flatten(_.values(capabilities)), (capability: Capability) => { + if (this.isMatch(req, capability)) { + if (isFromTo) { + matches.push(new Match(req, capability, isFromTo, fromId, toId)); + } else { + matches.push(new Match(req, capability, isFromTo, toId, fromId)); + } + } + }); + }); + return matches; + } + + public getUnfulfilledRequirements = (fromNodeId: string, requirements: RequirementsGroup, links: CompositionCiLinkBase[]): Requirement[] => { + const requirementArray: Requirement[] = []; + _.forEach(_.flatten(_.values(requirements)), (requirement: Requirement) => { + const reqFulfilled = this.isRequirementFulfilled(fromNodeId, requirement, links); + if (requirement.name !== 'dependency' && requirement.parentName !== 'dependency' && !reqFulfilled) { + requirementArray.push(requirement); + } + }); + return requirementArray; + } + + /** + * Returns true if there is a match between the capabilities and requirements that are passed in + * @param requirements + * @param capabilities + * @returns {boolean} + */ + public containsMatch = (requirements: Requirement[], capabilities: CapabilitiesGroup): boolean => { + return _.some(requirements, (req: Requirement) => { + return _.some(_.flatten(_.values(capabilities)), (capability: Capability) => { + return this.isMatch(req, capability); + }); + }); + } + + public hasUnfulfilledRequirementContainingMatch = (node: CompositionCiNodeBase, componentRequirements: Requirement[], capabilities: CapabilitiesGroup, links: CompositionCiLinkBase[]) => { + if (node && node.componentInstance) { + // Check if node has unfulfilled requirement that can be filled by component (#2) + const nodeRequirements: Requirement[] = this.getUnfulfilledRequirements(node.componentInstance.uniqueId, node.componentInstance.requirements, links); + if (!nodeRequirements.length) { + return false; + } + if (this.containsMatch(nodeRequirements, capabilities)) { + return true; + } + } + } + + /** + * Returns array of nodes that can connect to the component. + * In order to connect, one of the following conditions must be met: + * 1. component has an unfulfilled requirement that matches a node's capabilities + * 2. node has an unfulfilled requirement that matches the component's capabilities + * 3. vl is passed in which has the capability to fulfill requirement from component and requirement on node. + */ + public findMatchingNodesToComponentInstance(componentInstance: ComponentInstance, nodeDataArray: CompositionCiNodeBase[], links: CompositionCiLinkBase[]): any[] { + return _.filter(nodeDataArray, (node: CompositionCiNodeBase) => { + const matchedRequirementsCapabilities = this.getMatchedRequirementsCapabilities(node.componentInstance, componentInstance, links); + return matchedRequirementsCapabilities && matchedRequirementsCapabilities.length > 0; + }); + } + + public isMatch(requirement: Requirement, capability: Capability): boolean { + if (capability.type === requirement.capability) { + if (requirement.node) { + if (_.includes(capability.capabilitySources, requirement.node)) { + return true; + } + } else { + return true; + } + } + return false; + } + + private isRequirementFulfilled(fromNodeId: string, requirement: any, links: CompositionCiLinkBase[]): boolean { + return _.some(links, { + relation: { + fromNode: fromNodeId, + relationships: [{ + relation: { + requirementOwnerId: requirement.ownerId, + requirement: requirement.name, + relationship: { + type: requirement.relationship + } + + } + }] + } + }); + } + +} |