blob: 55c5070523f3064aff606af17c130fffdf09f484 [file] [log] [blame]
kumaran.m3b4814a2020-05-01 19:48:54 +05301/*
2 Copyright 2020 TATA ELXSI
3
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
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
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.
15
16 Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17 */
18/**
19 * @file VNFComposerComponent
20 */
21import { HttpHeaders } from '@angular/common/http';
22import { Component, ElementRef, Injector, ViewChild, ViewEncapsulation } from '@angular/core';
23import { ActivatedRoute, Router } from '@angular/router';
24import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
25import { TranslateService } from '@ngx-translate/core';
26import { NotifierService } from 'angular-notifier';
Barath Kumar R063a3f12020-12-29 16:35:09 +053027import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
kumaran.m3b4814a2020-05-01 19:48:54 +053028import { ConfirmationTopologyComponent } from 'ConfirmationTopology';
29import * as d3 from 'd3';
30import { DataService } from 'DataService';
31import { environment } from 'environment';
32import * as HttpStatus from 'http-status-codes';
33import * as jsyaml from 'js-yaml';
34import { RestService } from 'RestService';
35import { SharedService } from 'SharedService';
Barath Kumar R063a3f12020-12-29 16:35:09 +053036import { COMPOSERNODES, EXTCPD, GRAPHDETAILS, INTCPD, IVLD, Tick, TickPath, VDU, VDUINTCPD, VNFD, VNFDATA, VNIR } from 'VNFDModel';
kumaran.m3b4814a2020-05-01 19:48:54 +053037
38/**
39 * Creating component
40 * @Component takes VNFComposerComponent.html as template url
41 */
42@Component({
43 templateUrl: './VNFComposerComponent.html',
44 styleUrls: ['./VNFComposerComponent.scss'],
45 encapsulation: ViewEncapsulation.None
46})
47/** Exporting a class @exports VNFComposerComponent */
48export 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[] = [];
kumaran.m3b4814a2020-05-01 19:48:54 +053059 /** Contains VNFD Information @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +053060 public vnfdInfo: VNFD = { 'product-name': '', description: '', version: '', id: '', provider: '' };
kumaran.m3b4814a2020-05-01 19:48:54 +053061 /** 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;
kumaran.m3b4814a2020-05-01 19:48:54 +053075 /** Contains SVG attributes @private */
76 // tslint:disable-next-line:no-any
77 private svg: any;
78 /** Contains forced node animations @private */
79 // tslint:disable-next-line:no-any
80 private force: 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
88 private path: any;
89 /** Contains node network @private */
90 // tslint:disable-next-line:no-any
91 private network: 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 */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530102 private nodes: COMPOSERNODES[] = [];
kumaran.m3b4814a2020-05-01 19:48:54 +0530103 /** 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 */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530132 private vnfdPackageDetails: VNFD;
kumaran.m3b4814a2020-05-01 19:48:54 +0530133 /** 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;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530145 /** Contains VDU Old value Information @private */
146 private oldVDUID: string;
kumaran.m3b4814a2020-05-01 19:48:54 +0530147 /** Contains Internal VL Information @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530148 private intvlInfo: IVLD;
149 /** Contains Internal VL Old value Information @private */
150 private oldintVLID: string;
kumaran.m3b4814a2020-05-01 19:48:54 +0530151 /** Contains Connection Point Information @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530152 private cpInfo: EXTCPD;
153 /** Contains Connection Point Old value Information @private */
154 private oldCPID: string;
kumaran.m3b4814a2020-05-01 19:48:54 +0530155 /** Contains Internal Connection Point Information @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530156 private intcpInfo: VNIR;
kumaran.m3b4814a2020-05-01 19:48:54 +0530157 /** Instance of the modal service @private */
158 private modalService: NgbModal;
159
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);
170 }
171 /**
172 * Lifecyle Hooks the trigger before component is instantiate
173 */
174 public ngOnInit(): void {
175 // tslint:disable-next-line:no-backbone-get-set-outside-model
176 this.identifier = this.activatedRoute.snapshot.paramMap.get('id');
177 this.generateData();
178 this.headers = new HttpHeaders({
harshini.r92d376d2022-04-05 12:35:14 +0530179 'Content-Type': 'application/gzip',
kumaran.m3b4814a2020-05-01 19:48:54 +0530180 Accept: 'application/json',
181 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
182 });
183 }
184
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';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530189 this.restService.getResource(environment.VNFPACKAGESCONTENT_URL + '/' + this.identifier)
190 .subscribe((vnfdPackageDetails: VNFD): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530191 try {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530192 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);
kumaran.m3b4814a2020-05-01 19:48:54 +0530202 this.createNode(this.nodes);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530203 this.generateVNFInfo(vnfdPackageDetails);
kumaran.m3b4814a2020-05-01 19:48:54 +0530204 } catch (e) {
205 this.notifierService.notify('error', this.translateService.instant('ERROR'));
206 }
207 this.isLoadingResults = false;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530208 }, (error: ERRORDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530209 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();
212 } else {
213 this.restService.handleError(error, 'get');
214 }
215 this.isLoadingResults = false;
216 this.showRightSideInfo = '';
217 });
218 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530219 /** 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;
226 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530227 /** 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);
231 }
232 /** Events handles drop at D3 region @public */
233 public drop(ev: DragEvent): void {
234 ev.preventDefault();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530235 const getDropedName: string = ev.dataTransfer.getData('text');
236 if (getDropedName === 'vdu') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530237 this.svg.selectAll('*').remove();
238 this.vduDropCompose();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530239 } else if (getDropedName === 'cp') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530240 this.svg.selectAll('*').remove();
241 this.cpDropCompose();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530242 } else if (getDropedName === 'intvl') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530243 this.svg.selectAll('*').remove();
244 this.intvlDropCompose();
245 }
246 }
247 /** Events handles allow drop on D3 region @public */
248 public allowDrop(ev: DragEvent): void {
249 ev.preventDefault();
250 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530251 /** Generate and list VDU @public */
252 public generateVDU(vnfdPackageDetails: VNFD): void {
253 if (vnfdPackageDetails.vdu !== undefined) {
254 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
255 this.nodes.push({
256 id: vdu.id,
257 name: vdu.name,
258 reflexive: false,
259 type: 'vdu'
260 });
kumaran.m3b4814a2020-05-01 19:48:54 +0530261 });
262 }
263 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530264 /** 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 => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530268 this.nodes.push({
Barath Kumar R86e497d2021-05-04 17:16:14 +0530269 id: cp['int-cpd'].cpd !== undefined ? cp['int-cpd'].cpd : cp.id,
Barath Kumar R063a3f12020-12-29 16:35:09 +0530270 name: cp.id,
271 reflexive: false,
272 type: 'cp'
kumaran.m3b4814a2020-05-01 19:48:54 +0530273 });
274 });
275 }
276 }
277 /** Generate and list Internal VLD @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530278 public generateInternalVLD(vnfdPackageDetails: VNFD): void {
279 if (vnfdPackageDetails['int-virtual-link-desc'] !== undefined) {
280 vnfdPackageDetails['int-virtual-link-desc'].forEach((ivld: IVLD): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530281 this.nodes.push({
Barath Kumar R063a3f12020-12-29 16:35:09 +0530282 id: ivld.id,
283 name: ivld.id,
284 reflexive: false,
285 type: 'intvl'
kumaran.m3b4814a2020-05-01 19:48:54 +0530286 });
287 });
288 }
289 }
290 /** Generate and list Internal CP @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530291 public generateInternalCP(vnfdPackageDetails: VNFD): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530292 if (vnfdPackageDetails.vdu !== undefined) {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530293 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 => {
298 this.nodes.push({
299 id: intcpd.id,
300 name: vnir.name,
301 reflexive: false,
302 type: 'intcp'
303 });
304 });
305 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530306 });
307 }
308 });
309 }
310 }
311 /** Generate VDU External and Internal CP Links @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530312 public generateVDUCPLinks(vnfdPackageDetails: VNFD): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530313 if (vnfdPackageDetails.vdu !== undefined) {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530314 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 });
321 });
322 } else {
323 this.links.push({ source: vduLink, target: intCPD.id });
kumaran.m3b4814a2020-05-01 19:48:54 +0530324 }
325 });
326 }
327 });
328 }
329 }
330 /** Generate Network/VLD/Internal VirtualLink, CP Links @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530331 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 });
340 });
341 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530342 });
343 }
344 });
345 }
346 }
347 /** VNFD details can be saved on users inputs @public */
348 public saveVNFD(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530349 this.vnfdPackageDetails['product-name'] = this.vnfdInfo['product-name'];
kumaran.m3b4814a2020-05-01 19:48:54 +0530350 this.vnfdPackageDetails.description = this.vnfdInfo.description;
351 this.vnfdPackageDetails.version = this.vnfdInfo.version;
352 this.vnfdPackageDetails.id = this.vnfdInfo.id;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530353 this.vnfdPackageDetails.provider = this.vnfdInfo.provider;
kumaran.m3b4814a2020-05-01 19:48:54 +0530354 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
kumaran.m3b4814a2020-05-01 19:48:54 +0530355 }
356 /** VDU details can be saved on users inputs @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530357 public saveVDU(getVDUID: string): void {
358 const getOLDVDUID: string = this.oldVDUID;
359 this.vnfdPackageDetails.vdu.forEach((ref: VDU): void => {
360 if (ref.id === getVDUID) {
kumaran.m3b4814a2020-05-01 19:48:54 +0530361 ref.id = this.vduInfo.id;
362 ref.name = this.vduInfo.name;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530363 ref.description = this.vduInfo.description !== undefined ? this.vduInfo.description : '';
364 ref['sw-image-desc'] = this.vduInfo['sw-image-desc'];
365 }
366 });
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;
371 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530372 }
373 });
374 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
375 }
376 /** IntVL details can be saved on users inputs @public */
377 public saveIntVL(intVLID: string): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530378 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;
382 }
383 });
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;
390 }
391 }
392 });
kumaran.m3b4814a2020-05-01 19:48:54 +0530393 }
394 });
395 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
396 }
397 /** IntVL details can be saved on users inputs @public */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530398 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;
kumaran.m3b4814a2020-05-01 19:48:54 +0530403 }
404 });
Barath Kumar R063a3f12020-12-29 16:35:09 +0530405 if (this.vnfdPackageDetails['mgmt-cp'] === getOldCP) {
406 this.vnfdPackageDetails['mgmt-cp'] = this.cpInfo.id;
407 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530408 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
409 }
410 /** Edit topology @public */
411 public onEdit(): void {
412 this.router.navigate(['/packages/vnf/edit/', this.identifier]).catch();
413 }
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');
Barath Kumar R063a3f12020-12-29 16:35:09 +0530419 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530420 if (result) {
421 // empty
422 }
423 }).catch();
424 }
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) {
431 this.force.stop();
432 }
433 this.forceSimulationActive = alreadyFixedIsActive;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530434 this.nodes.forEach((d: COMPOSERNODES): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530435 d.fx = (alreadyFixedIsActive) ? null : d.x;
436 d.fy = (alreadyFixedIsActive) ? null : d.y;
437 });
438 if (alreadyFixedIsActive) {
439 this.force.restart();
440 }
441 }
442 /** Events handles when dragended @public */
443 public toggleSidebar(): void {
444 this.sideBarOpened = !this.sideBarOpened;
445 this.deselectAllNodes();
446 this.showRightSideInfo = 'vnfdInfo';
447 }
448 /** Get the default Configuration of containers @private */
449 private getGraphContainerAttr(): GRAPHDETAILS {
450 return {
451 width: 700,
452 height: 400,
453 nodeHeight: 50,
454 nodeWidth: 35,
455 textX: -35,
456 textY: 30,
457 radius: 5,
458 distance: 50,
459 strength: -500,
460 forcex: 2,
461 forcey: 2,
462 sourcePaddingYes: 17,
463 sourcePaddingNo: 12,
464 targetPaddingYes: 4,
465 targetPaddingNo: 3,
466 alphaTarget: 0.3,
467 imageX: -25,
468 imageY: -25,
469 shiftKeyCode: 17
470 };
471 }
472 /** Node is created and render at D3 region @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530473 private createNode(nodes: VNFD[]): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530474 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
475 d3.selectAll('svg#graphContainer > *').remove();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530476 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(); });
kumaran.m3b4814a2020-05-01 19:48:54 +0530482 this.force = d3.forceSimulation()
Barath Kumar R063a3f12020-12-29 16:35:09 +0530483 .force('link', d3.forceLink().id((d: TickPath): string => d.id).distance(graphContainerAttr.distance))
kumaran.m3b4814a2020-05-01 19:48:54 +0530484 .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))
Barath Kumar R063a3f12020-12-29 16:35:09 +0530487 .on('tick', (): void => { this.tick(); });
kumaran.m3b4814a2020-05-01 19:48:54 +0530488 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');
494 this.restart(nodes);
495 }
496 /** Update force layout (called automatically each iteration) @private */
497 private tick(): void {
498 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530499 this.path.attr('d', (d: Tick): string => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530500 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}`;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530508 }).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})`);
kumaran.m3b4814a2020-05-01 19:48:54 +0530513 }
514 /** Update graph (called when needed) @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530515 private restart(nodes: VNFD[]): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530516 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
Barath Kumar R063a3f12020-12-29 16:35:09 +0530519 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); }
kumaran.m3b4814a2020-05-01 19:48:54 +0530524 });
Barath Kumar R063a3f12020-12-29 16:35:09 +0530525 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);
kumaran.m3b4814a2020-05-01 19:48:54 +0530529 this.resetAndCreateNodes();
530 this.force.nodes(nodes).force('link').links(this.links); //Set the graph in motion
531 this.force.alphaTarget(graphContainerAttr.alphaTarget).restart();
532 }
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();
540 this.getPathNodes();
541 this.getgNetwork();
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);
550 }
551 /** Setting the Path @private */
552 private getPathNodes(): void {
553 this.path = this.path.enter().append('svg:path').attr('class', 'link');
554 }
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')
561 .style('opacity', 1)
562 .attr('x', graphContainerAttr.imageX)
563 .attr('y', graphContainerAttr.imageY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530564 .call(this.onDragDrop())
565 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
kumaran.m3b4814a2020-05-01 19:48:54 +0530566 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
567 .attr('xlink:href', 'assets/images/INTVL.svg')
Barath Kumar R063a3f12020-12-29 16:35:09 +0530568 .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(); });
kumaran.m3b4814a2020-05-01 19:48:54 +0530572 this.gNetwork.append('svg:text')
573 .attr('class', 'node_text')
574 .attr('y', graphContainerAttr.textY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530575 .text((d: COMPOSERNODES): string => d.id);
kumaran.m3b4814a2020-05-01 19:48:54 +0530576 }
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')
583 .style('opacity', 1)
584 .attr('x', graphContainerAttr.imageX)
585 .attr('y', graphContainerAttr.imageY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530586 .call(this.onDragDrop())
587 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
kumaran.m3b4814a2020-05-01 19:48:54 +0530588 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
589 .attr('xlink:href', 'assets/images/VDU.svg')
Barath Kumar R063a3f12020-12-29 16:35:09 +0530590 .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(); });
kumaran.m3b4814a2020-05-01 19:48:54 +0530594 this.gVirutualDeploymentUnit.append('svg:text')
595 .attr('class', 'node_text')
596 .attr('y', graphContainerAttr.textY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530597 .text((d: COMPOSERNODES): string => d.id);
kumaran.m3b4814a2020-05-01 19:48:54 +0530598 }
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')
605 .style('opacity', 1)
606 .attr('x', graphContainerAttr.imageX)
607 .attr('y', graphContainerAttr.imageY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530608 .call(this.onDragDrop())
609 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
kumaran.m3b4814a2020-05-01 19:48:54 +0530610 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
611 .attr('xlink:href', 'assets/images/CP-VNF.svg')
Barath Kumar R063a3f12020-12-29 16:35:09 +0530612 .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(); });
kumaran.m3b4814a2020-05-01 19:48:54 +0530616 this.gConnectionPoint.append('svg:text')
617 .attr('class', 'node_text')
618 .attr('y', graphContainerAttr.textY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530619 .text((d: COMPOSERNODES): string => d.name);
kumaran.m3b4814a2020-05-01 19:48:54 +0530620 }
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')
627 .style('opacity', 1)
628 .attr('x', graphContainerAttr.imageX)
629 .attr('y', graphContainerAttr.imageY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530630 .call(this.onDragDrop())
631 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
kumaran.m3b4814a2020-05-01 19:48:54 +0530632 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
633 .attr('xlink:href', 'assets/images/INTCP.svg')
Barath Kumar R063a3f12020-12-29 16:35:09 +0530634 .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(); });
kumaran.m3b4814a2020-05-01 19:48:54 +0530638 this.gIntConnectionPoint.append('svg:text')
639 .attr('class', 'node_text')
640 .attr('y', graphContainerAttr.textY)
Barath Kumar R063a3f12020-12-29 16:35:09 +0530641 .text((d: COMPOSERNODES): string => d.name);
kumaran.m3b4814a2020-05-01 19:48:54 +0530642 }
643 /** Drop VDU Composer Data @private */
644 private vduDropCompose(): void {
645 const randomID: string = this.sharedService.randomString();
Barath Kumar R86e497d2021-05-04 17:16:14 +0530646 if (this.vnfdPackageDetails['mgmt-cp'] === undefined) {
647 this.notifierService.notify('error', this.translateService.instant('PAGE.TOPOLOGY.ADDCPBEFOREVDU'));
648 } else {
649 if (this.vnfdPackageDetails.vdu === undefined) {
650 this.vnfdPackageDetails.vdu = [];
651 }
652 this.vnfdPackageDetails.vdu.push({
653 id: 'vdu_' + randomID,
654 name: 'vdu_' + randomID,
655 description: '',
656 'sw-image-desc': 'ubuntu',
657 'int-cpd': [],
658 'monitoring-parameter': [],
659 'virtual-compute-desc': '',
660 'virtual-storage-desc': []
661 });
662 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530663 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530664 }
665 /** Drop CP Composer Data @private */
666 private cpDropCompose(): void {
667 const randomID: string = this.sharedService.randomString();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530668 if (this.vnfdPackageDetails['ext-cpd'] === undefined) {
669 this.vnfdPackageDetails['ext-cpd'] = [];
kumaran.m3b4814a2020-05-01 19:48:54 +0530670 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530671 this.vnfdPackageDetails['ext-cpd'].push({
672 id: 'cp_' + randomID,
673 'int-cpd': {}
kumaran.m3b4814a2020-05-01 19:48:54 +0530674 });
Barath Kumar R86e497d2021-05-04 17:16:14 +0530675 if (this.vnfdPackageDetails['mgmt-cp'] === undefined) {
676 this.vnfdPackageDetails['mgmt-cp'] = 'cp_' + randomID;
677 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530678 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
679 }
680 /** Drop IntVL Composer Data @private */
681 private intvlDropCompose(): void {
682 const randomID: string = this.sharedService.randomString();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530683 if (this.vnfdPackageDetails['int-virtual-link-desc'] === undefined) {
684 this.vnfdPackageDetails['int-virtual-link-desc'] = [];
685 }
686 this.vnfdPackageDetails['int-virtual-link-desc'].push({
687 id: 'vnf_vl_' + randomID
kumaran.m3b4814a2020-05-01 19:48:54 +0530688 });
689 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
690 }
691 /** Add the Add Nodes Data @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530692 private addNodes(apiURL: string, identifier: string, data: VNFD): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530693 this.isLoadingResults = true;
694 const apiURLHeader: APIURLHEADER = {
695 url: apiURL + '/' + identifier + '/package_content',
696 httpOptions: { headers: this.headers }
697 };
Barath Kumar R063a3f12020-12-29 16:35:09 +0530698 const vnfData: VNFDATA = {};
699 vnfData.vnfd = data;
kumaran.m3b4814a2020-05-01 19:48:54 +0530700 const descriptorInfo: string = jsyaml.dump(vnfData, { sortKeys: true });
701 this.sharedService.targzFile({ packageType: 'vnfd', id: this.identifier, descriptor: descriptorInfo })
702 .then((content: ArrayBuffer): void => {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530703 this.restService.putResource(apiURLHeader, content).subscribe((res: {}): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530704 this.generateData();
705 this.notifierService.notify('success', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.UPDATEDSUCCESSFULLY'));
706 this.isLoadingResults = false;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530707 }, (error: ERRORDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530708 this.generateData();
709 this.restService.handleError(error, 'put');
710 this.isLoadingResults = false;
711 });
712 }).catch((): void => {
713 this.notifierService.notify('error', this.translateService.instant('ERROR'));
714 this.isLoadingResults = false;
715 });
716 }
717 /** Events handles when mousedown click it will capture the selected node data @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530718 private mouseDown(d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530719 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}`);
726 }
727 }
728 /** Event handles when mouseup event occures @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530729 private mouseUp(d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530730 if (!this.mousedownNode) { return; }
731 this.dragLine.classed('hidden', true);
732 this.mouseupNode = d;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530733 if (this.mousedownNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530734 this.vduMouseDownNode();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530735 } else if (this.mousedownNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530736 this.cpMouseDownNode();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530737 } else if (this.mousedownNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530738 this.intVLMouseDownNode();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530739 } else if (this.mousedownNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530740 this.intCPMouseDownNode();
741 } else {
kumaran.m3b4814a2020-05-01 19:48:54 +0530742 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
743 this.deselectPath();
744 }
745 this.resetMouseActions();
746 this.currentSelectedNode = null;
747 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530748 /** Establish a connection point between vdu and other nodes @private */
749 private vduMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530750 if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530751 this.vduCPConnection(this.mousedownNode.id, this.mouseupNode.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530752 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530753 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDINTCP'));
754 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530755 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530756 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDVDU'));
757 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530758 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530759 this.vduIntvlConnection(this.mousedownNode.id, this.mouseupNode.id);
760 }
761 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530762 /** Establish a connection point between cp and other nodes @private */
763 private cpMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530764 if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530765 this.vduCPConnection(this.mouseupNode.id, this.mousedownNode.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530766 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530767 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDVNFVL'));
768 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530769 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530770 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDINTCP'));
771 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530772 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530773 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDCP'));
774 this.deselectPath();
775 }
776 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530777 /** Establish a connection piont between intvl and other nodes @private */
778 private intVLMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530779 if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530780 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDCP'));
781 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530782 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530783 this.vduIntvlConnection(this.mouseupNode.id, this.mousedownNode.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530784 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530785 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDVNFVL'));
786 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530787 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530788 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDONTCP'));
789 this.deselectPath();
790 }
791 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530792 /** Establish a connection point between intcp and other nodes @private */
793 private intCPMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530794 if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530795 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVDU'));
796 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530797 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530798 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDCP'));
799 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530800 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530801 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVNFVL'));
802 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530803 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530804 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDINTCP'));
805 this.deselectPath();
806 }
807 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530808 /** Establish a connection between VDU & CP vice versa @private */
809 private vduCPConnection(nodeA: string, nodeB: string): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530810 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) {
819 vdu['int-cpd'] = [];
820 }
Barath Kumar R86e497d2021-05-04 17:16:14 +0530821 vdu['int-cpd'].push({
822 id: vduExternalID,
823 'virtual-network-interface-requirement': [
824 {
825 name: vduExternalID,
826 position: 1,
827 'virtual-interface': { type: 'PARAVIRT' }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530828 }
Barath Kumar R86e497d2021-05-04 17:16:14 +0530829 ]
830 });
831 this.vnfdPackageDetails['ext-cpd'][index] = {
832 id: extcpd.id,
833 'int-cpd': {
834 cpd: vduExternalID,
835 'vdu-id': vduID
836 }
837 };
Barath Kumar R063a3f12020-12-29 16:35:09 +0530838 }
839 });
840 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530841 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530842 });
843 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530844 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
845 this.deselectPath();
846 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530847 /** Establish a connection between vdu & intvl and vice versa @private */
848 private vduIntvlConnection(nodeA: string, nodeB: string): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530849 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) {
854 vdu['int-cpd'] = [];
855 }
856 vdu['int-cpd'].push({
857 id: vduInternalID,
858 'int-virtual-link-desc': nodeB,
859 'virtual-network-interface-requirement': [
860 {
861 name: vduInternalID,
862 position: 1,
863 'virtual-interface': { type: 'PARAVIRT' }
864 }
865 ]
866 });
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530867 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530868 });
869 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530870 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
871 this.deselectPath();
872 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530873 /** 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]}`);
878 }
879 /** reset Mouse varaibles @private */
880 private resetMouseActions(): void {
881 this.mousedownNode = null;
882 this.mouseupNode = null;
883 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530884 /** 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);
891 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530892 /** 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) {
kumaran.m3b4814a2020-05-01 19:48:54 +0530898 this.svg.classed('ctrl', true);
899 }
900 }
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);
911 }
912 }
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');
916 }
917 /** Events handles when Shift Click to perform create cp @private */
918 // tslint:disable-next-line: no-any
Barath Kumar R063a3f12020-12-29 16:35:09 +0530919 private singleClick(nodeSelected: any, d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530920 this.selectedNode(nodeSelected, d);
921 }
922 /** Get confirmation Before Deleting the Node in Topology @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530923 private getDeleteNodeConfirmation(d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530924 const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' });
925 modalRef.componentInstance.topologyType = 'Delete';
926 modalRef.componentInstance.topologyname = d.name;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530927 if (d.type === 'vdu') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530928 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.VDU';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530929 } else if (d.type === 'intvl') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530930 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTVL';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530931 } else if (d.type === 'cp') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530932 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.CONNECTIONPOINT';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530933 } else if (d.type === 'intcp') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530934 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTCP';
935 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530936 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530937 if (result) {
938 this.deleteNode(d);
939 }
940 }).catch();
941 }
942 /** Delete nodes @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530943 private deleteNode(d: COMPOSERNODES): void {
944 // tslint:disable-next-line: max-func-body-length
945 this.nodes.forEach((node: VNFD): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530946 if (node.id === d.id) {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530947 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'];
kumaran.m3b4814a2020-05-01 19:48:54 +0530954 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530955 return true;
956 } else {
957 return false;
kumaran.m3b4814a2020-05-01 19:48:54 +0530958 }
959 });
Barath Kumar R063a3f12020-12-29 16:35:09 +0530960 if (posExtCPD !== -1) {
961 this.vnfdPackageDetails['ext-cpd'].splice(posExtCPD, 1);
kumaran.m3b4814a2020-05-01 19:48:54 +0530962 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530963 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;
968 });
969 if (posINTCPD !== -1) {
970 vdu['int-cpd'].splice(posINTCPD, 1);
971 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530972 }
973 });
974 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530975 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530976 } 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;
980 });
981 if (posINTCPD !== -1) {
982 vdu['int-cpd'].splice(posINTCPD, 1);
983 }
984 });
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;
988 });
989 if (posINTVLD !== -1) {
990 this.vnfdPackageDetails['int-virtual-link-desc'].splice(posINTVLD, 1);
991 }
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;
997 });
998 vduDetails['int-cpd'] = newVDUintCPDArray;
999 }
1000 });
1001 }
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);
1010 }
1011 });
1012 }
1013 return true;
1014 } else {
1015 return false;
1016 }
1017 });
1018 if (posVDU !== -1) {
1019 this.vnfdPackageDetails.vdu.splice(posVDU, 1);
1020 }
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) {
Barath Kumar R86e497d2021-05-04 17:16:14 +05301025 extCPD['int-cpd'] = {};
Barath Kumar R063a3f12020-12-29 16:35:09 +05301026 }
1027 }
1028 });
1029 });
kumaran.m3b4814a2020-05-01 19:48:54 +05301030 } else {
1031 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
1032 }
1033 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
1034 }
1035 });
1036 }
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'));
1040 }
1041 /** Selected nodes @private */
1042 // tslint:disable-next-line: no-any
Barath Kumar R063a3f12020-12-29 16:35:09 +05301043 private selectedNode(nodeSeleced: any, d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +05301044 const alreadyIsActive: boolean = nodeSeleced.select('#' + d.id).classed(this.activeNode);
1045 this.deselectAllNodes();
1046 nodeSeleced.select('#' + d.id).classed(this.activeNode, !alreadyIsActive);
Barath Kumar R063a3f12020-12-29 16:35:09 +05301047 if (d.type === 'vdu' && !alreadyIsActive) {
1048 this.vnfdPackageDetails.vdu.forEach((res: VDU): void => {
1049 if (res.id === d.id) {
kumaran.m3b4814a2020-05-01 19:48:54 +05301050 this.showRightSideInfo = 'vduInfo';
1051 this.vduInfo = res;
Barath Kumar R063a3f12020-12-29 16:35:09 +05301052 this.oldVDUID = res.id;
kumaran.m3b4814a2020-05-01 19:48:54 +05301053 }
1054 });
Barath Kumar R063a3f12020-12-29 16:35:09 +05301055 } 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) {
kumaran.m3b4814a2020-05-01 19:48:54 +05301059 this.showRightSideInfo = 'cpInfo';
Barath Kumar R063a3f12020-12-29 16:35:09 +05301060 this.cpInfo = cp;
1061 this.oldCPID = cp.id;
kumaran.m3b4814a2020-05-01 19:48:54 +05301062 }
1063 });
Barath Kumar R063a3f12020-12-29 16:35:09 +05301064 } 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;
1070 }
1071 });
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';
1080 });
1081 }
1082 }
1083 });
1084 });
kumaran.m3b4814a2020-05-01 19:48:54 +05301085 } else {
1086 this.showRightSideInfo = 'vnfdInfo';
1087 }
1088 }
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);
1095 }
Barath Kumar R063a3f12020-12-29 16:35:09 +05301096 /** Events handles when to drag using filter for the keys @private */
1097 private dragFilter(): boolean {
1098 return d3.event.ctrlKey && !d3.event.button;
1099 }
kumaran.m3b4814a2020-05-01 19:48:54 +05301100 /** Events handles when dragstarted @private */
1101 private dragstarted(d: COMPOSERNODES): void {
1102 d.fx = d.x;
1103 d.fy = d.y;
1104 }
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;
1109 }
1110 /** Events handles when dragended @private */
1111 private dragended(d: COMPOSERNODES): void {
1112 if (this.forceSimulationActive) {
1113 d.fx = null;
1114 d.fy = null;
1115 } else {
1116 d.fx = d.x;
1117 d.fy = d.y;
1118 this.forceSimulationActive = false;
1119 }
1120 }
1121 /** Events handles when node double click @private */
1122 private onNodedblClickToggleSidebar(): void {
1123 this.sideBarOpened = false;
1124 }
1125 /** Events handles when node single click @private */
1126 private onNodeClickToggleSidebar(): void {
1127 this.sideBarOpened = true;
1128 }
1129}