Bug 1383 Error when consulting NS instance's topology
[osm/NG-UI.git] / src / app / packages / ns-packages / ns-composer / NSComposerComponent.ts
index 687f4fa..7ef8394 100644 (file)
@@ -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: '<b>' + this.vlName + '</b>',
         vnfdname: '<b>' + this.setVnfdName + '</b>',
         cpname: '<b>' + this.setVnfdConnectionPointRef + '</b>'
-      }).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;