2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 import { Injectable } from '@angular/core';
22 import { Component as TopologyTemplate } from 'app/models';
25 CompositionCiNodeVl, Service
27 import { CompositionCiServicePathLink } from 'app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link';
28 import { WorkspaceService } from 'app/ng2/pages/workspace/workspace.service';
29 import { ServiceServiceNg2 } from 'app/ng2/services/component-services/service.service';
30 import { TopologyTemplateService } from 'app/ng2/services/component-services/topology-template.service';
31 import { ServiceGenericResponse } from 'app/ng2/services/responses/service-generic-response';
32 import { QueueServiceUtils } from 'app/ng2/utils/queue-service-utils';
33 import { EventListenerService } from 'app/services';
34 import { GRAPH_EVENTS } from 'app/utils';
35 import * as _ from 'lodash';
36 import { SdcUiServices } from 'onap-ui-angular';
37 import { CompositionService } from '../../composition.service';
38 import { CommonGraphUtils } from '../common/common-graph-utils';
39 import { CompositionGraphGeneralUtils } from './composition-graph-general-utils';
42 * Created by obarda on 11/9/2016.
45 export class CompositionGraphNodesUtils {
46 constructor(private generalGraphUtils: CompositionGraphGeneralUtils,
47 private commonGraphUtils: CommonGraphUtils,
48 private eventListenerService: EventListenerService,
49 private queueServiceUtils: QueueServiceUtils,
50 private serviceService: ServiceServiceNg2,
51 private loaderService: SdcUiServices.LoaderService,
52 private compositionService: CompositionService,
53 private topologyTemplateService: TopologyTemplateService,
54 private workspaceService: WorkspaceService) {
58 * Returns component instances for all nodes passed in
59 * @param nodes - Cy nodes
62 public getAllNodesData(nodes: Cy.CollectionNodes) {
63 return _.map(nodes, (node: Cy.CollectionFirstNode) => {
68 public highlightMatchingNodesByName = (cy: Cy.Instance, nameToMatch: string) => {
71 cy.nodes("[name !@^= '" + nameToMatch + "']").style({'background-image-opacity': 0.4});
72 cy.nodes("[name @^= '" + nameToMatch + "']").style({'background-image-opacity': 1});
77 // Returns all nodes whose name starts with searchTerm
78 public getMatchingNodesByName = (cy: Cy.Instance, nameToMatch: string): Cy.CollectionNodes => {
79 return cy.nodes("[name @^= '" + nameToMatch + "']");
83 * Deletes component instances on server and then removes it from the graph as well
88 public deleteNode(cy: Cy.Instance, component: TopologyTemplate, nodeToDelete: Cy.CollectionNodes): void {
90 this.loaderService.activate();
91 const onSuccess: (response: ComponentInstance) => void = (response: ComponentInstance) => {
92 // check whether the node is connected to any VLs that only have one other connection. If so, delete that VL as well
93 this.loaderService.deactivate();
94 this.compositionService.deleteComponentInstance(response.uniqueId);
96 const nodeToDeleteIsNotVl = nodeToDelete.data().componentInstance && !(nodeToDelete.data().componentInstance.isVl());
97 if (nodeToDeleteIsNotVl) {
98 const connectedVls: Cy.CollectionFirstNode[] = this.getConnectedVlToNode(nodeToDelete);
99 this.handleConnectedVlsToDelete(connectedVls);
102 // check whether there is a service path going through this node, and if so clean it from the graph.
103 const nodeId = nodeToDelete.data().id;
104 const connectedPathLinks = cy.collection(`[type="${CompositionCiServicePathLink.LINK_TYPE}"][source="${nodeId}"], [type="${CompositionCiServicePathLink.LINK_TYPE}"][target="${nodeId}"]`);
105 _.forEach(connectedPathLinks, (link, key) => {
106 cy.remove(`[pathId="${link.data().pathId}"]`);
109 // update service path list
110 this.serviceService.getComponentCompositionData(component).subscribe((serviceResponse: ServiceGenericResponse) => {
111 (component as Service).forwardingPaths = serviceResponse.forwardingPaths;
114 this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE_SUCCESS, nodeId);
117 cy.remove(nodeToDelete);
120 const onFailed: (response: any) => void = (response: any) => {
121 this.loaderService.deactivate();
124 this.queueServiceUtils.addBlockingUIAction(
126 const uniqueId = this.workspaceService.metadata.uniqueId;
127 const componentType = this.workspaceService.metadata.componentType;
128 this.topologyTemplateService.deleteComponentInstance(componentType, uniqueId, nodeToDelete.data().componentInstance.uniqueId).subscribe(onSuccess, onFailed);
134 * Finds all VLs connected to a single node
136 * @returns {Array<Cy.CollectionFirstNode>}
138 public getConnectedVlToNode = (node: Cy.CollectionNodes): Cy.CollectionFirstNode[] => {
139 const connectedVls: Cy.CollectionFirstNode[] = new Array<Cy.CollectionFirstNode>();
140 _.forEach(node.connectedEdges().connectedNodes(), (connectedNode: Cy.CollectionFirstNode) => {
141 const connectedNodeIsVl = connectedNode.data().componentInstance.isVl();
142 if (connectedNodeIsVl) {
143 connectedVls.push(connectedNode);
150 * Delete all VLs that have only two connected nodes (this function is called when deleting a node)
151 * @param connectedVls
153 public handleConnectedVlsToDelete = (connectedVls: Cy.CollectionFirstNode[]) => {
154 _.forEach(connectedVls, (vlToDelete: Cy.CollectionNodes) => {
156 if (vlToDelete.connectedEdges().length === 2) { // if vl connected only to 2 nodes need to delete the vl
157 this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, vlToDelete.data().componentInstance.uniqueId);
163 * This function will update nodes position.
166 * @param nodesMoved - the node/multiple nodes now moved by the user
168 public onNodesPositionChanged = (cy: Cy.Instance, component: TopologyTemplate, nodesMoved: Cy.CollectionNodes): void => {
170 if (nodesMoved.length === 0) {
174 const isValidMove: boolean = this.generalGraphUtils.isGroupValidDrop(cy, nodesMoved);
177 const instancesToUpdate: ComponentInstance[] = new Array<ComponentInstance>();
179 _.each(nodesMoved, (node: Cy.CollectionFirstNode) => { // update all nodes new position
182 const newPosition: Cy.Position = this.commonGraphUtils.getNodePosition(node);
183 node.data().componentInstance.updatePosition(newPosition.x, newPosition.y);
184 instancesToUpdate.push(node.data().componentInstance);
188 if (instancesToUpdate.length > 0) {
189 this.generalGraphUtils.pushMultipleUpdateComponentInstancesRequestToQueue(instancesToUpdate);
192 // reset nodes position
193 nodesMoved.positions((i, node) => {
195 x: +node.data().componentInstance.posX,
196 y: +node.data().componentInstance.posY