blob: 081874a581b1addce2c4953e2cff611db541ac55 [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({
179 'Content-Type': 'application/zip',
180 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 R063a3f12020-12-29 16:35:09 +0530269 id: cp['int-cpd'] !== undefined ? cp['int-cpd'].cpd : cp.id,
270 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 R063a3f12020-12-29 16:35:09 +0530646 if (this.vnfdPackageDetails.vdu === undefined) {
647 this.vnfdPackageDetails.vdu = [];
648 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530649 this.vnfdPackageDetails.vdu.push({
Barath Kumar R063a3f12020-12-29 16:35:09 +0530650 id: 'vdu_' + randomID,
651 name: 'vdu_' + randomID,
652 description: '',
653 'sw-image-desc': 'ubuntu',
654 'int-cpd': [],
655 'monitoring-parameter': [],
656 'virtual-compute-desc': '',
657 'virtual-storage-desc': []
kumaran.m3b4814a2020-05-01 19:48:54 +0530658 });
659 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
660 }
661 /** Drop CP Composer Data @private */
662 private cpDropCompose(): void {
663 const randomID: string = this.sharedService.randomString();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530664 if (this.vnfdPackageDetails['ext-cpd'] === undefined) {
665 this.vnfdPackageDetails['ext-cpd'] = [];
666 this.vnfdPackageDetails['mgmt-cp'] = 'cp_' + randomID;
kumaran.m3b4814a2020-05-01 19:48:54 +0530667 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530668 this.vnfdPackageDetails['ext-cpd'].push({
669 id: 'cp_' + randomID,
670 'int-cpd': {}
kumaran.m3b4814a2020-05-01 19:48:54 +0530671 });
672 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
673 }
674 /** Drop IntVL Composer Data @private */
675 private intvlDropCompose(): void {
676 const randomID: string = this.sharedService.randomString();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530677 if (this.vnfdPackageDetails['int-virtual-link-desc'] === undefined) {
678 this.vnfdPackageDetails['int-virtual-link-desc'] = [];
679 }
680 this.vnfdPackageDetails['int-virtual-link-desc'].push({
681 id: 'vnf_vl_' + randomID
kumaran.m3b4814a2020-05-01 19:48:54 +0530682 });
683 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
684 }
685 /** Add the Add Nodes Data @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530686 private addNodes(apiURL: string, identifier: string, data: VNFD): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530687 this.isLoadingResults = true;
688 const apiURLHeader: APIURLHEADER = {
689 url: apiURL + '/' + identifier + '/package_content',
690 httpOptions: { headers: this.headers }
691 };
Barath Kumar R063a3f12020-12-29 16:35:09 +0530692 const vnfData: VNFDATA = {};
693 vnfData.vnfd = data;
kumaran.m3b4814a2020-05-01 19:48:54 +0530694 const descriptorInfo: string = jsyaml.dump(vnfData, { sortKeys: true });
695 this.sharedService.targzFile({ packageType: 'vnfd', id: this.identifier, descriptor: descriptorInfo })
696 .then((content: ArrayBuffer): void => {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530697 this.restService.putResource(apiURLHeader, content).subscribe((res: {}): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530698 this.generateData();
699 this.notifierService.notify('success', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.UPDATEDSUCCESSFULLY'));
700 this.isLoadingResults = false;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530701 }, (error: ERRORDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530702 this.generateData();
703 this.restService.handleError(error, 'put');
704 this.isLoadingResults = false;
705 });
706 }).catch((): void => {
707 this.notifierService.notify('error', this.translateService.instant('ERROR'));
708 this.isLoadingResults = false;
709 });
710 }
711 /** Events handles when mousedown click it will capture the selected node data @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530712 private mouseDown(d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530713 event.preventDefault();
714 if (d3.event.ctrlKey) { return; }
715 if (d3.event.shiftKey) {
716 this.mousedownNode = d;
717 this.currentSelectedNode = (this.mousedownNode === this.currentSelectedNode) ? null : this.mousedownNode;
718 this.dragLine.classed('hidden', false)
719 .attr('d', `M${this.mousedownNode.x},${this.mousedownNode.y}L${this.mousedownNode.x},${this.mousedownNode.y}`);
720 }
721 }
722 /** Event handles when mouseup event occures @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530723 private mouseUp(d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530724 if (!this.mousedownNode) { return; }
725 this.dragLine.classed('hidden', true);
726 this.mouseupNode = d;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530727 if (this.mousedownNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530728 this.vduMouseDownNode();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530729 } else if (this.mousedownNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530730 this.cpMouseDownNode();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530731 } else if (this.mousedownNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530732 this.intVLMouseDownNode();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530733 } else if (this.mousedownNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530734 this.intCPMouseDownNode();
735 } else {
kumaran.m3b4814a2020-05-01 19:48:54 +0530736 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
737 this.deselectPath();
738 }
739 this.resetMouseActions();
740 this.currentSelectedNode = null;
741 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530742 /** Establish a connection point between vdu and other nodes @private */
743 private vduMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530744 if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530745 this.vduCPConnection(this.mousedownNode.id, this.mouseupNode.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530746 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530747 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDINTCP'));
748 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530749 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530750 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDVDU'));
751 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530752 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530753 this.vduIntvlConnection(this.mousedownNode.id, this.mouseupNode.id);
754 }
755 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530756 /** Establish a connection point between cp and other nodes @private */
757 private cpMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530758 if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530759 this.vduCPConnection(this.mouseupNode.id, this.mousedownNode.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530760 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530761 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDVNFVL'));
762 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530763 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530764 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDINTCP'));
765 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530766 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530767 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDCP'));
768 this.deselectPath();
769 }
770 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530771 /** Establish a connection piont between intvl and other nodes @private */
772 private intVLMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530773 if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530774 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDCP'));
775 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530776 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530777 this.vduIntvlConnection(this.mouseupNode.id, this.mousedownNode.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530778 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530779 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDVNFVL'));
780 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530781 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530782 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDONTCP'));
783 this.deselectPath();
784 }
785 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530786 /** Establish a connection point between intcp and other nodes @private */
787 private intCPMouseDownNode(): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530788 if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'vdu') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530789 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVDU'));
790 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530791 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'cp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530792 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDCP'));
793 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530794 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intvl') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530795 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVNFVL'));
796 this.deselectPath();
Barath Kumar R063a3f12020-12-29 16:35:09 +0530797 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intcp') {
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530798 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDINTCP'));
799 this.deselectPath();
800 }
801 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530802 /** Establish a connection between VDU & CP vice versa @private */
803 private vduCPConnection(nodeA: string, nodeB: string): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530804 const vduExternalID: string = nodeA + '-eth_' + this.sharedService.randomString();
805 if (this.vnfdPackageDetails.vdu !== undefined) {
806 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
807 const vduID: string = vdu.id;
808 if (vdu.id === nodeA) {
809 if (this.vnfdPackageDetails['ext-cpd'] !== undefined) {
810 this.vnfdPackageDetails['ext-cpd'].forEach((extcpd: EXTCPD, index: number): void => {
811 if (extcpd.id === nodeB) {
812 if (vdu['int-cpd'] === undefined) {
813 vdu['int-cpd'] = [];
814 }
815 if (extcpd['int-cpd'] === undefined) {
816 vdu['int-cpd'].push({
817 id: vduExternalID,
818 'virtual-network-interface-requirement': [
819 {
820 name: vduExternalID,
821 position: 1,
822 'virtual-interface': { type: 'PARAVIRT' }
823 }
824 ]
825 });
826 this.vnfdPackageDetails['ext-cpd'][index] = {
827 id: extcpd.id,
828 'int-cpd': {
829 cpd: vduExternalID,
830 'vdu-id': vduID
831 }
832 };
833 }
834 }
835 });
836 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530837 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530838 });
839 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530840 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
841 this.deselectPath();
842 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530843 /** Establish a connection between vdu & intvl and vice versa @private */
844 private vduIntvlConnection(nodeA: string, nodeB: string): void {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530845 const vduInternalID: string = nodeA + '-eth_' + this.sharedService.randomString();
846 if (this.vnfdPackageDetails.vdu !== undefined) {
847 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
848 if (vdu.id === nodeA) {
849 if (vdu['int-cpd'] === undefined) {
850 vdu['int-cpd'] = [];
851 }
852 vdu['int-cpd'].push({
853 id: vduInternalID,
854 'int-virtual-link-desc': nodeB,
855 'virtual-network-interface-requirement': [
856 {
857 name: vduInternalID,
858 position: 1,
859 'virtual-interface': { type: 'PARAVIRT' }
860 }
861 ]
862 });
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530863 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530864 });
865 }
Barath Kumar Rb323b2a2020-07-07 15:31:19 +0530866 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
867 this.deselectPath();
868 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530869 /** Events handles when mousemove it will capture the selected node data @private */
870 private mousemove(): void {
871 if (!this.mousedownNode) { return; }
872 this.dragLine.attr('d',
873 `M${this.mousedownNode.x},${this.mousedownNode.y}L${d3.mouse(d3.event.currentTarget)[0]},${d3.mouse(d3.event.currentTarget)[1]}`);
874 }
875 /** reset Mouse varaibles @private */
876 private resetMouseActions(): void {
877 this.mousedownNode = null;
878 this.mouseupNode = null;
879 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530880 /** drag event @private */
881 // tslint:disable-next-line: no-any
882 private onDragDrop(): any {
883 return d3.drag().filter(this.dragFilter)
884 .on('start', this.dragstarted)
885 .on('drag', this.dragged)
886 .on('end', this.dragended);
887 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530888 /** Key press event @private */
889 private keyDown(): void {
890 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
891 if (this.lastKeyDown !== -1) { return; }
892 this.lastKeyDown = d3.event.keyCode;
893 if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) {
kumaran.m3b4814a2020-05-01 19:48:54 +0530894 this.svg.classed('ctrl', true);
895 }
896 }
897 /** Key realse event @private */
898 private keyUp(): void {
899 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
900 this.lastKeyDown = -1;
901 if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) {
902 this.gNetwork.on('.drag', null);
903 this.gVirutualDeploymentUnit.on('.drag', null);
904 this.gConnectionPoint.on('.drag', null);
905 this.gIntConnectionPoint.on('.drag', null);
906 this.svg.classed('ctrl', false);
907 }
908 }
909 /** Mosue Drag Line false if it is not satisfied @private */
910 private deselectPath(): void {
911 this.dragLine.classed('hidden', true).attr('d', 'M0,0L0,0');
912 }
913 /** Events handles when Shift Click to perform create cp @private */
914 // tslint:disable-next-line: no-any
Barath Kumar R063a3f12020-12-29 16:35:09 +0530915 private singleClick(nodeSelected: any, d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530916 this.selectedNode(nodeSelected, d);
917 }
918 /** Get confirmation Before Deleting the Node in Topology @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530919 private getDeleteNodeConfirmation(d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530920 const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' });
921 modalRef.componentInstance.topologyType = 'Delete';
922 modalRef.componentInstance.topologyname = d.name;
Barath Kumar R063a3f12020-12-29 16:35:09 +0530923 if (d.type === 'vdu') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530924 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.VDU';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530925 } else if (d.type === 'intvl') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530926 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTVL';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530927 } else if (d.type === 'cp') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530928 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.CONNECTIONPOINT';
Barath Kumar R063a3f12020-12-29 16:35:09 +0530929 } else if (d.type === 'intcp') {
kumaran.m3b4814a2020-05-01 19:48:54 +0530930 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTCP';
931 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530932 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530933 if (result) {
934 this.deleteNode(d);
935 }
936 }).catch();
937 }
938 /** Delete nodes @private */
Barath Kumar R063a3f12020-12-29 16:35:09 +0530939 private deleteNode(d: COMPOSERNODES): void {
940 // tslint:disable-next-line: max-func-body-length
941 this.nodes.forEach((node: VNFD): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530942 if (node.id === d.id) {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530943 if (d.type === 'cp') {
944 if (this.vnfdPackageDetails['ext-cpd'] !== undefined) {
945 let getRelatedVDUCPD: string; let getRelatedVDUID: string;
946 const posExtCPD: number = this.vnfdPackageDetails['ext-cpd'].findIndex((e: EXTCPD): boolean => {
947 if (e.id === d.name) {
948 if (e['int-cpd'] !== undefined) {
949 getRelatedVDUCPD = e['int-cpd'].cpd; getRelatedVDUID = e['int-cpd']['vdu-id'];
kumaran.m3b4814a2020-05-01 19:48:54 +0530950 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530951 return true;
952 } else {
953 return false;
kumaran.m3b4814a2020-05-01 19:48:54 +0530954 }
955 });
Barath Kumar R063a3f12020-12-29 16:35:09 +0530956 if (posExtCPD !== -1) {
957 this.vnfdPackageDetails['ext-cpd'].splice(posExtCPD, 1);
kumaran.m3b4814a2020-05-01 19:48:54 +0530958 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530959 if (getRelatedVDUCPD !== undefined && getRelatedVDUID !== undefined) {
960 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
961 if (vdu.id === getRelatedVDUID) {
962 const posINTCPD: number = vdu['int-cpd'].findIndex((intCPD: VDUINTCPD): boolean => {
963 return intCPD.id === getRelatedVDUCPD;
964 });
965 if (posINTCPD !== -1) {
966 vdu['int-cpd'].splice(posINTCPD, 1);
967 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530968 }
969 });
970 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530971 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530972 } else if (d.type === 'intcp') {
973 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
974 const posINTCPD: number = vdu['int-cpd'].findIndex((intCPD: VDUINTCPD): boolean => {
975 return intCPD.id === d.id;
976 });
977 if (posINTCPD !== -1) {
978 vdu['int-cpd'].splice(posINTCPD, 1);
979 }
980 });
981 } else if (d.type === 'intvl') {
982 const posINTVLD: number = this.vnfdPackageDetails['int-virtual-link-desc'].findIndex((intVLD: IVLD): boolean => {
983 return intVLD.id === d.id;
984 });
985 if (posINTVLD !== -1) {
986 this.vnfdPackageDetails['int-virtual-link-desc'].splice(posINTVLD, 1);
987 }
988 if (this.vnfdPackageDetails.vdu !== undefined) {
989 this.vnfdPackageDetails.vdu.forEach((vduDetails: VDU): void => {
990 if (vduDetails['int-cpd'] !== undefined) {
991 const newVDUintCPDArray: VDUINTCPD[] = vduDetails['int-cpd'].filter((item: VDUINTCPD): boolean => {
992 return item['int-virtual-link-desc'] !== undefined ? item['int-virtual-link-desc'] !== d.id ? true : false : true;
993 });
994 vduDetails['int-cpd'] = newVDUintCPDArray;
995 }
996 });
997 }
998 } else if (d.type === 'vdu') {
999 const getRelatedExtCPD: string[] = [];
1000 const posVDU: number = this.vnfdPackageDetails.vdu.findIndex((vduDetails: VDU): boolean => {
1001 if (vduDetails.id === d.id) {
1002 if (vduDetails['int-cpd'] !== undefined) {
1003 vduDetails['int-cpd'].forEach((intCPDDetails: VDUINTCPD): void => {
1004 if (intCPDDetails['int-virtual-link-desc'] === undefined) {
1005 getRelatedExtCPD.push(intCPDDetails.id);
1006 }
1007 });
1008 }
1009 return true;
1010 } else {
1011 return false;
1012 }
1013 });
1014 if (posVDU !== -1) {
1015 this.vnfdPackageDetails.vdu.splice(posVDU, 1);
1016 }
1017 getRelatedExtCPD.forEach((CPDID: string, index: number): void => {
1018 this.vnfdPackageDetails['ext-cpd'].forEach((extCPD: EXTCPD): void => {
1019 if (extCPD['int-cpd'] !== undefined) {
1020 if (extCPD['int-cpd'].cpd === CPDID) {
1021 delete extCPD['int-cpd'];
1022 }
1023 }
1024 });
1025 });
kumaran.m3b4814a2020-05-01 19:48:54 +05301026 } else {
1027 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
1028 }
1029 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
1030 }
1031 });
1032 }
1033 /** Get confirmation before deleting the ink in Topology @private */
1034 private getDeleteLinkConfirmation(d: Tick): void {
1035 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.YOUCANNOTDELETELINK'));
1036 }
1037 /** Selected nodes @private */
1038 // tslint:disable-next-line: no-any
Barath Kumar R063a3f12020-12-29 16:35:09 +05301039 private selectedNode(nodeSeleced: any, d: COMPOSERNODES): void {
kumaran.m3b4814a2020-05-01 19:48:54 +05301040 const alreadyIsActive: boolean = nodeSeleced.select('#' + d.id).classed(this.activeNode);
1041 this.deselectAllNodes();
1042 nodeSeleced.select('#' + d.id).classed(this.activeNode, !alreadyIsActive);
Barath Kumar R063a3f12020-12-29 16:35:09 +05301043 if (d.type === 'vdu' && !alreadyIsActive) {
1044 this.vnfdPackageDetails.vdu.forEach((res: VDU): void => {
1045 if (res.id === d.id) {
kumaran.m3b4814a2020-05-01 19:48:54 +05301046 this.showRightSideInfo = 'vduInfo';
1047 this.vduInfo = res;
Barath Kumar R063a3f12020-12-29 16:35:09 +05301048 this.oldVDUID = res.id;
kumaran.m3b4814a2020-05-01 19:48:54 +05301049 }
1050 });
Barath Kumar R063a3f12020-12-29 16:35:09 +05301051 } else if (d.type === 'cp' && !alreadyIsActive) {
1052 this.vnfdPackageDetails['ext-cpd'].forEach((cp: EXTCPD): void => {
1053 const getCPDID: string = cp['int-cpd'] !== undefined ? cp['int-cpd'].cpd : cp.id;
1054 if (getCPDID === d.id) {
kumaran.m3b4814a2020-05-01 19:48:54 +05301055 this.showRightSideInfo = 'cpInfo';
Barath Kumar R063a3f12020-12-29 16:35:09 +05301056 this.cpInfo = cp;
1057 this.oldCPID = cp.id;
kumaran.m3b4814a2020-05-01 19:48:54 +05301058 }
1059 });
Barath Kumar R063a3f12020-12-29 16:35:09 +05301060 } else if (d.type === 'intvl' && !alreadyIsActive) {
1061 this.vnfdPackageDetails['int-virtual-link-desc'].forEach((ivld: IVLD): void => {
1062 if (ivld.id === d.id) {
1063 this.showRightSideInfo = 'intvlInfo';
1064 this.intvlInfo = ivld;
1065 this.oldintVLID = ivld.id;
1066 }
1067 });
1068 } else if (d.type === 'intcp' && !alreadyIsActive) {
1069 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
1070 vdu['int-cpd'].forEach((intcpd: VDUINTCPD): void => {
1071 if (intcpd.id === d.id) {
1072 if (intcpd['int-virtual-link-desc'] !== undefined) {
1073 intcpd['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
1074 this.intcpInfo = vnir;
1075 this.showRightSideInfo = 'intcpInfo';
1076 });
1077 }
1078 }
1079 });
1080 });
kumaran.m3b4814a2020-05-01 19:48:54 +05301081 } else {
1082 this.showRightSideInfo = 'vnfdInfo';
1083 }
1084 }
1085 /** De-select all the selected nodes @private */
1086 private deselectAllNodes(): void {
1087 this.network.select('image').classed(this.activeNode, false);
1088 this.virutualDeploymentUnit.select('image').classed(this.activeNode, false);
1089 this.connectionPoint.select('image').classed(this.activeNode, false);
1090 this.intConnectionPoint.select('image').classed(this.activeNode, false);
1091 }
Barath Kumar R063a3f12020-12-29 16:35:09 +05301092 /** Events handles when to drag using filter for the keys @private */
1093 private dragFilter(): boolean {
1094 return d3.event.ctrlKey && !d3.event.button;
1095 }
kumaran.m3b4814a2020-05-01 19:48:54 +05301096 /** Events handles when dragstarted @private */
1097 private dragstarted(d: COMPOSERNODES): void {
1098 d.fx = d.x;
1099 d.fy = d.y;
1100 }
1101 /** Events handles when dragged @private */
1102 private dragged(d: COMPOSERNODES): void {
1103 d.fx = d.x = d3.event.x;
1104 d.fy = d.y = d3.event.y;
1105 }
1106 /** Events handles when dragended @private */
1107 private dragended(d: COMPOSERNODES): void {
1108 if (this.forceSimulationActive) {
1109 d.fx = null;
1110 d.fy = null;
1111 } else {
1112 d.fx = d.x;
1113 d.fy = d.y;
1114 this.forceSimulationActive = false;
1115 }
1116 }
1117 /** Events handles when node double click @private */
1118 private onNodedblClickToggleSidebar(): void {
1119 this.sideBarOpened = false;
1120 }
1121 /** Events handles when node single click @private */
1122 private onNodeClickToggleSidebar(): void {
1123 this.sideBarOpened = true;
1124 }
1125}