X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=src%2Fapp%2Fpackages%2Fns-packages%2Fns-composer%2FNSComposerComponent.ts;h=7ef839432bae0db5b106885f3e70da538da04cfa;hb=43dec1560d59d84cbc5d9290549ac987f1c285ce;hp=687f4fa9eb3137344a255d9aeb4d029fe2345a0d;hpb=218e881e8d5a5d01c41a255d7107d546d10c0329;p=osm%2FNG-UI.git diff --git a/src/app/packages/ns-packages/ns-composer/NSComposerComponent.ts b/src/app/packages/ns-packages/ns-composer/NSComposerComponent.ts index 687f4fa..7ef8394 100644 --- a/src/app/packages/ns-packages/ns-composer/NSComposerComponent.ts +++ b/src/app/packages/ns-packages/ns-composer/NSComposerComponent.ts @@ -18,7 +18,6 @@ /** * @file NS Compose Component */ -// tslint:disable: no-increment-decrement import { HttpHeaders } from '@angular/common/http'; import { Component, ElementRef, Injector, ViewChild, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; @@ -32,11 +31,20 @@ import { DataService } from 'DataService'; import { environment } from 'environment'; import * as HttpStatus from 'http-status-codes'; import * as jsyaml from 'js-yaml'; -import { COMPOSERNODES, CONSTITUENTVNFD, GRAPHDETAILS, NSDDetails, Tick, TickPath, VLD, VNFDCONNECTIONPOINTREF } from 'NSDModel'; +import { + CCI, + COMPOSERNODES, + DF, + GRAPHDETAILS, + NSData, + NSDATACREATION, + NSDDetails, + Tick, TickPath, VLC, VLD, VNFPROFILE +} from 'NSDModel'; import { RestService } from 'RestService'; import { SharedService } from 'SharedService'; import { isNullOrUndefined } from 'util'; -import { VNFData, VNFDDetails } from 'VNFDModel'; +import { VNFD, VNFData } from 'VNFDModel'; /** * Creating component @@ -57,14 +65,11 @@ export class NSComposerComponent { /** dataService to pass the data from one component to another @public */ public dataService: DataService; /** Contains VNFD Informations @public */ - public vnfdPackageDetails: VNFData = { identifier: '', shortName: '', vendor: '', description: '', version: '', id: '', name: '' }; + public nsPackageDetails: NSData = { id: '', name: '', description: '', version: '', designer: '' }; /** Contains VL Details @public */ - public vlDetails: VLD = { - name: '', - 'mgmt-network': true, - 'vim-network-name': '', - type: '', - id: '' + public virtualLinkDesc: VLD = { + id: '', + 'mgmt-network': true }; /** Contains the information of the type of modification @public */ public putType: string; @@ -87,19 +92,21 @@ export class NSComposerComponent { /** Contains the node information of VNF @public */ public vnfNodes: {}[] = []; /** contains the VNF Details @public */ - public vnfData: CONSTITUENTVNFD; + public vnfData: VNFPROFILE; + /** contains the Virtual Link connectivity Details @public */ + public virtualLinkProfileID: string; /** Need to show the VNF Details @public */ public isShowVNFDetails: boolean = false; /** Contains the node information of CP @public */ public cpNodes: {}[] = []; /** Need to show the CP Details */ - public cpData: VNFDCONNECTIONPOINTREF; + public cpData: CCI; /** Need to show the VNF Details @public */ public isShowCPDetails: boolean = false; /** random number count @public */ public randomNumberLength: number; /** Contains the vnfd information @public */ - public vnfList: VNFDDetails[] = []; + public vnfList: VNFD[] = []; /** Add the activeclass for the selected @public */ public activeClass: string = 'active'; /** Add the fixed class for the freeze @public */ @@ -109,7 +116,7 @@ export class NSComposerComponent { /** Give the message for the loading @public */ public message: string = 'PLEASEWAIT'; /** Get VNF selected node @public */ - public getVNFSelectedData: VNFDDetails[]; + public getVNFSelectedData: VNFD; /** Assign the forcesimulation active @public */ public forceSimulationActive: boolean = false; /** Assign pinned class for the button when freezed @public */ @@ -145,26 +152,14 @@ export class NSComposerComponent { private force: any; /** Contains all the selected node @private */ private selectedNode: COMPOSERNODES[] = []; - /** variables used for CP @private */ - private iConnectionPointRef: number = 0; /** Contains the connected point @private */ private connectionPoint: string; - /** Contains all the NSD information @private */ - private nsd: string; - /** Contains all the VNFD information @private */ - private vnfd: string; /** Contains id of the node @private */ private identifier: string; - /** Variables used for cp @private */ - private jConnectionPointRef: number = 0; /** Contains copy of NSD information @private */ private nsdCopy: string; /** Contains the VNFD copy @private */ private vnfdCopy: string; - /** Contains name of the node @private */ - private name: string; - /** Contains member vnf index value of the node @private */ - private memberVnfIndexValue: number = 0; /** Contains path information of the node */ // tslint:disable-next-line:no-any private path: any; @@ -198,8 +193,8 @@ export class NSComposerComponent { private setVnfdName: string; /** Contains all methods related to shared @private */ private sharedService: SharedService; - /** Contains selected node VLD objects @private */ - private selectedVLDResult: VLD; + /** Contains selected node VNF profile objects @private */ + private selectedVNFProfile: VNFPROFILE[]; constructor(injector: Injector) { this.injector = injector; @@ -234,106 +229,107 @@ export class NSComposerComponent { } /** On clicking redirect to NS edit page @public */ public onEdit(): void { - this.router.navigate(['/packages/ns/edit/', this.identifier]).catch(() => { + this.router.navigate(['/packages/ns/edit/', this.identifier]).catch((): void => { // Catch Navigation Error }); } /** Events handles drop at D3 region @public */ public drop(ev: DragEvent): void { - event.preventDefault(); - this.name = ev.dataTransfer.getData('text'); - if (this.name === 'vl') { + ev.preventDefault(); + const getDropedName: string = ev.dataTransfer.getData('text'); + if (getDropedName === 'vl') { this.svg.selectAll('*').remove(); this.vldropComposer(); } else { this.svg.selectAll('*').remove(); - this.vnfd = ev.dataTransfer.getData('text'); - this.vnfdropComposer(); + const vnfdName: string = ev.dataTransfer.getData('text'); + this.vnfdropComposer(vnfdName); } } /** Drop VL Composer Data @public */ public vldropComposer(): void { this.randomNumberLength = CONSTANTNUMBER.randomNumber; - const generateId: string = 'ns_vl_' + this.randomString( - this.randomNumberLength, - '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - ); - if (this.nsData.vld !== undefined) { - this.nsData.vld.push({ - 'vim-network-name': 'PUBLIC', - name: generateId, - 'mgmt-network': true, - type: 'ELAN', - id: generateId - }); - } else { - Object.assign(this.nsData, { - vld: [{ - 'vim-network-name': 'PUBLIC', - name: generateId, - 'mgmt-network': true, - type: 'ELAN', - id: generateId - }] - }); + const generateId: string = 'ns_vl_' + this.sharedService.randomString(); + if (this.nsData['virtual-link-desc'] === undefined) { + this.nsData['virtual-link-desc'] = []; } + this.nsData['virtual-link-desc'].push({ + id: generateId, + 'mgmt-network': false + }); this.putType = 'nsdadd'; this.addData(environment.NSDESCRIPTORS_URL, this.identifier, this.nsData, this.putType); } /** Drop VNFD Composer Data @public */ - public vnfdropComposer(): void { - if (this.nsData['constituent-vnfd'] !== undefined) { - this.nsData['constituent-vnfd'].push({ - 'vnfd-id-ref': this.vnfd, - 'member-vnf-index': ++this.memberVnfIndexValue + public vnfdropComposer(vnfdName: string): void { + const vnfID: string = 'ns_vnfd_' + this.sharedService.randomString(); + if (this.nsData.df.length > 0) { + this.addVNFDID(vnfdName); + this.nsData.df.forEach((res: DF): void => { + if (res['vnf-profile'] === undefined) { + res['vnf-profile'] = []; + } + res['vnf-profile'].push({ + id: vnfID, + 'virtual-link-connectivity': [], + 'vnfd-id': vnfdName + }); }); } else { - Object.assign(this.nsData, { - 'constituent-vnfd': [{ - 'vnfd-id-ref': this.vnfd, - 'member-vnf-index': ++this.memberVnfIndexValue + Object.assign(this.nsData.df, { + id: 'default-df', + 'vnf-profile': [{ + id: vnfID, + 'virtual-link-connectivity': [], + 'vnfd-id': vnfdName }] }); } this.putType = 'vnfdadd'; this.addData(environment.NSDESCRIPTORS_URL, this.identifier, this.nsData, this.putType); } + /** Add the VNFD-ID while drop VNFD if not exists @public */ + public addVNFDID(vnfdName: string): void { + const vnfdIDArray: string[] = this.nsData['vnfd-id']; + if (vnfdIDArray !== undefined) { + if (vnfdIDArray.indexOf(vnfdName) === -1) { + vnfdIDArray.push(vnfdName); + } + } else { + Object.assign(this.nsData, { + 'vnfd-id': [vnfdName] + }); + } + } /** Events handles allow drop on D3 region @public */ public allowDrop(ev: DragEvent): void { ev.preventDefault(); } /** Save NSD Information @public */ public saveNSD(): void { - if (this.vnfdPackageDetails.shortName !== undefined) { - this.nsData['short-name'] = this.vnfdPackageDetails.shortName; - } - if (this.vnfdPackageDetails.vendor !== undefined) { - this.nsData.vendor = this.vnfdPackageDetails.vendor; + if (this.nsPackageDetails.id !== undefined) { + this.nsData.id = this.nsPackageDetails.id; } - if (this.vnfdPackageDetails.description !== undefined) { - this.nsData.description = this.vnfdPackageDetails.description; + if (this.nsPackageDetails.name !== undefined) { + this.nsData.name = this.nsPackageDetails.name; } - if (this.vnfdPackageDetails.version !== undefined) { - this.nsData.version = this.vnfdPackageDetails.version; + if (this.nsPackageDetails.description !== undefined) { + this.nsData.description = this.nsPackageDetails.description; } - if (this.vnfdPackageDetails.id !== undefined) { - this.nsData.id = this.vnfdPackageDetails.id; + if (this.nsPackageDetails.version !== undefined) { + this.nsData.version = this.nsPackageDetails.version; } - if (this.vnfdPackageDetails.name !== undefined) { - this.nsData.name = this.vnfdPackageDetails.name; + if (this.nsPackageDetails.designer !== undefined) { + this.nsData.designer = this.nsPackageDetails.designer; } this.putType = 'nsdUpdate'; this.addData(environment.NSDESCRIPTORS_URL, this.identifier, this.nsData, this.putType); } /** Save Virtual Link @public */ public saveVL(vlid: string): void { - this.nsData.vld.forEach((result: VLD) => { + this.nsData['virtual-link-desc'].forEach((result: VLD): void => { if (result.id === vlid) { - result.name = this.vlDetails.name; - result['mgmt-network'] = !isNullOrUndefined(this.vlDetails['mgmt-network']) ? this.vlDetails['mgmt-network'] : true; - result['vim-network-name'] = !isNullOrUndefined(this.vlDetails['vim-network-name']) ? this.vlDetails['vim-network-name'] : ''; - result.type = this.vlDetails.type; - result.id = this.vlDetails.id; + result['mgmt-network'] = !isNullOrUndefined(this.virtualLinkDesc['mgmt-network']) ? this.virtualLinkDesc['mgmt-network'] : true; } }); this.putType = 'vlUpdate'; @@ -367,18 +363,17 @@ export class NSComposerComponent { url: apiURL + '/' + identifier + '/nsd_content', httpOptions: { headers: this.headers } }; - const nsData: {} = {}; - nsData['nsd:nsd-catalog'] = {}; - nsData['nsd:nsd-catalog'].nsd = []; - nsData['nsd:nsd-catalog'].nsd.push(data); - const descriptorInfo: string = jsyaml.dump(nsData, {sortKeys: true}); + const nsData: NSDATACREATION = { nsd: { nsd: [] } }; + nsData.nsd.nsd = []; + nsData.nsd.nsd.push(data); + const descriptorInfo: string = jsyaml.dump(nsData, { sortKeys: true }); this.sharedService.targzFile({ packageType: 'nsd', id: this.identifier, descriptor: descriptorInfo }) .then((content: ArrayBuffer): void => { - this.restService.putResource(apiURLHeader, content).subscribe((res: {}) => { + this.restService.putResource(apiURLHeader, content).subscribe((res: {}): void => { this.generateData(); this.notifierService.notify('success', this.translateService.instant(successMessage)); this.isLoadingResults = false; - }, (error: ERRORDATA) => { + }, (error: ERRORDATA): void => { this.generateData(); this.restService.handleError(error, 'put'); this.isLoadingResults = false; @@ -393,7 +388,7 @@ export class NSComposerComponent { const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' }); modalRef.componentInstance.topologyType = 'Info'; modalRef.componentInstance.topologytitle = this.translateService.instant('PAGE.TOPOLOGY.INFO'); - modalRef.result.then((result: MODALCLOSERESPONSEDATA) => { + modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => { if (result) { // empty } @@ -408,7 +403,7 @@ export class NSComposerComponent { this.force.stop(); } this.forceSimulationActive = alreadyFixedIsActive; - this.nodes.forEach((d: COMPOSERNODES) => { + this.nodes.forEach((d: COMPOSERNODES): void => { d.fx = (alreadyFixedIsActive) ? null : d.x; d.fy = (alreadyFixedIsActive) ? null : d.y; }); @@ -430,9 +425,9 @@ export class NSComposerComponent { } /** Prepare the information of the VNFD @private */ private generateVNFData(): void { - this.restService.getResource(environment.VNFPACKAGESCONTENT_URL).subscribe((vnfdPackageData: VNFDDetails[]) => { + this.restService.getResource(environment.VNFPACKAGESCONTENT_URL).subscribe((vnfdPackageData: VNFD[]): void => { this.vnfList = vnfdPackageData; - }, (error: ERRORDATA) => { + }, (error: ERRORDATA): void => { this.restService.handleError(error, 'get'); }); } @@ -440,32 +435,29 @@ export class NSComposerComponent { private generateDataNSDTopology(): void { this.nodes = []; this.links = []; - this.iConnectionPointRef = 0; - this.jConnectionPointRef = 0; - this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL + '/' + this.identifier).subscribe((nsData: NSDDetails) => { + this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL + '/' + this.identifier).subscribe((nsData: NSDDetails): void => { delete nsData._admin; delete nsData._id; delete nsData._links; this.nsData = nsData; - this.vnfdPackageDetails.shortName = nsData['short-name']; - this.vnfdPackageDetails.vendor = nsData.vendor; - this.vnfdPackageDetails.description = nsData.description; - this.vnfdPackageDetails.version = nsData.version; - this.vnfdPackageDetails.id = nsData.id; - this.vnfdPackageDetails.name = nsData.name; - if (nsData.vld !== undefined) { + this.generateNSInfo(nsData); + if (nsData['virtual-link-desc'] !== undefined) { /** Details of the VL */ this.nsDataVLD(nsData); } - if (nsData['constituent-vnfd'] !== undefined) { - /** Details of the VNFD */ - this.nsDataConstituentVNFD(nsData); + if (this.nsData.df.length > 0) { + this.nsData.df.forEach((res: DF): void => { + if (res['vnf-profile'] !== undefined) { + /** Details of the VNFD */ + this.nsDataConstituentVNFD(nsData); + } + }); } - if (nsData.vld !== undefined) { + if (nsData.df.length > 0) { this.nsDataVLDLinkCreation(nsData); } this.separateAndCreatenode(); - }, (error: ERRORDATA) => { + }, (error: ERRORDATA): void => { if (error.error.status === HttpStatus.NOT_FOUND || error.error.status === HttpStatus.UNAUTHORIZED) { this.router.navigateByUrl('404', { skipLocationChange: true }).catch(); } else { @@ -475,78 +467,88 @@ export class NSComposerComponent { this.isShowNSDDetails = false; }); } - /** nsData-vld undefined Call this function @private */ + /** Generate the NS Package Information */ + private generateNSInfo(nsData: NSDDetails): void { + this.nsPackageDetails.id = nsData.id; + this.nsPackageDetails.name = nsData.name; + this.nsPackageDetails.description = nsData.description; + this.nsPackageDetails.version = nsData.version; + this.nsPackageDetails.designer = nsData.designer; + } + /** nsData VL node creation function @private */ private nsDataVLD(nsData: NSDDetails): void { - nsData.vld.forEach((res: VLD) => { + nsData['virtual-link-desc'].forEach((res: VLD): void => { this.nodes.push({ id: res.id, reflexive: false, type: 'vld', name: res.id, selectorId: res.id }); - this.nsd = res.id; - if (res['vnfd-connection-point-ref'] !== undefined) { - res['vnfd-connection-point-ref'].forEach((result: VNFDCONNECTIONPOINTREF) => { - this.nodes.push( - { - id: this.nsd + ++this.iConnectionPointRef + ':' + result['vnfd-connection-point-ref'], - reflexive: false, - type: 'ns', - name: result['vnfd-connection-point-ref'], - nodeIndex: result['member-vnf-index-ref'], - selectorId: result['vnfd-connection-point-ref'] + '_' + result['member-vnf-index-ref'] + '-osm-' + this.nsd - }); - }); - } }); } - /** nsData constituent-vnfd undefined Call this function @private */ + /** nsData VNFD node creation function @private */ private nsDataConstituentVNFD(nsData: NSDDetails): void { - nsData['constituent-vnfd'].forEach((res: CONSTITUENTVNFD) => { - this.nodes.push( - { - id: res['vnfd-id-ref'] + ':' + res['member-vnf-index'], - reflexive: false, - type: 'vnfd', - name: res['vnfd-id-ref'], - nodeIndex: res['member-vnf-index'], - selectorId: res['vnfd-id-ref'] + '_' + res['member-vnf-index'] - }); - this.vnfd = res['vnfd-id-ref']; - this.memberVnfIndexValue = res['member-vnf-index']; + nsData.df.forEach((resDF: DF): void => { + resDF['vnf-profile'].forEach((resVNF: VNFPROFILE): void => { + this.nodes.push( + { + id: resVNF['vnfd-id'] + ':' + resVNF.id, + reflexive: false, + type: 'vnfd', + name: resVNF['vnfd-id'], + nodeIndex: resVNF.id, + selectorId: resVNF['vnfd-id'] + '_' + resVNF.id + }); + if (resVNF['virtual-link-connectivity'] !== undefined) { + this.nsDataCP(resVNF, resVNF.id); + } + }); }); } - - /** nsData-vld undefined Call this function @private */ - private nsDataVLDLinkCreation(nsData: NSDDetails): void { - nsData.vld.forEach((res: VLD) => { - this.nsdCopy = res.id; - if (res['vnfd-connection-point-ref'] !== undefined) { - this.nsDataVNFDConnectionPointRefrence(res); - } + /** nsData CP node creation function @private */ + private nsDataCP(resVNF: VNFPROFILE, vnfID: string): void { + resVNF['virtual-link-connectivity'].forEach((resultVLC: VLC, index: number): void => { + resultVLC['constituent-cpd-id'].forEach((resultCCI: CCI): void => { + this.nodes.push( + { + id: vnfID + ':' + resultCCI['constituent-base-element-id'] + index + ':' + resultCCI['constituent-cpd-id'], + reflexive: false, + type: 'ns', + name: resultCCI['constituent-cpd-id'], + nodeIndex: resultCCI['constituent-base-element-id'], + selectorId: 'osm-' + resultCCI['constituent-cpd-id'] + '-' + vnfID + resultCCI['constituent-base-element-id'] + index + }); + }); }); } - /** nsData-vnfd-connection-point-ref undefined Call this function @private */ - private nsDataVNFDConnectionPointRefrence(res: VLD): void { - res['vnfd-connection-point-ref'].forEach((result: VNFDCONNECTIONPOINTREF) => { - this.connectionPoint = this.nsdCopy + ++this.jConnectionPointRef + ':' + result['vnfd-connection-point-ref']; - this.vnfdCopy = result['vnfd-id-ref'] + ':' + result['member-vnf-index-ref']; - const connectionPointPos: number = this.nodes.map((e: COMPOSERNODES) => { return e.id; }).indexOf(this.connectionPoint); - const nsdPos: number = this.nodes.map((e: COMPOSERNODES) => { return e.id; }).indexOf(this.nsdCopy); - const vnfdPos: number = this.nodes.map((e: COMPOSERNODES) => { return e.id; }).indexOf(this.vnfdCopy); - this.links.push( - { - source: this.nodes[connectionPointPos], - target: this.nodes[nsdPos] - }, - { - source: this.nodes[connectionPointPos], - target: this.nodes[vnfdPos] + /** nsData Link node creation function @private */ + private nsDataVLDLinkCreation(nsData: NSDDetails): void { + nsData.df.forEach((resDF: DF): void => { + if (resDF['vnf-profile'] !== undefined) { + resDF['vnf-profile'].forEach((resVNF: VNFPROFILE): void => { + this.nsdCopy = resVNF['vnfd-id'] + ':' + resVNF.id; + if (resVNF['virtual-link-connectivity'] !== undefined) { + this.nsDataVNFDConnectionPointRefrence(resVNF); + } }); + } }); } - /** Generate random string @private */ - private randomString(length: number, chars: string): string { - let result: string = ''; - for (let randomStringRef: number = length; randomStringRef > 0; --randomStringRef) { - result += chars[Math.floor(Math.random() * chars.length)]; - } - return result; + /** nsDataVNFDConnectionPointRefrence undefined Call this function @private */ + private nsDataVNFDConnectionPointRefrence(resVNF: VNFPROFILE): void { + resVNF['virtual-link-connectivity'].forEach((resultVLC: VLC, index: number): void => { + resultVLC['constituent-cpd-id'].forEach((resultCCI: CCI): void => { + this.vnfdCopy = resultVLC['virtual-link-profile-id']; + this.connectionPoint = resVNF.id + ':' + resultCCI['constituent-base-element-id'] + index + ':' + resultCCI['constituent-cpd-id']; + const connectionPointPos: number = this.nodes.map((e: COMPOSERNODES): string => { return e.id; }).indexOf(this.connectionPoint); + const nsdPos: number = this.nodes.map((e: COMPOSERNODES): string => { return e.id; }).indexOf(this.nsdCopy); + const vnfdPos: number = this.nodes.map((e: COMPOSERNODES): string => { return e.id; }).indexOf(this.vnfdCopy); + this.links.push( + { + source: this.nodes[connectionPointPos], + target: this.nodes[nsdPos] + }, + { + source: this.nodes[connectionPointPos], + target: this.nodes[vnfdPos] + }); + }); + }); } /** Separate and create node @private */ private separateAndCreatenode(): void { @@ -581,7 +583,7 @@ export class NSComposerComponent { /** Separate the nodes along with its tyep @private */ private seprateNodes(node: COMPOSERNODES[]): void { this.vlNodes = []; this.vnfNodes = []; this.cpNodes = []; - node.forEach((nodeList: COMPOSERNODES) => { + node.forEach((nodeList: COMPOSERNODES): void => { if (nodeList.type === 'vld') { this.vlNodes.push(nodeList); } else if (nodeList.type === 'vnfd') { @@ -595,21 +597,20 @@ export class NSComposerComponent { private createnode(node: COMPOSERNODES[]): void { const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr(); d3.selectAll('svg#graphContainer > *').remove(); - d3.select(window).on('keydown', () => { this.keyDown(); }); - d3.select(window).on('keyup', () => { this.keyUp(); }); + d3.select(window).on('keydown', (): void => { this.keyDown(); }); + d3.select(window).on('keyup', (): void => { this.keyUp(); }); this.svg = d3.select('#graphContainer') .attr('oncontextmenu', 'return false;') - .attr('width', graphContainerAttr.width) - .attr('height', graphContainerAttr.height) - .on('mousemove', () => { this.mousemove(); }); + .attr('viewBox', `0 0 ${graphContainerAttr.width} ${graphContainerAttr.height}`) + .on('mousemove', (): void => { this.mousemove(); }); this.force = d3.forceSimulation() .force('charge', d3.forceManyBody().strength(graphContainerAttr.strength)) - .force('link', d3.forceLink().id((d: TickPath) => d.id).distance(graphContainerAttr.distance)) + .force('link', d3.forceLink().id((d: TickPath): string => d.id).distance(graphContainerAttr.distance)) .force('center', d3.forceCenter(graphContainerAttr.width / graphContainerAttr.forcex, graphContainerAttr.height / graphContainerAttr.forcey)) .force('x', d3.forceX(graphContainerAttr.width / graphContainerAttr.forcex)) .force('y', d3.forceY(graphContainerAttr.height / graphContainerAttr.forcey)) - .on('tick', () => { this.tick(); }); + .on('tick', (): void => { this.tick(); }); this.dragLine = this.svg.append('svg:path').attr('class', 'link dragline hidden').attr('d', 'M0,0L0,0'); this.path = this.svg.append('svg:g').selectAll('path'); this.vlNode = this.svg.append('svg:g').selectAll('vlnode'); @@ -622,7 +623,7 @@ export class NSComposerComponent { private tick(): void { const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr(); // draw directed edges with proper padding from node centers - this.path.attr('class', 'link').attr('d', (d: Tick) => { + this.path.attr('class', 'link').attr('d', (d: Tick): string => { const deltaX: number = d.target.x - d.source.x; const deltaY: number = d.target.y - d.source.y; const dist: number = Math.sqrt(deltaX * deltaX + deltaY * deltaY); @@ -635,18 +636,18 @@ export class NSComposerComponent { const targetX: number = d.target.x - (targetPadding * normX); const targetY: number = d.target.y - (targetPadding * normY); return `M${sourceX},${sourceY}L${targetX},${targetY}`; - }).on('dblclick', (d: Tick) => { this.getDeleteLinkConfirmation(d); }); - this.vlNode.attr('transform', (t: TickPath) => `translate(${t.x},${t.y})`); - this.vnfdnode.attr('transform', (t: TickPath) => `translate(${t.x},${t.y})`); - this.cpnode.attr('transform', (t: TickPath) => `translate(${t.x},${t.y})`); + }).on('dblclick', (d: Tick): void => { this.getDeleteLinkConfirmation(d); }); + this.vlNode.attr('transform', (t: TickPath): string => `translate(${t.x},${t.y})`); + this.vnfdnode.attr('transform', (t: TickPath): string => `translate(${t.x},${t.y})`); + this.cpnode.attr('transform', (t: TickPath): string => `translate(${t.x},${t.y})`); } /** Update graph (called when needed) at D3 region @private */ private restart(node: COMPOSERNODES[]): void { const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr(); this.path = this.path.data(this.links); - this.vlNode = this.vlNode.data(this.vlNodes, (d: COMPOSERNODES) => d.id); - this.vnfdnode = this.vnfdnode.data(this.vnfNodes, (d: COMPOSERNODES) => d.id); - this.cpnode = this.cpnode.data(this.cpNodes, (d: COMPOSERNODES) => d.id); + this.vlNode = this.vlNode.data(this.vlNodes, (d: COMPOSERNODES): string => d.id); + this.vnfdnode = this.vnfdnode.data(this.vnfNodes, (d: COMPOSERNODES): string => d.id); + this.cpnode = this.cpnode.data(this.cpNodes, (d: COMPOSERNODES): string => d.id); this.resetAndCreateNodes(); this.force.nodes(node).force('link').links(this.links); this.force.alphaTarget(graphContainerAttr.alphaTarget).restart(); @@ -679,17 +680,18 @@ export class NSComposerComponent { .style('opacity', 1) .attr('x', graphContainerAttr.imageX) .attr('y', graphContainerAttr.imageY) - .attr('id', (d: COMPOSERNODES) => { return d.selectorId; }) + .call(this.onDragDrop()) + .attr('id', (d: COMPOSERNODES): string => { return d.selectorId; }) .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight) .attr('xlink:href', 'assets/images/VL.svg') - .on('mousedown', (d: COMPOSERNODES) => { this.mouseDown(d); }) - .on('mouseup', (d: COMPOSERNODES) => { this.mouseUp(d); }) - .on('click', (d: COMPOSERNODES) => { this.singleClick(this.vlNode, d); this.onNodeClickToggleSidebar(); }) - .on('dblclick', (d: COMPOSERNODES) => { this.getDeleteConfirmation(d); this.onNodedblClickToggleSidebar(); }); + .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); }) + .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); }) + .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.vlNode, d); this.onNodeClickToggleSidebar(); }) + .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteConfirmation(d); this.onNodedblClickToggleSidebar(); }); this.gvlNode.append('svg:text') .attr('class', 'node_text') .attr('y', graphContainerAttr.textY) - .text((d: COMPOSERNODES) => d.id); + .text((d: COMPOSERNODES): string => d.id); } /** Setting all the VNFD nodes @private */ private getVNFDNodes(): void { @@ -700,17 +702,18 @@ export class NSComposerComponent { .style('opacity', 1) .attr('x', graphContainerAttr.imageX) .attr('y', graphContainerAttr.imageY) - .attr('id', (d: COMPOSERNODES) => { return d.selectorId; }) + .call(this.onDragDrop()) + .attr('id', (d: COMPOSERNODES): string => { return d.selectorId; }) .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight) .attr('xlink:href', 'assets/images/VNFD.svg') - .on('mousedown', (d: COMPOSERNODES) => { this.mouseDown(d); }) - .on('mouseup', (d: COMPOSERNODES) => { this.mouseUp(d); }) - .on('click', (d: COMPOSERNODES) => { this.singleClick(this.vnfdnode, d); this.onNodeClickToggleSidebar(); }) - .on('dblclick', (d: COMPOSERNODES) => { this.getDeleteConfirmation(d); this.onNodedblClickToggleSidebar(); }); + .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); }) + .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); }) + .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.vnfdnode, d); this.onNodeClickToggleSidebar(); }) + .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteConfirmation(d); this.onNodedblClickToggleSidebar(); }); this.gvnfdNode.append('svg:text') .attr('class', 'node_text') .attr('y', graphContainerAttr.textY) - .text((d: COMPOSERNODES) => d.id); + .text((d: COMPOSERNODES): string => d.name); } /** Setting all the CP nodes @private */ private getCPNodes(): void { @@ -721,17 +724,18 @@ export class NSComposerComponent { .style('opacity', 1) .attr('x', graphContainerAttr.imageX) .attr('y', graphContainerAttr.imageY) - .attr('id', (d: COMPOSERNODES) => { return d.selectorId; }) + .call(this.onDragDrop()) + .attr('id', (d: COMPOSERNODES): string => { return d.selectorId; }) .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight) .attr('xlink:href', 'assets/images/CP.svg') - .on('mousedown', (d: COMPOSERNODES) => { this.mouseDown(d); }) - .on('mouseup', (d: COMPOSERNODES) => { this.mouseUp(d); }) - .on('click', (d: COMPOSERNODES) => { this.singleClick(this.cpnode, d); this.onNodeClickToggleSidebar(); }) - .on('dblclick', (d: COMPOSERNODES) => { this.getDeleteConfirmation(d); this.onNodedblClickToggleSidebar(); }); + .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); }) + .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); }) + .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.cpnode, d); this.onNodeClickToggleSidebar(); }) + .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteConfirmation(d); this.onNodedblClickToggleSidebar(); }); this.gcpNode.append('svg:text') .attr('class', 'node_text') .attr('y', graphContainerAttr.textY) - .text((d: COMPOSERNODES) => d.id); + .text((d: COMPOSERNODES): string => d.name); } /** Events handles when mousemove it will capture the selected node data @private */ private mousemove(): void { @@ -740,41 +744,43 @@ export class NSComposerComponent { `M${this.mousedownNode.x},${this.mousedownNode.y}L${d3.mouse(d3.event.currentTarget)[0]},${d3.mouse(d3.event.currentTarget)[1]}`); } /** Get confirmation Before Deleting the Link in Topology @private */ - private getAddConfirmation(mouseData: COMPOSERNODES, getNsData: NSDDetails, addType: string, getVLDIndex: number): void { + private getAddConfirmation(mouseData: COMPOSERNODES, getNsData: NSDDetails, addType: string, getVLDIndex: string): void { let findVNFName: string = ''; let findVLDID: string = ''; if (mouseData.type === 'vld') { findVNFName = this.mouseupNode.name; findVLDID = this.mousedownNode.id; + this.vlName = this.mousedownNode.name; } else { findVNFName = this.mousedownNode.name; findVLDID = this.mouseupNode.id; + this.vlName = this.mouseupNode.name; + } + if (getNsData['vnfd-id'] !== undefined) { + getNsData['vnfd-id'].forEach((resVNFid: string): void => { + if (resVNFid === findVNFName) { + this.getVNFSelectedData = this.vnfList.filter((vnfList: VNFD): boolean => vnfList.id === findVNFName)[0]; + this.setVnfdConnectionPointRef = this.getVNFSelectedData['mgmt-cp']; + this.setVnfdName = this.getVNFSelectedData['product-name']; + this.selectedVNFProfile = getNsData.df[0]['vnf-profile']; + } + }); } - getNsData.vld.forEach((result: VLD) => { - if (result.id === findVLDID) { - this.vlName = result.name; - this.getVNFSelectedData = this.vnfList.filter((vnfList: VNFDDetails) => vnfList.id === findVNFName); - this.setVnfdConnectionPointRef = this.getVNFSelectedData[0]['mgmt-interface'].cp; - this.setVnfdName = this.getVNFSelectedData[0].name; - this.selectedVLDResult = result; - } - }); if (this.vlName !== undefined && this.setVnfdName !== undefined && this.setVnfdConnectionPointRef !== undefined) { const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' }); modalRef.componentInstance.topologyType = 'Add'; - modalRef.componentInstance.cpDetails = this.getVNFSelectedData[0]['connection-point']; + modalRef.componentInstance.cpDetails = this.getVNFSelectedData['ext-cpd']; this.translateService.get('PAGE.TOPOLOGY.ADDINGCP', { vlname: '' + this.vlName + '', vnfdname: '' + this.setVnfdName + '', cpname: '' + this.setVnfdConnectionPointRef + '' - }).subscribe((res: string) => { + }).subscribe((res: string): void => { modalRef.componentInstance.topologyname = res; }); modalRef.componentInstance.topologytitle = this.translateService.instant('PAGE.TOPOLOGY.CONNECTIONPOINT'); - modalRef.result.then((result: MODALCLOSERESPONSEWITHCP) => { + modalRef.result.then((result: MODALCLOSERESPONSEWITHCP): void => { if (result) { - this.nsData = getNsData; - this.generateCPForVNF(this.selectedVLDResult, result.connection_point, getVLDIndex); + this.generateCPForVNF(this.selectedVNFProfile, result.connection_point, getVLDIndex); this.addData(environment.NSDESCRIPTORS_URL, this.identifier, getNsData, addType); } else { this.deselectPath(); @@ -785,26 +791,32 @@ export class NSComposerComponent { this.notifierService.notify('error', this.translateService.instant('ERROR')); } } - /** Generate connection point for vnf using vld @private */ - private generateCPForVNF(result: VLD, cp: string, getVLDIndex: number): void { - if (result['vnfd-connection-point-ref'] !== undefined) { - result['vnfd-connection-point-ref'].push({ - 'member-vnf-index-ref': getVLDIndex, - 'vnfd-connection-point-ref': cp, - 'vnfd-id-ref': this.getVNFSelectedData[0].name + private generateCPForVNF(result: VNFPROFILE[], cp: string, getVLDIndex: string): void { + if (result !== undefined) { + result.forEach((resultVNFPROFILE: VNFPROFILE, index: number): void => { + if (getVLDIndex === resultVNFPROFILE.id) { + resultVNFPROFILE['virtual-link-connectivity'].push({ + 'constituent-cpd-id': [{ + 'constituent-base-element-id': getVLDIndex, + 'constituent-cpd-id': cp + }], + 'virtual-link-profile-id': this.vlName + }); + } }); } else { Object.assign(result, { - 'vnfd-connection-point-ref': [{ - 'member-vnf-index-ref': getVLDIndex, - 'vnfd-connection-point-ref': cp, - 'vnfd-id-ref': this.getVNFSelectedData[0].name + 'virtual-link-connectivity': [{ + 'constituent-cpd-id': [{ + 'constituent-base-element-id': getVLDIndex, + 'constituent-cpd-id': cp + }], + 'virtual-link-profile-id': this.vlName }] }); } } - /** Events handles when mousedown click it will capture the selected node data @private */ private mouseDown(d: COMPOSERNODES): void { event.preventDefault(); @@ -827,12 +839,12 @@ export class NSComposerComponent { this.mouseupNode = d; if (this.mousedownNode.type === 'vld' && this.mouseupNode.type === 'vnfd') { const getOldVLDIndex: string[] = this.mouseupNode.id.split(':'); - const setOldVLDindex: number = +getOldVLDIndex[1]; + const setOldVLDindex: string = getOldVLDIndex[1]; this.putType = 'cpAdded'; this.getAddConfirmation(this.mousedownNode, this.nsData, this.putType, setOldVLDindex); } else if (this.mousedownNode.type === 'vnfd' && this.mouseupNode.type === 'vld') { const getOldVLDIndex: string[] = this.mousedownNode.id.split(':'); - const setOldVLDindex: number = +getOldVLDIndex[1]; + const setOldVLDindex: string = getOldVLDIndex[1]; this.putType = 'cpAdded'; this.getAddConfirmation(this.mousedownNode, this.nsData, this.putType, setOldVLDindex); } else if (this.mousedownNode.type === 'vnfd' && this.mouseupNode.type === 'ns') { @@ -894,27 +906,39 @@ export class NSComposerComponent { this.deselectAllNodes(); nodeSeleced.select('#' + d.selectorId).classed(this.activeClass, !alreadyIsActive); if (d.type === 'vld' && !alreadyIsActive) { - this.nsData.vld.forEach((result: VLD) => { + this.nsData['virtual-link-desc'].forEach((result: VLD): void => { if (result.id === d.id) { this.showRightSideInfo(false, true, false, false); - this.vlDetails = result; + this.virtualLinkDesc = result; } }); } else if (d.type === 'vnfd' && !alreadyIsActive) { - this.nsData['constituent-vnfd'].forEach((result: CONSTITUENTVNFD) => { - if (result['member-vnf-index'] === d.nodeIndex && result['vnfd-id-ref'] === d.name) { - this.showRightSideInfo(false, false, true, false); - this.vnfData = result; + this.nsData.df.forEach((res: DF): void => { + if (res['vnf-profile'] !== undefined) { + res['vnf-profile'].forEach((resVNF: VNFPROFILE): void => { + if (resVNF.id === d.nodeIndex && resVNF['vnfd-id'] === d.name) { + this.showRightSideInfo(false, false, true, false); + this.vnfData = resVNF; + } + }); } }); } else if (d.type === 'ns' && !alreadyIsActive) { - this.nsData.vld.forEach((result: VLD) => { - if (result['vnfd-connection-point-ref'] !== undefined) { - result['vnfd-connection-point-ref'].forEach((resultCP: VNFDCONNECTIONPOINTREF) => { - if (resultCP['member-vnf-index-ref'] === d.nodeIndex && resultCP['vnfd-connection-point-ref'] === d.name) { - this.cpData = resultCP; - this.vlDetails = result; - this.showRightSideInfo(false, false, false, true); + this.nsData.df.forEach((resultDF: DF): void => { + if (resultDF['vnf-profile'] !== undefined) { + resultDF['vnf-profile'].forEach((resVNF: VNFPROFILE): void => { + if (resVNF['virtual-link-connectivity'] !== undefined) { + resVNF['virtual-link-connectivity'].forEach((resultVLC: VLC, index: number): void => { + resultVLC['constituent-cpd-id'].forEach((resultCCI: CCI): void => { + const connectionPointID: string = resVNF.id + ':' + resultCCI['constituent-base-element-id'] + index + ':' + resultCCI['constituent-cpd-id']; + if (connectionPointID === d.id) { + this.cpData = resultCCI; + this.vnfData = resVNF; + this.virtualLinkProfileID = resultVLC['virtual-link-profile-id']; + this.showRightSideInfo(false, false, false, true); + } + }); + }); } }); } @@ -927,9 +951,9 @@ export class NSComposerComponent { private getDeleteLinkConfirmation(d: Tick): void { const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' }); modalRef.componentInstance.topologyType = 'Delete'; - modalRef.componentInstance.topologyname = this.translateService.instant('PAGE.TOPOLOGY.LINK'); + modalRef.componentInstance.topologyname = this.translateService.instant('PAGE.TOPOLOGY.LINK') + ' - ' + d.source.id; modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.LINK'; - modalRef.result.then((result: MODALCLOSERESPONSEDATA) => { + modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => { if (result) { this.doubleClickLink(d); } @@ -938,20 +962,32 @@ export class NSComposerComponent { /** Events handles when Double Click to Delete the link @private */ private doubleClickLink(d: Tick): void { let getID: string = ''; - if (d.target.type === 'vld') { - getID = d.target.id; - } else if (d.source.type === 'vld') { + let getName: string = ''; + let getNodeIndex: string; + if (d.source.type === 'ns') { getID = d.source.id; + getName = d.source.name; + getNodeIndex = d.source.nodeIndex; } - this.nodes.forEach((res: COMPOSERNODES) => { - if (res.id === getID) { - if (this.nsData.vld !== undefined) { - this.nsData.vld.forEach((vldresult: VLD) => { - if (vldresult.id === getID) { - delete vldresult['vnfd-connection-point-ref']; - } - }); - } + /** Split the selected node of connectionpoint */ + const selectedNode: string[] = getID.split(':'); + this.nsData.df.forEach((resultDF: DF): void => { + if (resultDF['vnf-profile'] !== undefined) { + resultDF['vnf-profile'].forEach((elementVNF: VNFPROFILE): void => { + const selectedVNFProfileID: string = selectedNode[0]; + /** If VNF ID is equal to selected VNFProfile ID check the VLC of CCI to match the id and name to remove the VLC index */ + if (selectedVNFProfileID === elementVNF.id) { + elementVNF['virtual-link-connectivity'].forEach((elementVLC: VLC, index: number): void => { + const posCCI: number = elementVLC['constituent-cpd-id'].findIndex((e: CCI): boolean => { + const getCID: string = elementVNF.id + ':' + e['constituent-base-element-id'] + index + ':' + e['constituent-cpd-id']; + return getID === getCID; + }); + if (posCCI !== -1) { + elementVNF['virtual-link-connectivity'].splice(index, 1); + } + }); + } + }); } }); this.putType = 'linkdelete'; @@ -969,7 +1005,7 @@ export class NSComposerComponent { } else if (d.type === 'ns') { modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.CONNECTIONPOINT'; } - modalRef.result.then((result: MODALCLOSERESPONSEDATA) => { + modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => { if (result) { this.doubleClick(d); } @@ -978,72 +1014,95 @@ export class NSComposerComponent { /** Events handles when Double Click to Delete @private */ private doubleClick(d: COMPOSERNODES): void { const deletedNode: COMPOSERNODES = d; - this.nodes.forEach((res: COMPOSERNODES) => { + this.nodes.forEach((res: COMPOSERNODES, i: number): void => { if (res.id === d.id) { if (deletedNode.type === 'vld') { - const pos: number = this.nsData.vld.map((e: VLD) => { return e.id; }).indexOf(d.id); - this.nsData.vld.splice(pos, 1); + /** Remove the virtual-link-desc related to VL */ + const pos: number = this.nsData['virtual-link-desc'].map((e: VLD): string => { return e.id; }).indexOf(d.id); + this.nsData['virtual-link-desc'].splice(pos, 1); + /** Remove the virtual-link-connectivity between VL and VNFD */ + this.nsData.df.forEach((resultDF: DF): void => { + if (resultDF['vnf-profile'] !== undefined) { + resultDF['vnf-profile'].forEach((resVNF: VNFPROFILE): void => { + const getVLArray: number[] = resVNF['virtual-link-connectivity'].map((e: VLC, index: number): number => { + if (e['virtual-link-profile-id'] === d.id) { + return index; + } + }); + if (getVLArray.length > 0) { + getVLArray.forEach((removeIndex: number): void => { + const index: string = removeIndex.toString(); + resVNF['virtual-link-connectivity'].splice(resVNF['virtual-link-connectivity'][index], 1); + }); + } + }); + } + }); this.putType = 'nsddelete'; } else if (deletedNode.type === 'vnfd') { - const constituentVNFD: string[] = []; - if (this.nsData['constituent-vnfd'] !== undefined) { - this.nsData['constituent-vnfd'].forEach((ref: CONSTITUENTVNFD) => { - constituentVNFD.push(ref['vnfd-id-ref'] + ':' + ref['member-vnf-index']); - }); - } - const pos: number = constituentVNFD.map((e: string) => { return e; }).indexOf(d.id); - this.nsData['constituent-vnfd'].splice(pos, 1); - const getCP: string[] = d.id.split(':'); - const memberVnfIndexRef: number = +getCP[1]; - const vnfdIDRef: string = getCP[0]; - if (this.nsData.vld !== undefined) { - this.nsData.vld.forEach((resf: VLD) => { - if (resf['vnfd-connection-point-ref'] !== undefined) { - resf['vnfd-connection-point-ref'].forEach((connectionPoint: VNFDCONNECTIONPOINTREF, index: number) => { - if (+connectionPoint['member-vnf-index-ref'] === memberVnfIndexRef && connectionPoint['vnfd-id-ref'] === vnfdIDRef) { - resf['vnfd-connection-point-ref'].splice(index, 1); - } + this.nsData.df.forEach((resultDF: DF): void => { + if (resultDF['vnf-profile'] !== undefined) { + /** Remove the vnf-profile related to VNFD */ + const posVNF: number = resultDF['vnf-profile'].findIndex((e: VNFPROFILE): boolean => { + return e['vnfd-id'] === d.name && e.id === d.nodeIndex; + }); + resultDF['vnf-profile'].splice(posVNF, 1); + /** Check the VNFD exists in any vnf-profile */ + const isVNFDExists: boolean = resultDF['vnf-profile'].some((e: VNFPROFILE): boolean => { + return e['vnfd-id'] === d.name; + }); + /** If VNFD not exists in the vnf-profile remove from vnfd-id */ + if (!isVNFDExists) { + const posVNFD: number = this.nsData['vnfd-id'].findIndex((e: string): boolean => { + return e === d.name; }); + this.nsData['vnfd-id'].splice(posVNFD, 1); } - }); - } + } + }); this.putType = 'vnfddelete'; } else if (deletedNode.type === 'ns') { - const getCP: string[] = d.selectorId.split('-osm-'); - const memberVnfIndexRef: number = d.nodeIndex; - const vnfdIDRef: string = getCP[getCP.length - 1]; - if (this.nsData.vld !== undefined) { - this.nsData.vld.forEach((resf: VLD) => { - if (resf['vnfd-connection-point-ref'] !== undefined && resf.id === vnfdIDRef) { - resf['vnfd-connection-point-ref'].forEach((connectionPoint: VNFDCONNECTIONPOINTREF, index: number) => { - if (connectionPoint['member-vnf-index-ref'] === memberVnfIndexRef) { - resf['vnfd-connection-point-ref'].splice(index, 1); - } - }); - } - }); - } + /** Split the selected node */ + const selectedNode: string[] = d.id.split(':'); + this.nsData.df.forEach((resultDF: DF): void => { + if (resultDF['vnf-profile'] !== undefined) { + resultDF['vnf-profile'].forEach((elementVNF: VNFPROFILE): void => { + const selectedVNFProfileID: string = selectedNode[0]; + /** If VNF ID is equal to selected VNFProfile ID check the VLC of CCI to match the id and name to remove the VLC index */ + if (selectedVNFProfileID === elementVNF.id) { + elementVNF['virtual-link-connectivity'].forEach((elementVLC: VLC, index: number): void => { + const posCCI: number = elementVLC['constituent-cpd-id'].findIndex((e: CCI): boolean => { + const getID: string = elementVNF.id + ':' + e['constituent-base-element-id'] + index + ':' + e['constituent-cpd-id']; + return d.id === getID; + }); + if (posCCI !== -1) { + elementVNF['virtual-link-connectivity'].splice(index, 1); + } + }); + } + }); + } + }); this.putType = 'nsdelete'; } this.addData(environment.NSDESCRIPTORS_URL, this.identifier, this.nsData, this.putType); } }); } + /** drag event @private */ + // tslint:disable-next-line: no-any + private onDragDrop(): any { + return d3.drag().filter(this.dragFilter) + .on('start', this.dragstarted) + .on('drag', this.dragged) + .on('end', this.dragended); + } /** Key press event @private */ private keyDown(): void { const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr(); if (this.lastKeyDown !== -1) { return; } this.lastKeyDown = d3.event.keyCode; if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) { - this.gvlNode.call(d3.drag() - .on('start', this.dragstarted).on('drag', this.dragged).on('end', this.dragended) - ); - this.gvnfdNode.call(d3.drag() - .on('start', this.dragstarted).on('drag', this.dragged).on('end', this.dragended) - ); - this.gcpNode.call(d3.drag() - .on('start', this.dragstarted).on('drag', this.dragged).on('end', this.dragended) - ); this.svg.classed('ctrl', true); } } @@ -1058,6 +1117,10 @@ export class NSComposerComponent { this.svg.classed('ctrl', false); } } + /** Events handles when to drag using filter for the keys @private */ + private dragFilter(): boolean { + return d3.event.ctrlKey && !d3.event.button; + } /** Events handles when dragstarted @private */ private dragstarted(d: COMPOSERNODES): void { d.fx = d.x;