2 Copyright 2020 TATA ELXSI
4 Licensed under the Apache License, Version 2.0 (the 'License');
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
16 Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
19 * @file VNFComposerComponent
21 import { HttpHeaders } from '@angular/common/http';
22 import { Component, ElementRef, Injector, ViewChild, ViewEncapsulation } from '@angular/core';
23 import { ActivatedRoute, Router } from '@angular/router';
24 import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
25 import { TranslateService } from '@ngx-translate/core';
26 import { NotifierService } from 'angular-notifier';
27 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
28 import { ConfirmationTopologyComponent } from 'ConfirmationTopology';
29 import * as d3 from 'd3';
30 import { DataService } from 'DataService';
31 import { environment } from 'environment';
32 import * as HttpStatus from 'http-status-codes';
33 import * as jsyaml from 'js-yaml';
34 import { RestService } from 'RestService';
35 import { SharedService } from 'SharedService';
36 import { COMPOSERNODES, EXTCPD, GRAPHDETAILS, INTCPD, IVLD, Tick, TickPath, VDU, VDUINTCPD, VNFD, VNFDATA, VNIR } from 'VNFDModel';
40 * @Component takes VNFComposerComponent.html as template url
43 templateUrl: './VNFComposerComponent.html',
44 styleUrls: ['./VNFComposerComponent.scss'],
45 encapsulation: ViewEncapsulation.None
47 /** Exporting a class @exports VNFComposerComponent */
48 export class VNFComposerComponent {
49 /** To inject services @public */
50 public injector: Injector;
51 /** View child contains graphContainer ref @public */
52 @ViewChild('graphContainer', { static: true }) public graphContainer: ElementRef;
53 /** dataService to pass the data from one component to another @public */
54 public dataService: DataService;
55 /** random number count @public */
56 public randomNumberLength: number;
57 /** Contains the vnfd information @public */
58 public vnfList: string[] = [];
59 /** Contains VNFD Information @public */
60 public vnfdInfo: VNFD = { 'product-name': '', description: '', version: '', id: '', provider: '' };
61 /** Contains right panel box information @public */
62 public showRightSideInfo: string = '';
63 /** Add the fixed class for the freeze @public */
64 public fixedClass: string = 'fixed';
65 /** Check the loading results @public */
66 public isLoadingResults: boolean = true;
67 /** Give the message for the loading @public */
68 public message: string = 'PLEASEWAIT';
69 /** Assign the forcesimulation active @public */
70 public forceSimulationActive: boolean = false;
71 /** Assign pinned class for the button when freezed @public */
72 public classApplied: boolean = false;
73 /** Contains sidebar open status @public */
74 public sideBarOpened: boolean = false;
75 /** Contains SVG attributes @private */
76 // tslint:disable-next-line:no-any
78 /** Contains forced node animations @private */
79 // tslint:disable-next-line:no-any
81 /** Contains the Drag line */
82 // tslint:disable-next-line: no-any
83 private dragLine: any;
84 /** Contains id of the node @private */
85 private identifier: string;
86 /** Contains path information of the node */
87 // tslint:disable-next-line:no-any
89 /** Contains node network @private */
90 // tslint:disable-next-line:no-any
92 /** Contains node network @private */
93 // tslint:disable-next-line:no-any
94 private virutualDeploymentUnit: any;
95 /** Contains node connectionPoint @private */
96 // tslint:disable-next-line:no-any
97 private connectionPoint: any;
98 /** Contains node intConnectionPoint @private */
99 // tslint:disable-next-line:no-any
100 private intConnectionPoint: any;
101 /** Contains the node information @private */
102 private nodes: COMPOSERNODES[] = [];
103 /** Contains the link information of nodes @private */
104 private links: {}[] = [];
105 /** Instance of the rest service @private */
106 private restService: RestService;
107 /** Service holds the router information @private */
108 private router: Router;
109 /** Service contails all the shared service information @private */
110 private sharedService: SharedService;
111 /** Holds teh instance of AuthService class of type AuthService @private */
112 private activatedRoute: ActivatedRoute;
113 /** Notifier service to popup notification @private */
114 private notifierService: NotifierService;
115 /** Controls the header form @private */
116 private headers: HttpHeaders;
117 /** Contains tranlsate instance @private */
118 private translateService: TranslateService;
119 /** Rendered nodes represent network @private */
120 // tslint:disable-next-line:no-any
121 private gNetwork: any;
122 /** Rendered nodes represent VDU @private */
123 // tslint:disable-next-line:no-any
124 private gVirutualDeploymentUnit: any;
125 /** Rendered nodes represent connection point @private */
126 // tslint:disable-next-line:no-any
127 private gConnectionPoint: any;
128 /** Rendered nodes represent internal connection point @private */
129 // tslint:disable-next-line:no-any
130 private gIntConnectionPoint: any;
131 /** Contains all the information about VNF Details @private */
132 private vnfdPackageDetails: VNFD;
133 /** Conatins mousedown action @private */
134 private mousedownNode: COMPOSERNODES = null;
135 /** Conatins mouseup action @private */
136 private mouseupNode: COMPOSERNODES = null;
137 /** Conatins current Selection node action @private */
138 private currentSelectedNode: COMPOSERNODES = null;
139 /** Add the activeNode for the selected @private */
140 private activeNode: string = 'active';
141 /** Contains lastkeypressed instance @private */
142 private lastKeyDown: number = -1;
143 /** Contains VDU Information @private */
144 private vduInfo: VDU;
145 /** Contains VDU Old value Information @private */
146 private oldVDUID: string;
147 /** Contains Internal VL Information @private */
148 private intvlInfo: IVLD;
149 /** Contains Internal VL Old value Information @private */
150 private oldintVLID: string;
151 /** Contains Connection Point Information @private */
152 private cpInfo: EXTCPD;
153 /** Contains Connection Point Old value Information @private */
154 private oldCPID: string;
155 /** Contains Internal Connection Point Information @private */
156 private intcpInfo: VNIR;
157 /** Instance of the modal service @private */
158 private modalService: NgbModal;
160 constructor(injector: Injector) {
161 this.injector = injector;
162 this.restService = this.injector.get(RestService);
163 this.dataService = this.injector.get(DataService);
164 this.router = this.injector.get(Router);
165 this.activatedRoute = this.injector.get(ActivatedRoute);
166 this.notifierService = this.injector.get(NotifierService);
167 this.translateService = this.injector.get(TranslateService);
168 this.sharedService = this.injector.get(SharedService);
169 this.modalService = this.injector.get(NgbModal);
172 * Lifecyle Hooks the trigger before component is instantiate
174 public ngOnInit(): void {
175 // tslint:disable-next-line:no-backbone-get-set-outside-model
176 this.identifier = this.activatedRoute.snapshot.paramMap.get('id');
178 this.headers = new HttpHeaders({
179 'Content-Type': 'application/zip',
180 Accept: 'application/json',
181 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
185 /** Prepare information for node creation of VNFD @public */
186 public generateData(): void {
187 this.nodes = []; this.links = []; this.vnfdPackageDetails = null;
188 this.showRightSideInfo = 'vnfdInfo';
189 this.restService.getResource(environment.VNFPACKAGESCONTENT_URL + '/' + this.identifier)
190 .subscribe((vnfdPackageDetails: VNFD): void => {
192 delete vnfdPackageDetails._admin;
193 delete vnfdPackageDetails._id;
194 delete vnfdPackageDetails._links;
195 this.vnfdPackageDetails = vnfdPackageDetails;
196 this.generateVDU(vnfdPackageDetails);
197 this.generateCPPoint(vnfdPackageDetails);
198 this.generateInternalVLD(vnfdPackageDetails);
199 this.generateInternalCP(vnfdPackageDetails);
200 this.generateIntVLCPLinks(vnfdPackageDetails);
201 this.generateVDUCPLinks(vnfdPackageDetails);
202 this.createNode(this.nodes);
203 this.generateVNFInfo(vnfdPackageDetails);
205 this.notifierService.notify('error', this.translateService.instant('ERROR'));
207 this.isLoadingResults = false;
208 }, (error: ERRORDATA): void => {
209 error.error = typeof error.error === 'string' ? jsyaml.load(error.error) : error.error;
210 if (error.error.status === HttpStatus.NOT_FOUND || error.error.status === HttpStatus.UNAUTHORIZED) {
211 this.router.navigateByUrl('404', { skipLocationChange: true }).catch();
213 this.restService.handleError(error, 'get');
215 this.isLoadingResults = false;
216 this.showRightSideInfo = '';
219 /** Generate the VNF Package Information */
220 public generateVNFInfo(vnfdPackageDetails: VNFD): void {
221 this.vnfdInfo['product-name'] = vnfdPackageDetails['product-name'];
222 this.vnfdInfo.description = vnfdPackageDetails.description;
223 this.vnfdInfo.version = vnfdPackageDetails.version;
224 this.vnfdInfo.id = vnfdPackageDetails.id;
225 this.vnfdInfo.provider = vnfdPackageDetails.provider;
227 /** Events handles at drag on D3 region @public */
228 // tslint:disable-next-line:no-any
229 public drag(ev: any): void {
230 ev.dataTransfer.setData('text', ev.target.id);
232 /** Events handles drop at D3 region @public */
233 public drop(ev: DragEvent): void {
235 const getDropedName: string = ev.dataTransfer.getData('text');
236 if (getDropedName === 'vdu') {
237 this.svg.selectAll('*').remove();
238 this.vduDropCompose();
239 } else if (getDropedName === 'cp') {
240 this.svg.selectAll('*').remove();
241 this.cpDropCompose();
242 } else if (getDropedName === 'intvl') {
243 this.svg.selectAll('*').remove();
244 this.intvlDropCompose();
247 /** Events handles allow drop on D3 region @public */
248 public allowDrop(ev: DragEvent): void {
251 /** Generate and list VDU @public */
252 public generateVDU(vnfdPackageDetails: VNFD): void {
253 if (vnfdPackageDetails.vdu !== undefined) {
254 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
264 /** Generate and list CP points @public */
265 public generateCPPoint(vnfdPackageDetails: VNFD): void {
266 if (vnfdPackageDetails['ext-cpd'] !== undefined) {
267 vnfdPackageDetails['ext-cpd'].forEach((cp: EXTCPD): void => {
269 id: cp['int-cpd'].cpd !== undefined ? cp['int-cpd'].cpd : cp.id,
277 /** Generate and list Internal VLD @public */
278 public generateInternalVLD(vnfdPackageDetails: VNFD): void {
279 if (vnfdPackageDetails['int-virtual-link-desc'] !== undefined) {
280 vnfdPackageDetails['int-virtual-link-desc'].forEach((ivld: IVLD): void => {
290 /** Generate and list Internal CP @public */
291 public generateInternalCP(vnfdPackageDetails: VNFD): void {
292 if (vnfdPackageDetails.vdu !== undefined) {
293 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
294 if (vdu['int-cpd'] !== undefined) {
295 vdu['int-cpd'].forEach((intcpd: VDUINTCPD): void => {
296 if (intcpd['int-virtual-link-desc'] !== undefined) {
297 intcpd['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
311 /** Generate VDU External and Internal CP Links @public */
312 public generateVDUCPLinks(vnfdPackageDetails: VNFD): void {
313 if (vnfdPackageDetails.vdu !== undefined) {
314 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
315 const vduLink: string = vdu.id;
316 if (vdu['int-cpd'] !== undefined) {
317 vdu['int-cpd'].forEach((intCPD: VDUINTCPD): void => {
318 if (intCPD['int-virtual-link-desc'] !== undefined) {
319 intCPD['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
320 this.links.push({ source: vduLink, target: intCPD.id });
323 this.links.push({ source: vduLink, target: intCPD.id });
330 /** Generate Network/VLD/Internal VirtualLink, CP Links @public */
331 public generateIntVLCPLinks(vnfdPackageDetails: VNFD): void {
332 if (vnfdPackageDetails.vdu !== undefined) {
333 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
334 if (vdu['int-cpd'] !== undefined) {
335 vdu['int-cpd'].forEach((intCPD: VDUINTCPD): void => {
336 const vldName: string = intCPD['int-virtual-link-desc'];
337 if (intCPD['int-virtual-link-desc'] !== undefined) {
338 intCPD['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
339 this.links.push({ source: vldName, target: intCPD.id });
347 /** VNFD details can be saved on users inputs @public */
348 public saveVNFD(): void {
349 this.vnfdPackageDetails['product-name'] = this.vnfdInfo['product-name'];
350 this.vnfdPackageDetails.description = this.vnfdInfo.description;
351 this.vnfdPackageDetails.version = this.vnfdInfo.version;
352 this.vnfdPackageDetails.id = this.vnfdInfo.id;
353 this.vnfdPackageDetails.provider = this.vnfdInfo.provider;
354 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
356 /** VDU details can be saved on users inputs @public */
357 public saveVDU(getVDUID: string): void {
358 const getOLDVDUID: string = this.oldVDUID;
359 this.vnfdPackageDetails.vdu.forEach((ref: VDU): void => {
360 if (ref.id === getVDUID) {
361 ref.id = this.vduInfo.id;
362 ref.name = this.vduInfo.name;
363 ref.description = this.vduInfo.description !== undefined ? this.vduInfo.description : '';
364 ref['sw-image-desc'] = this.vduInfo['sw-image-desc'];
367 this.vnfdPackageDetails['ext-cpd'].forEach((extCPD: EXTCPD): void => {
368 if (extCPD['int-cpd'] !== undefined) {
369 if (extCPD['int-cpd']['vdu-id'] === getOLDVDUID) {
370 extCPD['int-cpd']['vdu-id'] = this.vduInfo.id;
374 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
376 /** IntVL details can be saved on users inputs @public */
377 public saveIntVL(intVLID: string): void {
378 const getOldID: string = this.oldintVLID;
379 this.vnfdPackageDetails['int-virtual-link-desc'].forEach((ivldDetails: IVLD): void => {
380 if (ivldDetails.id === intVLID) {
381 ivldDetails.id = this.intvlInfo.id;
384 this.vnfdPackageDetails.vdu.forEach((vduDetails: VDU): void => {
385 if (vduDetails['int-cpd'] !== undefined) {
386 vduDetails['int-cpd'].forEach((intCPDDetails: VDUINTCPD): void => {
387 if (intCPDDetails['int-virtual-link-desc'] !== undefined) {
388 if (intCPDDetails['int-virtual-link-desc'] === getOldID) {
389 intCPDDetails['int-virtual-link-desc'] = this.intvlInfo.id;
395 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
397 /** IntVL details can be saved on users inputs @public */
398 public saveCP(cpID: string): void {
399 const getOldCP: string = this.oldCPID;
400 this.vnfdPackageDetails['ext-cpd'].forEach((ref: EXTCPD): void => {
401 if (ref.id === cpID) {
402 ref.id = this.cpInfo.id;
405 if (this.vnfdPackageDetails['mgmt-cp'] === getOldCP) {
406 this.vnfdPackageDetails['mgmt-cp'] = this.cpInfo.id;
408 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
410 /** Edit topology @public */
411 public onEdit(): void {
412 this.router.navigate(['/packages/vnf/edit/', this.identifier]).catch();
414 /** Show Info @public */
415 public showInfo(): void {
416 const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' });
417 modalRef.componentInstance.topologyType = 'Info';
418 modalRef.componentInstance.topologytitle = this.translateService.instant('PAGE.TOPOLOGY.INFO');
419 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
425 /** Event to freeze the animation @public */
426 public onFreeze(): void {
427 this.classApplied = !this.classApplied;
428 const alreadyFixedIsActive: boolean = d3.select('svg#graphContainer').classed(this.fixedClass);
429 d3.select('svg#graphContainer').classed(this.fixedClass, !alreadyFixedIsActive);
430 if (alreadyFixedIsActive) {
433 this.forceSimulationActive = alreadyFixedIsActive;
434 this.nodes.forEach((d: COMPOSERNODES): void => {
435 d.fx = (alreadyFixedIsActive) ? null : d.x;
436 d.fy = (alreadyFixedIsActive) ? null : d.y;
438 if (alreadyFixedIsActive) {
439 this.force.restart();
442 /** Events handles when dragended @public */
443 public toggleSidebar(): void {
444 this.sideBarOpened = !this.sideBarOpened;
445 this.deselectAllNodes();
446 this.showRightSideInfo = 'vnfdInfo';
448 /** Get the default Configuration of containers @private */
449 private getGraphContainerAttr(): GRAPHDETAILS {
462 sourcePaddingYes: 17,
472 /** Node is created and render at D3 region @private */
473 private createNode(nodes: VNFD[]): void {
474 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
475 d3.selectAll('svg#graphContainer > *').remove();
476 d3.select(window).on('keydown', (): void => { this.keyDown(); });
477 d3.select(window).on('keyup', (): void => { this.keyUp(); });
478 this.svg = d3.select('#graphContainer')
479 .attr('oncontextmenu', 'return false;')
480 .attr('viewBox', `0 0 ${graphContainerAttr.width} ${graphContainerAttr.height}`)
481 .on('mousemove', (): void => { this.mousemove(); });
482 this.force = d3.forceSimulation()
483 .force('link', d3.forceLink().id((d: TickPath): string => d.id).distance(graphContainerAttr.distance))
484 .force('charge', d3.forceManyBody().strength(graphContainerAttr.strength))
485 .force('x', d3.forceX(graphContainerAttr.width / graphContainerAttr.forcex))
486 .force('y', d3.forceY(graphContainerAttr.height / graphContainerAttr.forcey))
487 .on('tick', (): void => { this.tick(); });
488 this.path = this.svg.append('svg:g').selectAll('path');
489 this.dragLine = this.svg.append('svg:path').attr('class', 'link dragline hidden').attr('d', 'M0,0L0,0');
490 this.network = this.svg.append('svg:g').selectAll('network');
491 this.virutualDeploymentUnit = this.svg.append('svg:g').selectAll('virutualDeploymentUnit');
492 this.connectionPoint = this.svg.append('svg:g').selectAll('connectionPoint');
493 this.intConnectionPoint = this.svg.append('svg:g').selectAll('intConnectionPoint');
496 /** Update force layout (called automatically each iteration) @private */
497 private tick(): void {
498 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
499 this.path.attr('d', (d: Tick): string => {
500 const deltaX: number = d.target.x - d.source.x; const deltaY: number = d.target.y - d.source.y;
501 const dist: number = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
502 const normX: number = deltaX / dist; const normY: number = deltaY / dist;
503 const sourcePadding: number = d.left ? graphContainerAttr.sourcePaddingYes : graphContainerAttr.sourcePaddingNo;
504 const targetPadding: number = d.right ? graphContainerAttr.targetPaddingYes : graphContainerAttr.targetPaddingNo;
505 const sourceX: number = d.source.x + (sourcePadding * normX); const sourceY: number = d.source.y + (sourcePadding * normY);
506 const targetX: number = d.target.x - (targetPadding * normX); const targetY: number = d.target.y - (targetPadding * normY);
507 return `M${sourceX},${sourceY}L${targetX},${targetY}`;
508 }).on('dblclick', (d: Tick): void => { this.getDeleteLinkConfirmation(d); });
509 this.network.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
510 this.virutualDeploymentUnit.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
511 this.connectionPoint.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
512 this.intConnectionPoint.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
514 /** Update graph (called when needed) @private */
515 private restart(nodes: VNFD[]): void {
516 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
517 this.path = this.path.data(this.links);
518 const cpNodes: {}[] = []; const vduNodes: {}[] = []; const vlNodes: {}[] = []; const intcpNodes: {}[] = []; //Nodes are known by id
519 nodes.forEach((nodeList: COMPOSERNODES): void => {
520 if (nodeList.type === 'cp') { cpNodes.push(nodeList); }
521 else if (nodeList.type === 'vdu') { vduNodes.push(nodeList); }
522 else if (nodeList.type === 'intvl') { vlNodes.push(nodeList); }
523 else if (nodeList.type === 'intcp') { intcpNodes.push(nodeList); }
525 this.network = this.network.data(vlNodes, (d: VNFD): string => d.id);
526 this.virutualDeploymentUnit = this.virutualDeploymentUnit.data(vduNodes, (d: VNFD): string => d.id);
527 this.connectionPoint = this.connectionPoint.data(cpNodes, (d: VNFD): string => d.id);
528 this.intConnectionPoint = this.intConnectionPoint.data(intcpNodes, (d: VNFD): string => d.id);
529 this.resetAndCreateNodes();
530 this.force.nodes(nodes).force('link').links(this.links); //Set the graph in motion
531 this.force.alphaTarget(graphContainerAttr.alphaTarget).restart();
533 /** Rest and create nodes @private */
534 private resetAndCreateNodes(): void {
535 this.path.exit().remove();
536 this.network.exit().remove();
537 this.virutualDeploymentUnit.exit().remove();
538 this.connectionPoint.exit().remove();
539 this.intConnectionPoint.exit().remove();
542 this.getgVirutualDeploymentUnit();
543 this.getgConnectionPoint();
544 this.getgIntConnectionPoint();
545 this.network = this.gNetwork.merge(this.network);
546 this.virutualDeploymentUnit = this.gVirutualDeploymentUnit.merge(this.virutualDeploymentUnit);
547 this.connectionPoint = this.gConnectionPoint.merge(this.connectionPoint);
548 this.intConnectionPoint = this.gIntConnectionPoint.merge(this.intConnectionPoint);
549 this.path.merge(this.path);
551 /** Setting the Path @private */
552 private getPathNodes(): void {
553 this.path = this.path.enter().append('svg:path').attr('class', 'link');
555 /** Settings all the network attributes of nodes @private */
556 private getgNetwork(): void {
557 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
558 this.gNetwork = this.network.enter().append('svg:g');
559 this.gNetwork.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
560 this.gNetwork.append('svg:image')
562 .attr('x', graphContainerAttr.imageX)
563 .attr('y', graphContainerAttr.imageY)
564 .call(this.onDragDrop())
565 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
566 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
567 .attr('xlink:href', 'assets/images/INTVL.svg')
568 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
569 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
570 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.network, d); this.onNodeClickToggleSidebar(); })
571 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
572 this.gNetwork.append('svg:text')
573 .attr('class', 'node_text')
574 .attr('y', graphContainerAttr.textY)
575 .text((d: COMPOSERNODES): string => d.id);
577 /** Settings all the connection point attributes of nodes @private */
578 private getgVirutualDeploymentUnit(): void {
579 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
580 this.gVirutualDeploymentUnit = this.virutualDeploymentUnit.enter().append('svg:g');
581 this.gVirutualDeploymentUnit.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
582 this.gVirutualDeploymentUnit.append('svg:image')
584 .attr('x', graphContainerAttr.imageX)
585 .attr('y', graphContainerAttr.imageY)
586 .call(this.onDragDrop())
587 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
588 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
589 .attr('xlink:href', 'assets/images/VDU.svg')
590 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
591 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
592 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.virutualDeploymentUnit, d); this.onNodeClickToggleSidebar(); })
593 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
594 this.gVirutualDeploymentUnit.append('svg:text')
595 .attr('class', 'node_text')
596 .attr('y', graphContainerAttr.textY)
597 .text((d: COMPOSERNODES): string => d.id);
599 /** Settings all the connection point attributes of nodes @private */
600 private getgConnectionPoint(): void {
601 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
602 this.gConnectionPoint = this.connectionPoint.enter().append('svg:g');
603 this.gVirutualDeploymentUnit.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
604 this.gConnectionPoint.append('svg:image')
606 .attr('x', graphContainerAttr.imageX)
607 .attr('y', graphContainerAttr.imageY)
608 .call(this.onDragDrop())
609 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
610 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
611 .attr('xlink:href', 'assets/images/CP-VNF.svg')
612 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
613 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
614 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.connectionPoint, d); this.onNodeClickToggleSidebar(); })
615 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
616 this.gConnectionPoint.append('svg:text')
617 .attr('class', 'node_text')
618 .attr('y', graphContainerAttr.textY)
619 .text((d: COMPOSERNODES): string => d.name);
621 /** Settings all the internal connection point attributes of nodes @private */
622 private getgIntConnectionPoint(): void {
623 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
624 this.gIntConnectionPoint = this.intConnectionPoint.enter().append('svg:g');
625 this.gIntConnectionPoint.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
626 this.gIntConnectionPoint.append('svg:image')
628 .attr('x', graphContainerAttr.imageX)
629 .attr('y', graphContainerAttr.imageY)
630 .call(this.onDragDrop())
631 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
632 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
633 .attr('xlink:href', 'assets/images/INTCP.svg')
634 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
635 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
636 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.intConnectionPoint, d); this.onNodeClickToggleSidebar(); })
637 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
638 this.gIntConnectionPoint.append('svg:text')
639 .attr('class', 'node_text')
640 .attr('y', graphContainerAttr.textY)
641 .text((d: COMPOSERNODES): string => d.name);
643 /** Drop VDU Composer Data @private */
644 private vduDropCompose(): void {
645 const randomID: string = this.sharedService.randomString();
646 if (this.vnfdPackageDetails['mgmt-cp'] === undefined) {
647 this.notifierService.notify('error', this.translateService.instant('PAGE.TOPOLOGY.ADDCPBEFOREVDU'));
649 if (this.vnfdPackageDetails.vdu === undefined) {
650 this.vnfdPackageDetails.vdu = [];
652 this.vnfdPackageDetails.vdu.push({
653 id: 'vdu_' + randomID,
654 name: 'vdu_' + randomID,
656 'sw-image-desc': 'ubuntu',
658 'monitoring-parameter': [],
659 'virtual-compute-desc': '',
660 'virtual-storage-desc': []
662 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
665 /** Drop CP Composer Data @private */
666 private cpDropCompose(): void {
667 const randomID: string = this.sharedService.randomString();
668 if (this.vnfdPackageDetails['ext-cpd'] === undefined) {
669 this.vnfdPackageDetails['ext-cpd'] = [];
671 this.vnfdPackageDetails['ext-cpd'].push({
672 id: 'cp_' + randomID,
675 if (this.vnfdPackageDetails['mgmt-cp'] === undefined) {
676 this.vnfdPackageDetails['mgmt-cp'] = 'cp_' + randomID;
678 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
680 /** Drop IntVL Composer Data @private */
681 private intvlDropCompose(): void {
682 const randomID: string = this.sharedService.randomString();
683 if (this.vnfdPackageDetails['int-virtual-link-desc'] === undefined) {
684 this.vnfdPackageDetails['int-virtual-link-desc'] = [];
686 this.vnfdPackageDetails['int-virtual-link-desc'].push({
687 id: 'vnf_vl_' + randomID
689 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
691 /** Add the Add Nodes Data @private */
692 private addNodes(apiURL: string, identifier: string, data: VNFD): void {
693 this.isLoadingResults = true;
694 const apiURLHeader: APIURLHEADER = {
695 url: apiURL + '/' + identifier + '/package_content',
696 httpOptions: { headers: this.headers }
698 const vnfData: VNFDATA = {};
700 const descriptorInfo: string = jsyaml.dump(vnfData, { sortKeys: true });
701 this.sharedService.targzFile({ packageType: 'vnfd', id: this.identifier, descriptor: descriptorInfo })
702 .then((content: ArrayBuffer): void => {
703 this.restService.putResource(apiURLHeader, content).subscribe((res: {}): void => {
705 this.notifierService.notify('success', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.UPDATEDSUCCESSFULLY'));
706 this.isLoadingResults = false;
707 }, (error: ERRORDATA): void => {
709 this.restService.handleError(error, 'put');
710 this.isLoadingResults = false;
712 }).catch((): void => {
713 this.notifierService.notify('error', this.translateService.instant('ERROR'));
714 this.isLoadingResults = false;
717 /** Events handles when mousedown click it will capture the selected node data @private */
718 private mouseDown(d: COMPOSERNODES): void {
719 event.preventDefault();
720 if (d3.event.ctrlKey) { return; }
721 if (d3.event.shiftKey) {
722 this.mousedownNode = d;
723 this.currentSelectedNode = (this.mousedownNode === this.currentSelectedNode) ? null : this.mousedownNode;
724 this.dragLine.classed('hidden', false)
725 .attr('d', `M${this.mousedownNode.x},${this.mousedownNode.y}L${this.mousedownNode.x},${this.mousedownNode.y}`);
728 /** Event handles when mouseup event occures @private */
729 private mouseUp(d: COMPOSERNODES): void {
730 if (!this.mousedownNode) { return; }
731 this.dragLine.classed('hidden', true);
732 this.mouseupNode = d;
733 if (this.mousedownNode.type === 'vdu') {
734 this.vduMouseDownNode();
735 } else if (this.mousedownNode.type === 'cp') {
736 this.cpMouseDownNode();
737 } else if (this.mousedownNode.type === 'intvl') {
738 this.intVLMouseDownNode();
739 } else if (this.mousedownNode.type === 'intcp') {
740 this.intCPMouseDownNode();
742 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
745 this.resetMouseActions();
746 this.currentSelectedNode = null;
748 /** Establish a connection point between vdu and other nodes @private */
749 private vduMouseDownNode(): void {
750 if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'cp') {
751 this.vduCPConnection(this.mousedownNode.id, this.mouseupNode.id);
752 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intcp') {
753 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDINTCP'));
755 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'vdu') {
756 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDVDU'));
758 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intvl') {
759 this.vduIntvlConnection(this.mousedownNode.id, this.mouseupNode.id);
762 /** Establish a connection point between cp and other nodes @private */
763 private cpMouseDownNode(): void {
764 if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'vdu') {
765 this.vduCPConnection(this.mouseupNode.id, this.mousedownNode.id);
766 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intvl') {
767 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDVNFVL'));
769 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intcp') {
770 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDINTCP'));
772 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'cp') {
773 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDCP'));
777 /** Establish a connection piont between intvl and other nodes @private */
778 private intVLMouseDownNode(): void {
779 if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'cp') {
780 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDCP'));
782 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'vdu') {
783 this.vduIntvlConnection(this.mouseupNode.id, this.mousedownNode.id);
784 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intvl') {
785 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDVNFVL'));
787 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intcp') {
788 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDONTCP'));
792 /** Establish a connection point between intcp and other nodes @private */
793 private intCPMouseDownNode(): void {
794 if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'vdu') {
795 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVDU'));
797 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'cp') {
798 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDCP'));
800 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intvl') {
801 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVNFVL'));
803 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intcp') {
804 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDINTCP'));
808 /** Establish a connection between VDU & CP vice versa @private */
809 private vduCPConnection(nodeA: string, nodeB: string): void {
810 const vduExternalID: string = nodeA + '-eth_' + this.sharedService.randomString();
811 if (this.vnfdPackageDetails.vdu !== undefined) {
812 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
813 const vduID: string = vdu.id;
814 if (vdu.id === nodeA) {
815 if (this.vnfdPackageDetails['ext-cpd'] !== undefined) {
816 this.vnfdPackageDetails['ext-cpd'].forEach((extcpd: EXTCPD, index: number): void => {
817 if (extcpd.id === nodeB) {
818 if (vdu['int-cpd'] === undefined) {
821 vdu['int-cpd'].push({
823 'virtual-network-interface-requirement': [
827 'virtual-interface': { type: 'PARAVIRT' }
831 this.vnfdPackageDetails['ext-cpd'][index] = {
844 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
847 /** Establish a connection between vdu & intvl and vice versa @private */
848 private vduIntvlConnection(nodeA: string, nodeB: string): void {
849 const vduInternalID: string = nodeA + '-eth_' + this.sharedService.randomString();
850 if (this.vnfdPackageDetails.vdu !== undefined) {
851 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
852 if (vdu.id === nodeA) {
853 if (vdu['int-cpd'] === undefined) {
856 vdu['int-cpd'].push({
858 'int-virtual-link-desc': nodeB,
859 'virtual-network-interface-requirement': [
863 'virtual-interface': { type: 'PARAVIRT' }
870 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
873 /** Events handles when mousemove it will capture the selected node data @private */
874 private mousemove(): void {
875 if (!this.mousedownNode) { return; }
876 this.dragLine.attr('d',
877 `M${this.mousedownNode.x},${this.mousedownNode.y}L${d3.mouse(d3.event.currentTarget)[0]},${d3.mouse(d3.event.currentTarget)[1]}`);
879 /** reset Mouse varaibles @private */
880 private resetMouseActions(): void {
881 this.mousedownNode = null;
882 this.mouseupNode = null;
884 /** drag event @private */
885 // tslint:disable-next-line: no-any
886 private onDragDrop(): any {
887 return d3.drag().filter(this.dragFilter)
888 .on('start', this.dragstarted)
889 .on('drag', this.dragged)
890 .on('end', this.dragended);
892 /** Key press event @private */
893 private keyDown(): void {
894 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
895 if (this.lastKeyDown !== -1) { return; }
896 this.lastKeyDown = d3.event.keyCode;
897 if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) {
898 this.svg.classed('ctrl', true);
901 /** Key realse event @private */
902 private keyUp(): void {
903 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
904 this.lastKeyDown = -1;
905 if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) {
906 this.gNetwork.on('.drag', null);
907 this.gVirutualDeploymentUnit.on('.drag', null);
908 this.gConnectionPoint.on('.drag', null);
909 this.gIntConnectionPoint.on('.drag', null);
910 this.svg.classed('ctrl', false);
913 /** Mosue Drag Line false if it is not satisfied @private */
914 private deselectPath(): void {
915 this.dragLine.classed('hidden', true).attr('d', 'M0,0L0,0');
917 /** Events handles when Shift Click to perform create cp @private */
918 // tslint:disable-next-line: no-any
919 private singleClick(nodeSelected: any, d: COMPOSERNODES): void {
920 this.selectedNode(nodeSelected, d);
922 /** Get confirmation Before Deleting the Node in Topology @private */
923 private getDeleteNodeConfirmation(d: COMPOSERNODES): void {
924 const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' });
925 modalRef.componentInstance.topologyType = 'Delete';
926 modalRef.componentInstance.topologyname = d.name;
927 if (d.type === 'vdu') {
928 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.VDU';
929 } else if (d.type === 'intvl') {
930 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTVL';
931 } else if (d.type === 'cp') {
932 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.CONNECTIONPOINT';
933 } else if (d.type === 'intcp') {
934 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTCP';
936 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
942 /** Delete nodes @private */
943 private deleteNode(d: COMPOSERNODES): void {
944 // tslint:disable-next-line: max-func-body-length
945 this.nodes.forEach((node: VNFD): void => {
946 if (node.id === d.id) {
947 if (d.type === 'cp') {
948 if (this.vnfdPackageDetails['ext-cpd'] !== undefined) {
949 let getRelatedVDUCPD: string; let getRelatedVDUID: string;
950 const posExtCPD: number = this.vnfdPackageDetails['ext-cpd'].findIndex((e: EXTCPD): boolean => {
951 if (e.id === d.name) {
952 if (e['int-cpd'] !== undefined) {
953 getRelatedVDUCPD = e['int-cpd'].cpd; getRelatedVDUID = e['int-cpd']['vdu-id'];
960 if (posExtCPD !== -1) {
961 this.vnfdPackageDetails['ext-cpd'].splice(posExtCPD, 1);
963 if (getRelatedVDUCPD !== undefined && getRelatedVDUID !== undefined) {
964 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
965 if (vdu.id === getRelatedVDUID) {
966 const posINTCPD: number = vdu['int-cpd'].findIndex((intCPD: VDUINTCPD): boolean => {
967 return intCPD.id === getRelatedVDUCPD;
969 if (posINTCPD !== -1) {
970 vdu['int-cpd'].splice(posINTCPD, 1);
976 } else if (d.type === 'intcp') {
977 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
978 const posINTCPD: number = vdu['int-cpd'].findIndex((intCPD: VDUINTCPD): boolean => {
979 return intCPD.id === d.id;
981 if (posINTCPD !== -1) {
982 vdu['int-cpd'].splice(posINTCPD, 1);
985 } else if (d.type === 'intvl') {
986 const posINTVLD: number = this.vnfdPackageDetails['int-virtual-link-desc'].findIndex((intVLD: IVLD): boolean => {
987 return intVLD.id === d.id;
989 if (posINTVLD !== -1) {
990 this.vnfdPackageDetails['int-virtual-link-desc'].splice(posINTVLD, 1);
992 if (this.vnfdPackageDetails.vdu !== undefined) {
993 this.vnfdPackageDetails.vdu.forEach((vduDetails: VDU): void => {
994 if (vduDetails['int-cpd'] !== undefined) {
995 const newVDUintCPDArray: VDUINTCPD[] = vduDetails['int-cpd'].filter((item: VDUINTCPD): boolean => {
996 return item['int-virtual-link-desc'] !== undefined ? item['int-virtual-link-desc'] !== d.id ? true : false : true;
998 vduDetails['int-cpd'] = newVDUintCPDArray;
1002 } else if (d.type === 'vdu') {
1003 const getRelatedExtCPD: string[] = [];
1004 const posVDU: number = this.vnfdPackageDetails.vdu.findIndex((vduDetails: VDU): boolean => {
1005 if (vduDetails.id === d.id) {
1006 if (vduDetails['int-cpd'] !== undefined) {
1007 vduDetails['int-cpd'].forEach((intCPDDetails: VDUINTCPD): void => {
1008 if (intCPDDetails['int-virtual-link-desc'] === undefined) {
1009 getRelatedExtCPD.push(intCPDDetails.id);
1018 if (posVDU !== -1) {
1019 this.vnfdPackageDetails.vdu.splice(posVDU, 1);
1021 getRelatedExtCPD.forEach((CPDID: string, index: number): void => {
1022 this.vnfdPackageDetails['ext-cpd'].forEach((extCPD: EXTCPD): void => {
1023 if (extCPD['int-cpd'] !== undefined) {
1024 if (extCPD['int-cpd'].cpd === CPDID) {
1025 extCPD['int-cpd'] = {};
1031 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
1033 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
1037 /** Get confirmation before deleting the ink in Topology @private */
1038 private getDeleteLinkConfirmation(d: Tick): void {
1039 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.YOUCANNOTDELETELINK'));
1041 /** Selected nodes @private */
1042 // tslint:disable-next-line: no-any
1043 private selectedNode(nodeSeleced: any, d: COMPOSERNODES): void {
1044 const alreadyIsActive: boolean = nodeSeleced.select('#' + d.id).classed(this.activeNode);
1045 this.deselectAllNodes();
1046 nodeSeleced.select('#' + d.id).classed(this.activeNode, !alreadyIsActive);
1047 if (d.type === 'vdu' && !alreadyIsActive) {
1048 this.vnfdPackageDetails.vdu.forEach((res: VDU): void => {
1049 if (res.id === d.id) {
1050 this.showRightSideInfo = 'vduInfo';
1052 this.oldVDUID = res.id;
1055 } else if (d.type === 'cp' && !alreadyIsActive) {
1056 this.vnfdPackageDetails['ext-cpd'].forEach((cp: EXTCPD): void => {
1057 const getCPDID: string = cp['int-cpd'] !== undefined ? cp['int-cpd'].cpd : cp.id;
1058 if (getCPDID === d.id) {
1059 this.showRightSideInfo = 'cpInfo';
1061 this.oldCPID = cp.id;
1064 } else if (d.type === 'intvl' && !alreadyIsActive) {
1065 this.vnfdPackageDetails['int-virtual-link-desc'].forEach((ivld: IVLD): void => {
1066 if (ivld.id === d.id) {
1067 this.showRightSideInfo = 'intvlInfo';
1068 this.intvlInfo = ivld;
1069 this.oldintVLID = ivld.id;
1072 } else if (d.type === 'intcp' && !alreadyIsActive) {
1073 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
1074 vdu['int-cpd'].forEach((intcpd: VDUINTCPD): void => {
1075 if (intcpd.id === d.id) {
1076 if (intcpd['int-virtual-link-desc'] !== undefined) {
1077 intcpd['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
1078 this.intcpInfo = vnir;
1079 this.showRightSideInfo = 'intcpInfo';
1086 this.showRightSideInfo = 'vnfdInfo';
1089 /** De-select all the selected nodes @private */
1090 private deselectAllNodes(): void {
1091 this.network.select('image').classed(this.activeNode, false);
1092 this.virutualDeploymentUnit.select('image').classed(this.activeNode, false);
1093 this.connectionPoint.select('image').classed(this.activeNode, false);
1094 this.intConnectionPoint.select('image').classed(this.activeNode, false);
1096 /** Events handles when to drag using filter for the keys @private */
1097 private dragFilter(): boolean {
1098 return d3.event.ctrlKey && !d3.event.button;
1100 /** Events handles when dragstarted @private */
1101 private dragstarted(d: COMPOSERNODES): void {
1105 /** Events handles when dragged @private */
1106 private dragged(d: COMPOSERNODES): void {
1107 d.fx = d.x = d3.event.x;
1108 d.fy = d.y = d3.event.y;
1110 /** Events handles when dragended @private */
1111 private dragended(d: COMPOSERNODES): void {
1112 if (this.forceSimulationActive) {
1118 this.forceSimulationActive = false;
1121 /** Events handles when node double click @private */
1122 private onNodedblClickToggleSidebar(): void {
1123 this.sideBarOpened = false;
1125 /** Events handles when node single click @private */
1126 private onNodeClickToggleSidebar(): void {
1127 this.sideBarOpened = true;