Merge "Jointjs integration with angular"
diff --git a/cds-ui/client/JointJS-POC-In-Progress/app-routing.module.ts b/cds-ui/client/JointJS-POC-In-Progress/app-routing.module.ts
new file mode 100644
index 0000000..d425c6f
--- /dev/null
+++ b/cds-ui/client/JointJS-POC-In-Progress/app-routing.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [];
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule]
+})
+export class AppRoutingModule { }
diff --git a/cds-ui/client/JointJS-POC-In-Progress/app.component.html b/cds-ui/client/JointJS-POC-In-Progress/app.component.html
new file mode 100644
index 0000000..da05dd5
--- /dev/null
+++ b/cds-ui/client/JointJS-POC-In-Progress/app.component.html
@@ -0,0 +1,31 @@
+<!-- <div id="myholder"></div> -->
+<div style="background-color: black; color: white; height: 75px; width:100%; font-size: 2em; margin-bottom: 3px">
+  CDS DESIGNER POC
+  <button (click)="convertGraphToJson()">Save</button>
+</div>
+<div style="display: flex;flex-direction:row; height: 700PX">
+  <div id="stencil" style="width: 30%;height: 100%;border: 1px solid; border-radius:0.5em; background-color: gainsboro"></div>
+  <div style="width: 70%; height: 100%;">
+    <div style="position: fixed;width: 200px;background-color: gainsboro;height: 36px;z-index: 2;">
+    <button *ngIf="!sourceMode" style="border-radius: 0.5em;width: 6em;height: 2.5em;border: 2px solid black;" (click)="convertGraphToJson()">Source</button>
+    <button  *ngIf="sourceMode" style="border-radius: 0.5em;width: 6em;height: 2.5em;border: 2px solid black;" (click)="convertJsonToGraph()">Graph</button>
+    <i (click) ="zoomIn()" class="fa fa-search-plus" aria-hidden="true"></i>
+    <i (click) ="zoomOut()" class="fa fa-search-minus" aria-hidden="true"></i>
+    </div>    
+    <div [hidden]="sourceMode" id="paper" style="height: 100%;"></div>
+    <div id="sourceJson" [hidden]="!sourceMode"style="width: 100%; height: 100%;"><textarea style="margin-top: 4em;
+      width: 100%;
+      height: 100%;">{{grapJson}}</textarea></div>
+  </div> 
+  <div id="propertyPanel" style="width: 20%; height: 100%; background-color: white">
+    <div style="background-color: gainsboro;height:28px">Attributes</div>
+    <div style="height: 100px;padding: 10px">
+      Action Name<br/>
+      <input type="text" [(ngModel)]="selectedElement.attributes.attrs.label.text" (change)="setNewValue($event)"/>
+    </div>
+    <div>
+      <div style="background-color: gainsboro;height:28px">Input</div>
+
+    </div>
+  </div>
+</div>
diff --git a/cds-ui/client/JointJS-POC-In-Progress/app.component.scss b/cds-ui/client/JointJS-POC-In-Progress/app.component.scss
new file mode 100644
index 0000000..68d06fb
--- /dev/null
+++ b/cds-ui/client/JointJS-POC-In-Progress/app.component.scss
@@ -0,0 +1,81 @@
+#stencil {
+    position: relative;
+    border: 1px solid gray;
+    display: inline-block;
+    background: transparent;
+    overflow: hidden;
+}
+#stencil svg {
+    background: transparent;
+}
+#stencil svg .link {
+    z-index: 2;
+}
+.html-element {
+    position: absolute;
+    background: #3498DB;
+    /* Make sure events are propagated to the JointJS element so, e.g. dragging works.*/
+    pointer-events: none;
+    -webkit-user-select: none;
+    border-radius: 4px;
+    border: 2px solid #2980B9;
+    box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
+    padding: 5px;
+    box-sizing: border-box;
+    z-index: 2;
+}
+.html-element select,
+.html-element input,
+.html-element button {
+    /* Enable interacting with inputs only. */
+    pointer-events: auto;
+}
+.html-element button.delete {
+    color: white;
+    border: none;
+    background-color: #C0392B;
+    border-radius: 20px;
+    width: 15px;
+    height: 15px;
+    line-height: 15px;
+    text-align: middle;
+    position: absolute;
+    top: -15px;
+    left: -15px;
+    padding: 0;
+    margin: 0;
+    font-weight: bold;
+    cursor: pointer;
+}
+.html-element button.delete:hover {
+    width: 20px;
+    height: 20px;
+    line-height: 20px;
+}
+.html-element select {
+    position: absolute;
+    right: 2px;
+    bottom: 28px;
+}
+.html-element input {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    border: none;
+    color: #333;
+    padding: 5px;
+    height: 16px;
+}
+.html-element label {
+    color: #333;
+    text-shadow: 1px 0 0 lightgray;
+    font-weight: bold;
+}
+.html-element span {
+    position: absolute;
+    top: 2px;
+    right: 9px;
+    color: white;
+    font-size: 10px;
+}
\ No newline at end of file
diff --git a/cds-ui/client/JointJS-POC-In-Progress/app.component.spec.ts b/cds-ui/client/JointJS-POC-In-Progress/app.component.spec.ts
new file mode 100644
index 0000000..8de310a
--- /dev/null
+++ b/cds-ui/client/JointJS-POC-In-Progress/app.component.spec.ts
@@ -0,0 +1,35 @@
+import { TestBed, async } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      imports: [
+        RouterTestingModule
+      ],
+      declarations: [
+        AppComponent
+      ],
+    }).compileComponents();
+  }));
+
+  it('should create the app', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.debugElement.componentInstance;
+    expect(app).toBeTruthy();
+  });
+
+  it(`should have as title 'jointJS-designer'`, () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.debugElement.componentInstance;
+    expect(app.title).toEqual('jointJS-designer');
+  });
+
+  it('should render title in a h1 tag', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    fixture.detectChanges();
+    const compiled = fixture.debugElement.nativeElement;
+    expect(compiled.querySelector('h1').textContent).toContain('Welcome to jointJS-designer!');
+  });
+});
diff --git a/cds-ui/client/JointJS-POC-In-Progress/app.component.ts b/cds-ui/client/JointJS-POC-In-Progress/app.component.ts
new file mode 100644
index 0000000..289a577
--- /dev/null
+++ b/cds-ui/client/JointJS-POC-In-Progress/app.component.ts
@@ -0,0 +1,869 @@
+declare var require: any
+import { Component, OnInit } from '@angular/core';
+import * as $ from 'jquery';
+import * as _ from 'lodash';
+const joint = require('../../node_modules/jointjs/dist/joint.js');
+
+
+@Component({
+  selector: 'app-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.scss']
+})
+export class AppComponent implements OnInit {
+  title = 'jointJS-designer';
+
+  public graph: any;
+  public paper: any;
+  public rect: any;
+  public rect2: any;
+  public link: any;
+
+  public stencilGraph: any;
+  public stencilPaper: any;
+
+  public selectedElement = {
+    attributes: {
+      attrs: {
+        label: {
+          text: 'abc'
+        }
+      }
+    }
+  };
+
+  grapJson: any;
+  sourceMode = false;
+
+  constructor() {
+
+  }
+
+  ngOnInit() {
+    // this.creatElementWithPorts();
+    // this.dragCopyPlainElements();
+    this.sourceMode = false;
+    this.dragCopyElementsWithPort();
+    // this.newDragCopy();
+
+    this.createContainerElements();
+  }
+
+  creatElementWithPorts() {
+    // working code
+
+    // create graph
+    let elementList: any[] = [];
+    // this.graph = new joint.dia.Graph;
+
+    // // create paper
+    // this.paper = new joint.dia.Paper({
+    //   el: document.getElementById('paper'),
+    //   width: 1000,
+    //   height: 1000,
+    //   model: this.graph,
+    //   gridSize: 2,
+    //   drawGrid: true
+    // });
+
+    // this.paper.setGrid({
+    //   name: 'dot',
+    //   args:
+    //     { color: 'black', thickness: 2, scaleFactor: 8 }
+
+    // }).drawGrid();
+
+    // create element
+    this.rect = new joint.shapes.basic.Rect({
+      position: { x: 100, y: 30 },
+      size: { width: 100, height: 100 },
+      attrs: { rect: { fill: 'white' }, text: { text: 'my box', fill: 'white' } }
+    });
+    this.rect.translate(100, 50);
+    elementList.push(this.rect);
+
+    this.rect.position(10, 10);
+    // clone element
+    // this.rect2 = this.rect.clone();
+    // this.rect2.translate(180);
+    // elementList.push(this.rect2);
+
+    // Create link
+    // this.link = new joint.dia.Link({
+    //   source: { id: this.rect.id },
+    //   target: { id: this.rect2.id }
+    // });
+
+
+    // create circle
+    var circle = new joint.shapes.standard.Circle();
+    circle.resize(100, 100);
+    circle.position(180, 10);
+    circle.attr('root/title', 'joint.shapes.standard.Circle');
+    circle.attr('label/text', 'Circle');
+    circle.attr('body/fill', 'lightblue');
+    elementList.push(circle);
+
+    // create link
+    var ellipse = new joint.shapes.standard.Ellipse();
+    ellipse.resize(150, 100);
+    ellipse.position(180, 150);
+    ellipse.attr('root/title', 'joint.shapes.standard.Ellipse');
+    ellipse.attr('label/text', 'Ellipse');
+    ellipse.attr('body/fill', 'lightblue');
+    elementList.push(ellipse);
+
+    // rectangle with header
+    var headeredRectangle = new joint.shapes.standard.HeaderedRectangle();
+    headeredRectangle.resize(150, 100);
+    headeredRectangle.position(10, 280);
+    headeredRectangle.attr('root/title', 'joint.shapes.standard.HeaderedRectangle');
+    headeredRectangle.attr('header/fill', 'lightgray');
+    headeredRectangle.attr('headerText/text', 'Header');
+    headeredRectangle.attr('bodyText/text', 'Headered\nRectangle');
+    elementList.push(headeredRectangle);
+
+    let m1 = new joint.shapes.devs.Model({
+      position: { x: 200, y: 280 },
+      size: { width: 90, height: 90 },
+      inPorts: ['in1', 'in2'],
+      outPorts: ['out', 'out2'],
+      ports: {
+        groups: {
+          'in': {
+            attrs: {
+              '.port-body': {
+                fill: '#16A085'
+              }
+            }
+          },
+          'out': {
+            attrs: {
+              '.port-body': {
+                fill: '#E74C3C'
+              }
+            }
+          }
+        }
+      },
+      attrs: {
+        '.label': { text: 'Model', 'ref-x': .5, 'ref-y': .2 },
+        rect: { fill: 'white' }
+      }
+    });
+    elementList.push(m1);
+
+    //container element
+    let c1 = new joint.shapes.devs.Coupled({
+      position: {
+          x: 150,
+          y: 470
+      },
+      size: {
+          width: 200,
+          height: 200
+      }
+    });
+
+    c1.set('inPorts', ['in']);
+  c1.set('outPorts', ['out 1', 'out 2']);
+  c1.attr({
+    '.body': {
+        'rx': 6,
+        'ry': 6
+    }
+});
+  elementList.push(c1);
+  // circle.position(10, 150);
+  var a1 = new joint.shapes.devs.Atomic({
+    position: {
+        x: 10,
+        y: 150
+    },
+    inPorts: ['xy'],
+    outPorts: ['x', 'y']
+  });
+
+  a1.attr({
+    '.body': {
+        'rx': 6,
+        'ry': 6
+    }
+  });
+
+  elementList.push(a1);
+
+    
+    return elementList;
+  }
+
+  dragCopyPlainElements() {
+    // Canvas where sape are dropped
+    this.graph = new joint.dia.Graph,
+      this.paper = new joint.dia.Paper({
+        el: $('#paper'),
+        model: this.graph
+      });
+
+    // Canvas from which you take shapes
+    this.stencilGraph = new joint.dia.Graph,
+      this.stencilPaper = new joint.dia.Paper({
+        el: $('#stencil'),
+        height: 60,
+        model: this.stencilGraph,
+        interactive: false
+      });
+
+    var r1 = new joint.shapes.basic.Rect({
+      position: {
+        x: 10,
+        y: 10
+      },
+      size: {
+        width: 100,
+        height: 40
+      },
+      attrs: {
+        text: {
+          text: 'Rect1'
+        }
+      }
+    });
+    var r2 = new joint.shapes.basic.Rect({
+      position: {
+        x: 120,
+        y: 10
+      },
+      size: {
+        width: 100,
+        height: 40
+      },
+      attrs: {
+        text: {
+          text: 'Rect2'
+        }
+      }
+    });
+    this.stencilGraph.addCells([r1, r2]);
+
+    let _this = this;
+
+    this.stencilPaper.on('cell:pointerdown', function (cellView, e, x, y) {
+      $('body').append('<div id="flyPaper" style="position:fixed;z-index:100;opacity:.7;pointer-event:none;"></div>');
+      var flyGraph = new joint.dia.Graph,
+        flyPaper = new joint.dia.Paper({
+          el: $('#flyPaper'),
+          model: flyGraph,
+          interactive: false
+        }),
+        flyShape = cellView.model.clone(),
+        pos = cellView.model.position(),
+        offset = {
+          x: x - pos.x,
+          y: y - pos.y
+        };
+
+      flyShape.position(0, 0);
+      flyGraph.addCell(flyShape);
+      $("#flyPaper").offset({
+        left: e.pageX - offset.x,
+        top: e.pageY - offset.y
+      });
+      $('body').on('mousemove.fly', function (e) {
+        $("#flyPaper").offset({
+          left: e.pageX - offset.x,
+          top: e.pageY - offset.y
+        });
+      });
+      $('body').on('mouseup.fly', function (e) {
+        var x = e.pageX,
+          y = e.pageY,
+          target = _this.paper.$el.offset();
+
+        // Dropped over paper ?
+        if (x > target.left && x < target.left + _this.paper.$el.width() && y > target.top && y < target.top + _this.paper.$el.height()) {
+          var s = flyShape.clone();
+          s.position(x - target.left - offset.x, y - target.top - offset.y);
+          _this.graph.addCell(s);
+        }
+        $('body').off('mousemove.fly').off('mouseup.fly');
+        flyShape.remove();
+        $('#flyPaper').remove();
+      });
+    })
+  }
+
+  dragCopyElementsWithPort() {
+    // Canvas where sape are dropped
+    
+    this.graph = new joint.dia.Graph,
+      this.paper = new joint.dia.Paper({
+        el: $('#paper'),
+        model: this.graph,
+        height: 700,
+        width: 1000,
+        gridSize: 2,
+        drawGrid: true
+      });
+
+    // create paper
+    // this.paper = new joint.dia.Paper({
+    //   el: document.getElementById('paper'),
+    //   width: 1000,
+    //   height: 1000,
+    //   model: this.graph,
+    //   gridSize: 2,
+    //   drawGrid: true
+    // });
+
+    this.paper.setGrid({
+      name: 'dot',
+      args:
+        { color: 'black', thickness: 2, scaleFactor: 8 }
+
+    }).drawGrid();
+
+    // Canvas from which you take shapes
+    this.stencilGraph = new joint.dia.Graph,
+      this.stencilPaper = new joint.dia.Paper({
+        el: $('#stencil'),
+        height: 700,
+        width: 382,
+        model: this.stencilGraph,
+        interactive: false
+      });      
+    
+      let elementWithPort = this.creatElementWithPorts();
+      // let elementWithPort = this.createCustomElement();
+      // let elementWithPort = this.myCustomElementGenerator();
+
+      
+    
+    elementWithPort.forEach(element => {
+      this.stencilGraph.addCell(element);
+    });
+    
+    let _this = this;
+    this.stencilPaperEventListeners(_this);
+    this.drawAreapaperEventListerners();
+  }
+
+  resetAll(paper) {
+    this.paper.drawBackground({
+      color: 'white'
+    })
+
+    var elements = this.paper.model.getElements();
+    for (var i = 0, ii = elements.length; i < ii; i++) {
+      var currentElement = elements[i];
+      currentElement.attr('body/stroke', 'black');
+    }
+
+    var links = this.paper.model.getLinks();
+    for (var j = 0, jj = links.length; j < jj; j++) {
+      var currentLink = links[j];
+      currentLink.attr('line/stroke', 'black');
+      currentLink.label(0, {
+        attrs: {
+          body: {
+            stroke: 'black'
+          }
+        }
+      })
+    }
+  }
+
+  onDrag(evt) {
+    // transform client to paper coordinates
+    var p = evt.data.paper.snapToGrid({
+      x: evt.clientX,
+      y: evt.clientY
+    });
+    // manually execute the linkView mousemove handler
+    evt.data.view.pointermove(evt, p.x, p.y);
+  }
+
+  onDragEnd(evt) {
+    // manually execute the linkView mouseup handler
+    evt.data.view.pointerup(evt);
+    $(document).off('.example');
+  }
+
+  stencilPaperEventListeners(_this) {
+    this.stencilPaper.on('cell:pointerdown', function (cellView, e, x, y) {
+      $('body').append('<div id="flyPaper" style="position:fixed;z-index:100;opacity:.7;pointer-event:none;"></div>');
+      var flyGraph = new joint.dia.Graph,
+        flyPaper = new joint.dia.Paper({
+          el: $('#flyPaper'),
+          model: flyGraph,
+          interactive: true
+        }),
+        flyShape = cellView.model.clone(),
+        pos = cellView.model.position(),
+        offset = {
+          x: x - pos.x,
+          y: y - pos.y
+        };
+
+      flyShape.position(0, 0);
+      flyGraph.addCell(flyShape);
+      $("#flyPaper").offset({
+        left: e.pageX - offset.x,
+        top: e.pageY - offset.y
+      });
+      $('body').on('mousemove.fly', function (e) {
+        $("#flyPaper").offset({
+          left: e.pageX - offset.x,
+          top: e.pageY - offset.y
+        });
+      });
+      let elementabove, elementBelow;
+      $('body').on('mouseup.fly', function (e) {
+        console.log(this);        
+        var x = e.pageX,
+          y = e.pageY,
+          target = _this.paper.$el.offset();
+
+        // Dropped over paper ?
+        if (x > target.left && x < target.left + _this.paper.$el.width() && y > target.top && y < target.top + _this.paper.$el.height()) {
+          var s = flyShape.clone();
+
+          // var coordinates = new g.Point(x, y);
+          // elementabove = s;
+          // elementBelow =  _this.paper.model.findModelsFromPoint(coordinates).find(function(el) {
+          //   return (el.id !== elementabove.id);
+          // });
+          // elementBelow =_this.paper.findModelsFromPoint(coordinates).find(function(el) {
+          //     return (el.id !== elementabove.id);
+          //   });
+          // elementBelow.embed(elementabove);
+
+          s.position(x - target.left - offset.x, y - target.top - offset.y);
+          _this.graph.addCell(s);
+          // let elementssss = (_this.graph.getElements());
+          // console.log("elementsss", elementssss);
+          // let elementBelow = elementssss[0];
+          // let elementAbove;
+          // if(elementssss[1]) {
+          //   elementAbove = elementssss[1];
+          //   elementBelow.embed(elementabove);
+          // }
+        }
+        $('body').off('mousemove.fly').off('mouseup.fly');
+        flyShape.remove();
+        $('#flyPaper').remove();
+      });
+      _this.paper.on('mouse')
+    })
+  }
+
+  drawAreapaperEventListerners() {
+    // create event listerners
+    let _this = this;
+    this.paper.on('element:pointerdblclick', function (elementView) {
+      _this.resetAll(this);
+      _this.selectedElement = elementView.model;
+      var currentElement = elementView.model;
+      currentElement.attr('body/stroke', 'orange');
+      // currentElement.attr('label/text', "abc");
+    });
+
+    this.paper.on('blank:pointerdblclick', function () {
+      _this.resetAll(this);
+
+      this.drawBackground({
+        color: 'orange'
+      });
+    });
+
+    this.paper.on('link:pointerclick', function (linkView) {
+      _this.resetAll(this);
+      let currentElement = linkView.model;
+      currentElement.appendLabel({
+        attrs: {
+          text: {
+            text: "Hello to new link!"
+          }
+        }
+      });
+
+    });
+
+
+    this.paper.on('blank:pointerdown', function (evt, x, y) {
+      let linkView = this.getDefaultLink()
+        .set({
+          'source': { x: x, y: y },
+          'target': { x: x, y: y }
+        })
+        .addTo(this.model)
+        .findView(this);
+      linkView.startArrowheadMove('target');
+
+      $(document).on({
+        'mousemove.example': _this.onDrag,
+        'mouseup.example': _this.onDragEnd
+      }, {
+          // shared data between listeners
+          view: linkView,
+          paper: this
+        });
+    });
+
+    this.paper.on({
+      // 'element:pointerdown': function(elementView, evt) {
+
+      //   evt.data = elementView.model.position();
+      // },
+      'element:pointerup': function(elementView, evt, x, y) {
+        var coordinates = new g.Point(x, y);
+        var elementAbove = elementView.model;
+        var elementBelow = this.model.findModelsFromPoint(coordinates).find(function(el) {
+                return (el.id !== elementAbove.id);
+            });
+        if(elementBelow) elementBelow.embed(elementAbove);
+      }
+
+    }); //end of my event
+  }
+
+  createCustomElement() {
+    joint.shapes.html = {};
+    joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
+      defaults: joint.util.deepSupplement({
+          type: 'html.Element',
+          attrs: {
+              rect: { stroke: 'none', 'fill-opacity': 0 }
+          }
+      }, joint.shapes.basic.Rect.prototype.defaults)
+    });
+
+    // / Create a custom view for that element that displays an HTML div above it.
+    // -------------------------------------------------------------------------
+
+    joint.shapes.html.ElementView = joint.dia.ElementView.extend({
+
+          template: [
+            '<div class="html-element">',
+            '<button class="delete">x</button>',
+            '<label></label>',
+            '<span></span>', '<br/>',
+            '<select><option>--</option><option>one</option><option>two</option></select>',
+            '<input type="text" value="I\'m HTML input" />',
+            '</div>'
+        ].join(''),
+
+        initialize: function() {
+          _.bindAll(this, 'updateBox');
+          joint.dia.ElementView.prototype.initialize.apply(this, arguments);
+
+          this.$box = $(_.template(this.template)());
+          // Prevent paper from handling pointerdown.
+          this.$box.find('input,select').on('mousedown click', function(evt) {
+              evt.stopPropagation();
+          });
+          // This is an example of reacting on the input change and storing the input data in the cell model.
+          this.$box.find('input').on('change', _.bind(function(evt) {
+              this.model.set('input', $(evt.target).val());
+          }, this));
+          this.$box.find('select').on('change', _.bind(function(evt) {
+              this.model.set('select', $(evt.target).val());
+          }, this));
+          this.$box.find('select').val(this.model.get('select'));
+          this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
+          // Update the box position whenever the underlying model changes.
+          this.model.on('change', this.updateBox, this);
+          // Remove the box when the model gets removed from the graph.
+          this.model.on('remove', this.removeBox, this);
+
+          this.updateBox();
+        },
+
+        render: function() {
+          joint.dia.ElementView.prototype.render.apply(this, arguments);
+          this.paper.$el.prepend(this.$box);
+          this.updateBox();
+          return this;
+        },
+
+      updateBox: function() {
+        // Set the position and dimension of the box so that it covers the JointJS element.
+        var bbox = this.model.getBBox();
+        // Example of updating the HTML with a data stored in the cell model.
+        this.$box.find('label').text(this.model.get('label'));
+        this.$box.find('span').text(this.model.get('select'));
+        this.$box.css({
+            width: bbox.width,
+            height: bbox.height,
+            left: bbox.x,
+            top: bbox.y,
+            transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)'
+        });
+      },
+
+      removeBox: function(evt) {
+        this.$box.remove();
+      }
+    });
+
+    // Create JointJS elements and add them to the graph as usual.
+        // -----------------------------------------------------------
+
+        var el1 = new joint.shapes.html.Element({
+          position: { x: 10, y: 10 },
+          size: { width: 170, height: 100 },
+          label: 'I am HTML',
+          select: 'one'
+      });
+
+      var el2 = new joint.shapes.html.Element({
+        position: { x: 370, y: 160 },
+        size: { width: 170, height: 100 },
+        label: 'Me too',
+        select: 'two'
+    });
+    var l = new joint.dia.Link({
+        source: { id: el1.id },
+        target: { id: el2.id },
+        attrs: { '.connection': { 'stroke-width': 5, stroke: '#34495E' }}
+    });
+
+    let elementArray : any[] = [];
+    elementArray.push(el1, el2);
+    return elementArray;
+  }
+
+  myCustomElementGenerator() {
+    var Ellipse = joint.dia.Element.define('examples.Ellipse', {
+      // default attributes
+      markup: [{
+          tagName: 'ellipse',
+          selector: 'ellipse' // not necessary but faster
+      }],
+      attrs: {
+          ellipse: {
+              fill: 'white',
+              stroke: 'black',
+              strokeWidth: 4,
+              refRx: .5,
+              refRy: .5,
+              refCx: .5,
+              refCy: .5
+          }
+      }
+  });
+
+    var Rectangle = joint.shapes.standard.Rectangle.define('examples.CustomRectangle', {
+      markup: [{
+        tagName: 'body',
+        selector: 'body' // not necessary but faster
+      },
+      {
+        tagName: 'label',
+        selector: 'label'
+      }],
+      attrs: {
+        body: {
+          rx: 10, // add a corner radius
+          ry: 10,
+          strokeWidth: 1,
+          fill: 'cornflowerblue'
+        },
+        label: {
+          textAnchor: 'left', // align text to left
+          refX: 10, // offset text from right edge of model bbox
+          fill: 'white',
+          fontSize: 18,
+          text: 'mad mad mad'
+        }
+      }
+    })
+  
+
+  var customElement = (new joint.dia.Element.examples.Ellipse()).position(100, 100).size(120, 50);
+    let elementsArray = [];
+    elementsArray.push(customElement);
+
+  var customRect = new Rectangle().position(100, 200).size(120, 120);
+  elementsArray.push(customRect);
+    return elementsArray;
+  }
+
+  convertGraphToJson() {
+    this.grapJson = JSON.stringify(this.graph.toJSON());
+    // this.grapJson = this.graph.toJSON();
+    console.log(this.graph.toJSON());
+    console.log(this.grapJson);
+    this.sourceMode = true;
+  }
+
+  setNewValue(event) {
+    // this.selectedElement.attr('label/text', event.currentTarget.value);
+  }
+
+  convertJsonToGraph() {
+    this.sourceMode = false;
+  }
+
+  zoomIn() {
+    var graphScale = 1;
+    graphScale += 0.1;
+    this.paper.scale(graphScale, graphScale);
+  }
+
+  zoomOut() {
+    var graphScale = 1;
+    graphScale -= 0.1;
+    this.paper.scale(graphScale, graphScale);
+  }
+
+  createContainerElements() {
+    this.graph = new joint.dia.Graph;
+
+    this.paper = new joint.dia.Paper({
+
+      el: document.getElementById('paper'),
+      width: 800,
+      height: 400,
+      gridSize: 1,
+      model: this.graph,
+      snapLinks: true,
+      linkPinning: false,
+      embeddingMode: true,
+      clickThreshold: 5,
+      defaultConnectionPoint: { name: 'boundary' },
+      highlighting: {
+          'default': {
+              name: 'stroke',
+              options: {
+                  padding: 6
+              }
+          },
+          'embedding': {
+              name: 'addClass',
+              options: {
+                  className: 'highlighted-parent'
+              }
+          }
+      },
+  
+      validateEmbedding: function(childView, parentView) {
+          return parentView.model instanceof joint.shapes.devs.Coupled;
+      },
+  
+      validateConnection: function(sourceView, sourceMagnet, targetView, targetMagnet) {
+          return sourceMagnet != targetMagnet;
+      }
+  });
+
+  let c1 = new joint.shapes.devs.Coupled({
+    position: {
+        x: 230,
+        y: 50
+    },
+    size: {
+        width: 300,
+        height: 300
+    }
+});
+
+c1.set('inPorts', ['in']);
+c1.set('outPorts', ['out 1', 'out 2']);
+
+var a1 = new joint.shapes.devs.Atomic({
+  position: {
+      x: 360,
+      y: 260
+  },
+  inPorts: ['xy'],
+  outPorts: ['x', 'y']
+});
+
+var a2 = new joint.shapes.devs.Atomic({
+  position: {
+      x: 50,
+      y: 160
+  },
+  outPorts: ['out']
+});
+
+var a3 = new joint.shapes.devs.Atomic({
+  position: {
+      x: 650,
+      y: 50
+  },
+  size: {
+      width: 100,
+      height: 300
+  },
+  inPorts: ['a', 'b']
+});
+
+[c1, a1, a2, a3].forEach(function(element) {
+  element.attr({
+      '.body': {
+          'rx': 6,
+          'ry': 6
+      }
+  });
+});
+
+
+
+this.graph.addCells([c1, a1, a2, a3]);
+
+c1.embed(a1);
+
+this.connect(a2, 'out', c1, 'in');
+this.connect(c1, 'in', a1, 'xy');
+this.connect(a1, 'x', c1, 'out 1');
+this.connect(a1, 'y', c1, 'out 2');
+this.connect(c1, 'out 1', a3, 'a');
+this.connect(c1, 'out 2', a3, 'b');
+
+var strokeDasharrayPath = '.body/strokeDasharray';
+let _this = this;
+
+this.paper.on('element:pointerdblclick', function(elementView) {
+    var element = elementView.model;
+    if (element.get('type') === 'devs.Atomic') {
+      _this.toggleDelegation(element);
+    }
+});
+
+this.paper.setInteractivity(function(elementView) {
+    return {
+        stopDelegation: !elementView.model.attr(strokeDasharrayPath)
+    };
+});
+
+  
+} // function end
+
+  // function
+  connect(source, sourcePort, target, targetPort) {
+
+    var link = new joint.shapes.devs.Link({
+        source: {
+            id: source.id,
+            port: sourcePort
+        },
+        target: {
+            id: target.id,
+            port: targetPort
+        }
+    });
+
+    link.addTo(this.graph).reparent();
+  }
+
+  toggleDelegation(element) {
+    var strokeDasharrayPath = '.body/strokeDasharray';
+    element.attr(strokeDasharrayPath, element.attr(strokeDasharrayPath) ? '' : '15,1');
+}
+
+createContainerElemnetsByDragDrop() {
+  
+
+}
+}
diff --git a/cds-ui/client/JointJS-POC-In-Progress/app.module.ts b/cds-ui/client/JointJS-POC-In-Progress/app.module.ts
new file mode 100644
index 0000000..15eb6d5
--- /dev/null
+++ b/cds-ui/client/JointJS-POC-In-Progress/app.module.ts
@@ -0,0 +1,24 @@
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';  
+
+import { AppRoutingModule } from './app-routing.module';
+import { AppComponent } from './app.component';
+import { DragCopyComponent } from './drag-copy/drag-copy.component';
+
+@NgModule({
+  declarations: [
+    AppComponent,
+    DragCopyComponent
+  ],
+  imports: [
+    BrowserModule,
+    AppRoutingModule,
+    FormsModule,
+    CommonModule
+  ],
+  providers: [],
+  bootstrap: [AppComponent]
+})
+export class AppModule { }
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
index f1d1d14..ceaace3 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
@@ -49,11 +49,11 @@
     }
     saveBlueprint(body: any | null, options?: any): Observable<any> {
 
-        return this.api.post(BlueprintURLs.save, body, options);
+        return this.api.post(BlueprintURLs.save, body, { responseType: 'text' });
     }
     publishBlueprint(body: any | null, options?: any): Observable<any> {
 
-        return this.api.post(BlueprintURLs.publish, body, options);
+        return this.api.post(BlueprintURLs.publish, body, { responseType: 'text' });
     }
 
     deployPost(body: any | null, options?: any): Observable<any> {
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html
index a6612d5..3740ced 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html
@@ -38,7 +38,7 @@
                 <button mat-menu-item (click)="saveToBlueprintProcessor()">Deploy</button>
                 <!-- <button mat-menu-item (click)="processBlueprint()">Test</button> -->
             </mat-menu>
-            <button class="btn-active" (click)="publishToControllerBlueprint()">Publish</button>
+            <!-- <button class="btn-active" (click)="publishToControllerBlueprint()">Publish</button> -->
             <button class="btn-active" (click)="saveToControllerBlueprint()">Save</button>
             <button class="btn-active" (click)="getEnriched()">Enrich</button>
 
diff --git a/cds-ui/server/src/config/app-config.ts b/cds-ui/server/src/config/app-config.ts
index dcca629..a2cebe5 100644
--- a/cds-ui/server/src/config/app-config.ts
+++ b/cds-ui/server/src/config/app-config.ts
@@ -21,12 +21,12 @@
     })
 });
 
-export const controllerApiConfig = Object.freeze({
-    http: Object.freeze({
-        url: process.env.API_BLUEPRINT_PROCESSOR_HTTP_BASE_URL || "http://localhost:8081/api/v1",
-        authToken: process.env.API_BLUEPRINT_PROCESSOR_HTTP_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw=="
-    })
-});
+// export const controllerApiConfig = Object.freeze({
+//     http: Object.freeze({
+//         url: process.env.API_BLUEPRINT_PROCESSOR_HTTP_BASE_URL || "http://localhost:8081/api/v1",
+//         authToken: process.env.API_BLUEPRINT_PROCESSOR_HTTP_AUTH_TOKEN || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw=="
+//     })
+// });
 
 export const processorApiConfig = Object.freeze({
     http: Object.freeze({
diff --git a/cds-ui/server/src/controllers/blueprint-rest.controller.ts b/cds-ui/server/src/controllers/blueprint-rest.controller.ts
index c73f7a6..7895898 100644
--- a/cds-ui/server/src/controllers/blueprint-rest.controller.ts
+++ b/cds-ui/server/src/controllers/blueprint-rest.controller.ts
@@ -48,7 +48,7 @@
 import * as fs from 'fs';
 import * as multiparty from 'multiparty';
 import * as request_lib from 'request';
-import { controllerApiConfig, processorApiConfig, appConfig } from '../config/app-config';
+import { processorApiConfig, appConfig } from '../config/app-config';
 import { bluePrintManagementServiceGrpcClient } from '../clients/blueprint-management-service-grpc-client';
 
 export class BlueprintRestController {
@@ -220,7 +220,7 @@
   }
 
   async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response> {
-    return this.uploadFileToBlueprintService(file, controllerApiConfig.http.url + uri, controllerApiConfig.http.authToken, response);
+    return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
   }
 
   async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<Response> {
@@ -267,7 +267,7 @@
   }
 
   async downloadFileFromBlueprintController(uri: string, response: Response): Promise<Response> {
-    return this.downloadFileFromBlueprintService(controllerApiConfig.http.url + uri, controllerApiConfig.http.authToken, response);
+    return this.downloadFileFromBlueprintService(processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
   }
 
   async downloadFileFromBlueprintService(url: string, authToken: string, response: Response): Promise<Response> {
diff --git a/cds-ui/server/src/datasources/blueprint.datasource-template.ts b/cds-ui/server/src/datasources/blueprint.datasource-template.ts
index 1188d9b..85e0aa3 100644
--- a/cds-ui/server/src/datasources/blueprint.datasource-template.ts
+++ b/cds-ui/server/src/datasources/blueprint.datasource-template.ts
@@ -1,19 +1,19 @@
-import {controllerApiConfig} from '../config/app-config';
+import {processorApiConfig} from '../config/app-config';
 
 export default {
     "name": "blueprint",
     "connector": "rest",
-    "baseURL": controllerApiConfig.http.url,
+    "baseURL": processorApiConfig.http.url,
     "crud": false,
     "debug": true,
     "operations": [{
         "template": {
             "method": "GET",
-            "url": controllerApiConfig.http.url + "/blueprint-model/",
+            "url": processorApiConfig.http.url + "/blueprint-model/",
             "headers": {
                 "accepts": "application/json",
                 "content-type": "application/json",
-                "authorization": controllerApiConfig.http.authToken
+                "authorization": processorApiConfig.http.authToken
             },
             "responsePath": "$.*"
         },
@@ -25,11 +25,11 @@
     {
         "template": {
             "method": "GET",
-            "url": controllerApiConfig.http.url + "/blueprint-model/search/{tags}",
+            "url": processorApiConfig.http.url + "/blueprint-model/search/{tags}",
             "headers": {
                 "accepts": "application/json",
                 "content-type": "application/json",
-                "authorization": controllerApiConfig.http.authToken
+                "authorization": processorApiConfig.http.authToken
             },
             "responsePath": "$.*"
         },
diff --git a/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts b/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts
index 9f9d754..f839bb2 100644
--- a/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts
+++ b/cds-ui/server/src/datasources/resource-dictionary.datasource-template.ts
@@ -1,19 +1,19 @@
-import {controllerApiConfig} from '../config/app-config';
+import {processorApiConfig} from '../config/app-config';
 
 export default {
     "name": "resourceDictionary",
     "connector": "rest",
-    "baseURL": controllerApiConfig.http.url + "/dictionary",
+    "baseURL": processorApiConfig.http.url + "/dictionary",
     "crud": false,
     "debug": true,
     "operations": [{
             "template": {
                 "method": "GET",
-                "url": controllerApiConfig.http.url + "/dictionary/{name}",
+                "url": processorApiConfig.http.url + "/dictionary/{name}",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "responsePath": "$.*"
             },
@@ -25,11 +25,11 @@
         {
             "template": {
                 "method": "GET",
-                "url": controllerApiConfig.http.url + "/dictionary/source-mapping",
+                "url": processorApiConfig.http.url + "/dictionary/source-mapping",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "responsePath": "$.*"
             },
@@ -41,11 +41,11 @@
         {
             "template": {
                 "method": "GET",
-                "url": controllerApiConfig.http.url + "/dictionary/search/{tags}",
+                "url": processorApiConfig.http.url + "/dictionary/search/{tags}",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "responsePath": "$.*"
             },
@@ -57,11 +57,11 @@
         {
             "template": {
                 "method": "POST",
-                "url": controllerApiConfig.http.url + "/dictionary",
+                "url": processorApiConfig.http.url + "/dictionary",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "body": "{resourceDictionary}",
                 "responsePath": "$.*"
@@ -74,11 +74,11 @@
         {
             "template": {
                 "method": "POST",
-                "url": controllerApiConfig.http.url + "/dictionary/by-names",
+                "url": processorApiConfig.http.url + "/dictionary/by-names",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "body": "{resourceDictionaryList}",
                 "responsePath": "$.*"
@@ -91,11 +91,11 @@
         {
             "template": {
                 "method": "GET",
-                "url": controllerApiConfig.http.url + "/model-type/{source}",
+                "url": processorApiConfig.http.url + "/model-type/{source}",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "responsePath": "$.*"
             },
@@ -107,11 +107,11 @@
         {
             "template": {
                 "method": "GET",
-                "url": controllerApiConfig.http.url + "/model-type/by-definition/data_type",
+                "url": processorApiConfig.http.url + "/model-type/by-definition/data_type",
                 "headers": {
                     "accepts": "application/json",
                     "content-type": "application/json",
-                    "authorization": controllerApiConfig.http.authToken
+                    "authorization": processorApiConfig.http.authToken
                 },
                 "responsePath": "$.*"
             },
diff --git a/components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/resources_definition_types.json
index 426b91d..a35974c 100644
--- a/components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/resources_definition_types.json
+++ b/components/model-catalog/blueprint-model/service-blueprint/vFW/Definitions/resources_definition_types.json
@@ -876,22 +876,6 @@
       "default" : {
         "type" : "source-default",
         "properties" : { }
-      },
-      "sdnc" : {
-        "type" : "source-rest",
-        "properties" : {
-          "type" : "JSON",
-          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-id",
-          "path" : "/param/0/value",
-          "input-key-mapping" : {
-            "service-instance-id" : "service-instance-id",
-            "vnf-id" : "vnf-id"
-          },
-          "output-key-mapping" : {
-            "vnf-id" : "value"
-          },
-          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
-        }
       }
     }
   },
@@ -930,16 +914,16 @@
         "type" : "source-rest",
         "properties" : {
           "type" : "JSON",
-          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-name/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-name",
+          "url-path" : "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-name",
           "path" : "/param/0/value",
           "input-key-mapping" : {
             "service-instance-id" : "service-instance-id",
-            "vnf-name" : "vnf-name"
+            "vnf-id" : "vnf-id"
           },
           "output-key-mapping" : {
             "vnf-name" : "value"
           },
-          "key-dependencies" : [ "service-instance-id", "vnf-name" ]
+          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
         }
       },
       "aai-data" : {
@@ -1184,4 +1168,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json
index aa49e1e..f7da409 100644
--- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json
+++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/resources_definition_types.json
@@ -1760,23 +1760,6 @@
       "default" : {
         "type" : "source-default",
         "properties" : { }
-      },
-      "sdnc" : {
-        "type" : "source-rest",
-        "properties" : {
-          "verb" : "GET",
-          "type" : "JSON",
-          "url-path" : "/restconf/config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-id",
-          "path" : "/param/0/value",
-          "input-key-mapping" : {
-            "service-instance-id" : "service-instance-id",
-            "vnf-id" : "vnf-id"
-          },
-          "output-key-mapping" : {
-            "vnf-id" : "value"
-          },
-          "key-dependencies" : [ "service-instance-id", "vnf-id" ]
-        }
       }
     }
   },
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt
index d29abb0..9552b61 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt
+++ b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt
@@ -35,7 +35,8 @@
     override suspend fun processNB(executionRequest: ExecutionServiceInput) {
         log.info("Executing process : ${executionRequest.payload}")
 
-        val data = executionRequest.payload.at("/check-request/data")
+        val data = requestPayloadActionProperty("data")?.first()
+            ?: throw BluePrintProcessorException("Failed to load payload data properties.")
 
         log.info("Data : ${data.asJsonString()}")
 
diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json
index 8445d29..a71bef9 100755
--- a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json
+++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-id.json
@@ -13,25 +13,6 @@
         "default": {
           "type": "source-default",
           "properties": {}
-        },
-        "sdnc": {
-          "type": "source-rest",
-          "properties": {
-            "type": "JSON",
-            "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-id",
-            "path": "/param/0/value",
-            "input-key-mapping": {
-              "service-instance-id": "service-instance-id",
-              "vnf-id": "vnf-id"
-            },
-            "output-key-mapping": {
-              "vnf-id": "value"
-            },
-            "key-dependencies": [
-              "service-instance-id",
-              "vnf-id"
-            ]
-          }
         }
       }
     }
diff --git a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json
index 675b754..7d65119 100755
--- a/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json
+++ b/components/model-catalog/resource-dictionary/starter-dictionary/vnf-name.json
@@ -18,18 +18,18 @@
       "type": "source-rest",
       "properties": {
         "type": "JSON",
-        "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-name/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-name",
+        "url-path": "config/GENERIC-RESOURCE-API:services/service/$service-instance-id/service-data/vnfs/vnf/$vnf-id/vnf-data/vnf-topology/vnf-parameters-data/param/vnf-name",
         "path": "/param/0/value",
         "input-key-mapping": {
           "service-instance-id": "service-instance-id",
-          "vnf-name": "vnf-name"
+          "vnf-id": "vnf-id"
         },
         "output-key-mapping": {
           "vnf-name": "value"
         },
         "key-dependencies": [
           "service-instance-id",
-          "vnf-name"
+          "vnf-id"
         ]
       }
     },
diff --git a/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt
new file mode 100644
index 0000000..5ed5ff4
--- /dev/null
+++ b/ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/LoggingWebFilter.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor
+
+import org.onap.ccsdk.cds.blueprintsprocessor.core.service.LoggingService
+import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext
+import org.springframework.stereotype.Component
+import org.springframework.web.server.ServerWebExchange
+import org.springframework.web.server.WebFilter
+import org.springframework.web.server.WebFilterChain
+import reactor.core.publisher.Mono
+import reactor.util.context.Context
+
+@Component
+open class LoggingWebFilter : WebFilter {
+    override fun filter(serverWebExchange: ServerWebExchange, webFilterChain: WebFilterChain): Mono<Void> {
+
+        val loggingService = LoggingService()
+        loggingService.entering(serverWebExchange.request)
+        val filterChain = webFilterChain.filter(serverWebExchange).subscriberContext(
+                Context.of(MDCContext,  MDCContext()))
+        loggingService.exiting(serverWebExchange.request, serverWebExchange.response)
+        return filterChain
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
index e40ccba..faabb80 100755
--- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
+++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties
@@ -36,7 +36,7 @@
 blueprintsprocessor.blueprintWorkingPath=blueprints/work
 # Controller Blueprint Load Configurations
 # blueprints.load.initial-data may be overridden by ENV variables
-blueprintsprocessor.loadInitialData=true
+blueprintsprocessor.loadInitialData=false
 blueprintsprocessor.loadBluePrint=false
 blueprintsprocessor.loadBluePrintPaths=./../../../components/model-catalog/blueprint-model/service-blueprint
 blueprintsprocessor.loadModelType=true
diff --git a/ms/blueprintsprocessor/application/src/main/resources/logback.xml b/ms/blueprintsprocessor/application/src/main/resources/logback.xml
index 6f91709..9d2b82f 100644
--- a/ms/blueprintsprocessor/application/src/main/resources/logback.xml
+++ b/ms/blueprintsprocessor/application/src/main/resources/logback.xml
@@ -15,11 +15,16 @@
   -->
 
 <configuration>
+
+    <property name="localPattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
+    <property name="defaultPattern"
+              value="%date{ISO8601,UTC}|%X{RequestID}|%X{InvocationID}|%thread|%X{ServiceName}|%X{ClientIPAddress}|%logger{50}| %msg%n"/>
+
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <!-- encoders are assigned the type
              ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
         <encoder>
-            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <pattern>${defaultPattern}</pattern>
         </encoder>
     </appender>
 
diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt
index ab04054..1cd8a2a 100644
--- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt
+++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/BluePrintMessageLibData.kt
@@ -36,6 +36,7 @@
     var clientId: String? = null
     var topic: String? = null
     var pollMillSec: Long = 1000
+    var pollRecords: Int = -1
 }
 
 open class KafkaBasicAuthMessageConsumerProperties : KafkaMessageConsumerProperties()
diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt
index 5a9e61b..b5d444a 100644
--- a/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt
+++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/KafkaBasicAuthMessageConsumerService.kt
@@ -51,6 +51,10 @@
         if (messageConsumerProperties.clientId != null) {
             configProperties[ConsumerConfig.CLIENT_ID_CONFIG] = messageConsumerProperties.clientId!!
         }
+        /** To handle Back pressure, Get only configured record for processing */
+        if (messageConsumerProperties.pollRecords > 0) {
+            configProperties[ConsumerConfig.MAX_POLL_RECORDS_CONFIG] = messageConsumerProperties.pollRecords
+        }
         // TODO("Security Implementation based on type")
         /** add or override already set properties */
         additionalConfig?.let { configProperties.putAll(it) }
@@ -84,6 +88,7 @@
             kafkaConsumer!!.use { kc ->
                 while (keepGoing) {
                     val consumerRecords = kc.poll(Duration.ofMillis(messageConsumerProperties.pollMillSec))
+                    log.info("Consumed Records : ${consumerRecords.count()}")
                     runBlocking {
                         consumerRecords?.forEach { consumerRecord ->
                             /** execute the command block */
diff --git a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt
index 2b84eaa..f4e85a9 100644
--- a/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt
+++ b/ms/blueprintsprocessor/modules/commons/message-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/message/service/BlueprintMessageConsumerServiceTest.kt
@@ -52,6 +52,7 @@
     "blueprintsprocessor.messageconsumer.sample.topic=default-topic",
     "blueprintsprocessor.messageconsumer.sample.clientId=default-client-id",
     "blueprintsprocessor.messageconsumer.sample.pollMillSec=10",
+    "blueprintsprocessor.messageconsumer.sample.pollRecords=1",
 
     "blueprintsprocessor.messageproducer.sample.type=kafka-basic-auth",
     "blueprintsprocessor.messageproducer.sample.bootstrapServers=127.0.0.1:9092",
@@ -129,11 +130,11 @@
                     .blueprintMessageProducerService("sample") as KafkaBasicAuthMessageProducerService
             launch {
                 repeat(5) {
-                    delay(1000)
+                    delay(100)
                     blueprintMessageProducerService.sendMessage("this is my message($it)")
                 }
             }
-            delay(10000)
+            delay(5000)
             blueprintMessageConsumerService.shutDown()
         }
     }
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/LoggerExtensions.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/LoggerExtensions.kt
new file mode 100644
index 0000000..cdf6ce1
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/LoggerExtensions.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.core
+
+import kotlinx.coroutines.*
+import kotlinx.coroutines.reactor.ReactorContext
+import kotlinx.coroutines.reactor.asCoroutineContext
+import org.onap.ccsdk.cds.blueprintsprocessor.core.service.MonoMDCCoroutine
+import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext
+import reactor.core.publisher.Mono
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+
+/** Used in Rest controller API methods to populate MDC context to nested coroutines from reactor web filter context. */
+@UseExperimental(InternalCoroutinesApi::class)
+fun <T> monoMdc(context: CoroutineContext = EmptyCoroutineContext,
+                block: suspend CoroutineScope.() -> T?): Mono<T> = Mono.create { sink ->
+
+    val reactorContext = (context[ReactorContext]?.context?.putAll(sink.currentContext())
+            ?: sink.currentContext()).asCoroutineContext()
+    /** Populate MDC context only if present in Reactor Context */
+    val newContext = if (!reactorContext.context.isEmpty
+            && reactorContext.context.hasKey(MDCContext)) {
+        val mdcContext = reactorContext.context.get<MDCContext>(MDCContext)
+        GlobalScope.newCoroutineContext(context + reactorContext + mdcContext)
+    } else GlobalScope.newCoroutineContext(context + reactorContext)
+
+    val coroutine = MonoMDCCoroutine(newContext, sink)
+    sink.onDispose(coroutine)
+    coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/service/BluePrintProcessorLoggingService.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/service/BluePrintProcessorLoggingService.kt
new file mode 100644
index 0000000..4da7dcd
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/service/BluePrintProcessorLoggingService.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.core.service
+
+import kotlinx.coroutines.AbstractCoroutine
+import kotlinx.coroutines.InternalCoroutinesApi
+import kotlinx.coroutines.handleCoroutineException
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.slf4j.MDC
+import org.springframework.http.server.reactive.ServerHttpRequest
+import org.springframework.http.server.reactive.ServerHttpResponse
+import reactor.core.Disposable
+import reactor.core.publisher.MonoSink
+import java.time.ZoneOffset
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+import java.util.*
+import kotlin.coroutines.CoroutineContext
+
+class LoggingService {
+    private val log = logger(LoggingService::class)
+
+    companion object {
+        const val ONAP_REQUEST_ID = "X-ONAP-RequestID"
+        const val ONAP_INVOCATION_ID = "X-ONAP-InvocationID"
+        const val ONAP_PARTNER_NAME = "X-ONAP-PartnerName"
+    }
+
+    fun entering(request: ServerHttpRequest) {
+        val headers = request.headers
+        val requestID = defaultToUUID(headers.getFirst(ONAP_REQUEST_ID))
+        val invocationID = defaultToUUID(headers.getFirst(ONAP_INVOCATION_ID))
+        val partnerName = defaultToEmpty(headers.getFirst(ONAP_PARTNER_NAME))
+        MDC.put("InvokeTimestamp", ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT))
+        MDC.put("RequestID", requestID)
+        MDC.put("InvocationID", invocationID)
+        MDC.put("PartnerName", partnerName)
+        MDC.put("ClientIPAddress", defaultToEmpty(request.remoteAddress?.address?.hostAddress))
+        MDC.put("ServerFQDN", defaultToEmpty(request.remoteAddress?.hostString))
+        if (MDC.get("ServiceName") == null || MDC.get("ServiceName").equals("", ignoreCase = true)) {
+            MDC.put("ServiceName", request.uri.path)
+        }
+    }
+
+    fun exiting(request: ServerHttpRequest, response: ServerHttpResponse) {
+        try {
+            val reqHeaders = request.headers
+            val resHeaders = response.headers
+            resHeaders[ONAP_REQUEST_ID] = MDC.get("RequestID")
+            resHeaders[ONAP_INVOCATION_ID] = MDC.get("InvocationID")
+        } catch (e: Exception) {
+            log.warn("couldn't set response headers", e)
+        } finally {
+            MDC.clear()
+        }
+    }
+
+    private fun defaultToEmpty(input: Any?): String {
+        return input?.toString() ?: ""
+    }
+
+    private fun defaultToUUID(input: String?): String {
+        return input ?: UUID.randomUUID().toString()
+    }
+}
+
+
+@InternalCoroutinesApi
+class MonoMDCCoroutine<in T>(
+        parentContext: CoroutineContext,
+        private val sink: MonoSink<T>
+) : AbstractCoroutine<T>(parentContext, true), Disposable {
+    private var disposed = false
+
+    override fun onCompleted(value: T) {
+        if (!disposed) {
+            if (value == null) sink.success() else sink.success(value)
+        }
+    }
+
+    override fun onCancelled(cause: Throwable, handled: Boolean) {
+        if (!disposed) {
+            sink.error(cause)
+        } else if (!handled) {
+            handleCoroutineException(context, cause)
+        }
+    }
+
+    override fun dispose() {
+        disposed = true
+        cancel()
+    }
+
+    override fun isDisposed(): Boolean = disposed
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
index 4d13486..a6bff70 100644
--- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
@@ -19,7 +19,7 @@
 
 import io.swagger.annotations.ApiOperation
 import io.swagger.annotations.ApiParam
-import kotlinx.coroutines.runBlocking
+import org.onap.ccsdk.cds.blueprintsprocessor.core.monoMdc
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch
 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler.BluePrintModelHandler
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
@@ -29,6 +29,7 @@
 import org.springframework.http.codec.multipart.FilePart
 import org.springframework.security.access.prepost.PreAuthorize
 import org.springframework.web.bind.annotation.*
+import reactor.core.publisher.Mono
 
 /**
  * BlueprintModelController Purpose: Handle controllerBlueprint API request
@@ -44,7 +45,7 @@
     @ResponseBody
     @Throws(BluePrintException::class)
     @PreAuthorize("hasRole('USER')")
-    fun saveBlueprint(@RequestPart("file") filePart: FilePart): BlueprintModelSearch = runBlocking {
+    fun saveBlueprint(@RequestPart("file") filePart: FilePart): Mono<BlueprintModelSearch> = monoMdc {
         bluePrintModelHandler.saveBlueprintModel(filePart)
     }
 
@@ -67,8 +68,9 @@
     @Throws(BluePrintException::class)
     @PreAuthorize("hasRole('USER')")
     fun getBlueprintByNameAndVersion(@PathVariable(value = "name") name: String,
-                                     @PathVariable(value = "version") version: String): BlueprintModelSearch {
-        return this.bluePrintModelHandler.getBlueprintModelSearchByNameAndVersion(name, version)
+                                     @PathVariable(value = "version") version: String)
+            : Mono<BlueprintModelSearch> = monoMdc {
+        bluePrintModelHandler.getBlueprintModelSearchByNameAndVersion(name, version)
     }
 
     @GetMapping("/download/by-name/{name}/version/{version}", produces = [MediaType.APPLICATION_JSON_VALUE])
@@ -76,8 +78,9 @@
     @Throws(BluePrintException::class)
     @PreAuthorize("hasRole('USER')")
     fun downloadBlueprintByNameAndVersion(@PathVariable(value = "name") name: String,
-                                          @PathVariable(value = "version") version: String): ResponseEntity<Resource> {
-        return this.bluePrintModelHandler.downloadBlueprintModelFileByNameAndVersion(name, version)
+                                          @PathVariable(value = "version") version: String)
+            : Mono<ResponseEntity<Resource>> = monoMdc {
+        bluePrintModelHandler.downloadBlueprintModelFileByNameAndVersion(name, version)
     }
 
     @GetMapping("/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
@@ -92,8 +95,8 @@
     @ResponseBody
     @Throws(BluePrintException::class)
     @PreAuthorize("hasRole('USER')")
-    fun downloadBluePrint(@PathVariable(value = "id") id: String): ResponseEntity<Resource> {
-        return this.bluePrintModelHandler.downloadBlueprintModelFile(id)
+    fun downloadBluePrint(@PathVariable(value = "id") id: String): Mono<ResponseEntity<Resource>> = monoMdc {
+        bluePrintModelHandler.downloadBlueprintModelFile(id)
     }
 
     @PostMapping("/enrich", produces = [MediaType.APPLICATION_JSON_VALUE], consumes = [MediaType
@@ -101,7 +104,7 @@
     @ResponseBody
     @Throws(BluePrintException::class)
     @PreAuthorize("hasRole('USER')")
-    fun enrichBlueprint(@RequestPart("file") file: FilePart): ResponseEntity<Resource> = runBlocking {
+    fun enrichBlueprint(@RequestPart("file") file: FilePart): Mono<ResponseEntity<Resource>> = monoMdc {
         bluePrintModelHandler.enrichBlueprint(file)
     }
 
@@ -109,7 +112,7 @@
     @ResponseBody
     @Throws(BluePrintException::class)
     @PreAuthorize("hasRole('USER')")
-    fun publishBlueprint(@RequestPart("file") file: FilePart): BlueprintModelSearch = runBlocking {
+    fun publishBlueprint(@RequestPart("file") file: FilePart): Mono<BlueprintModelSearch> = monoMdc {
         bluePrintModelHandler.publishBlueprint(file)
     }
 
@@ -128,7 +131,7 @@
     fun deleteBlueprint(@ApiParam(value = "Name of the CBA.", required = true)
                         @PathVariable(value = "name") name: String,
                         @ApiParam(value = "Version of the CBA.", required = true)
-                        @PathVariable(value = "version") version: String) = runBlocking {
+                        @PathVariable(value = "version") version: String) = monoMdc {
         bluePrintModelHandler.deleteBlueprintModel(name, version)
     }
 }
diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt
index 4441d2b..f14f61e 100644
--- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt
+++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt
@@ -17,27 +17,29 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api
 
-import com.fasterxml.jackson.databind.JsonNode
 import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
 import io.swagger.annotations.ApiParam
-import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ACTION_MODE_ASYNC
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
+import org.onap.ccsdk.cds.blueprintsprocessor.core.monoMdc
 import org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.utils.determineHttpStatusCode
 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.http.ResponseEntity
 import org.springframework.security.access.prepost.PreAuthorize
 import org.springframework.web.bind.annotation.*
+import reactor.core.publisher.Mono
 
 @RestController
 @RequestMapping("/api/v1/execution-service")
 @Api(value = "/api/v1/execution-service",
         description = "Interaction with CBA.")
 open class ExecutionServiceController {
+    val log = logger(ExecutionServiceController::class)
 
     @Autowired
     lateinit var executionServiceHandler: ExecutionServiceHandler
@@ -47,7 +49,8 @@
             produces = [MediaType.APPLICATION_JSON_VALUE])
     @ResponseBody
     @ApiOperation(value = "Health Check", hidden = true)
-    fun executionServiceControllerHealthCheck(): JsonNode = runBlocking {
+    fun executionServiceControllerHealthCheck() = monoMdc {
+        log.info("Health check success...")
         "Success".asJsonPrimitive()
     }
 
@@ -59,12 +62,13 @@
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
     fun process(@ApiParam(value = "ExecutionServiceInput payload.", required = true)
-                @RequestBody executionServiceInput: ExecutionServiceInput): ResponseEntity<ExecutionServiceOutput> =
-            runBlocking {
-                if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) {
-                    throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.")
-                }
-                val processResult = executionServiceHandler.doProcess(executionServiceInput)
-                ResponseEntity(processResult, determineHttpStatusCode(processResult.status.code))
-            }
+                @RequestBody executionServiceInput: ExecutionServiceInput)
+            : Mono<ResponseEntity<ExecutionServiceOutput>> = monoMdc {
+
+        if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) {
+            throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.")
+        }
+        val processResult = executionServiceHandler.doProcess(executionServiceInput)
+        ResponseEntity(processResult, determineHttpStatusCode(processResult.status.code))
+    }
 }
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
index 5163a93..bee9192 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
@@ -167,9 +167,9 @@
      */
     fun requestPayloadActionProperty(expression: String?): JsonNode? {
         val requestExpression = if (expression.isNullOrBlank()) {
-            "$operationName-request"
+            "$workflowName-request"
         } else {
-            "$operationName-request.$expression"
+            "$workflowName-request.$expression"
         }
         return executionServiceInput.payload.jsonPathParse(".$requestExpression")
     }
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt
index a16c520..062d370 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt
@@ -54,6 +54,7 @@
         scriptComponent.operationName = componentFunction.operationName
         scriptComponent.nodeTemplateName = componentFunction.nodeTemplateName
         scriptComponent.operationInputs = componentFunction.operationInputs
+        scriptComponent.executionServiceInput = componentFunction.executionServiceInput
         scriptComponent.scriptType = scriptType
 
         // Populate Instance Properties
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionService.kt
index 0784816..adb1d67 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionService.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionService.kt
@@ -20,15 +20,14 @@
 import com.github.marcoferrer.krotoplus.coroutines.client.ClientBidiCallChannel
 import com.github.marcoferrer.krotoplus.coroutines.client.clientCallBidiStreaming
 import io.grpc.ManagedChannel
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.FlowPreview
-import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.*
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.consumeAsFlow
-import kotlinx.coroutines.launch
 import org.onap.ccsdk.cds.blueprintsprocessor.grpc.GrpcClientProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcClientService
 import org.onap.ccsdk.cds.blueprintsprocessor.grpc.service.BluePrintGrpcLibPropertyService
+import org.onap.ccsdk.cds.controllerblueprints.common.api.EventType
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
 import org.onap.ccsdk.cds.controllerblueprints.core.logger
 import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc
@@ -39,11 +38,13 @@
 
 interface StreamingRemoteExecutionService<ReqT, ResT> {
 
-    suspend fun openSubscription(selector: Any, requestId: String): Flow<ResT>
+    suspend fun openSubscription(selector: Any, txId: String): Flow<ResT>
 
-    suspend fun send(input: ReqT)
+    suspend fun sendNonInteractive(selector: Any, txId: String, input: ReqT, timeOutMill: Long): ResT
 
-    suspend fun cancelSubscription(requestId: String)
+    suspend fun send(txId: String, input: ReqT)
+
+    suspend fun cancelSubscription(txId: String)
 
     suspend fun closeChannel(selector: Any)
 }
@@ -63,60 +64,90 @@
 
 
     /**
-     * Open new channel to send and receive for grpc properties [selector] for [requestId],
+     * Open new channel to send and receive for grpc properties [selector] for [txId],
      * Create the only one GRPC channel per host port and reuse for further communication.
      * Create request communication channel to send and receive requests and responses.
-     * We can send multiple request with same requestId with unique subRequestId.
+     * We can send multiple request with same txId.
      * Consume the flow for responses,
      * Client should cancel the subscription for the request Id once no longer response is needed.
      * */
     @FlowPreview
-    override suspend fun openSubscription(selector: Any, requestId: String): Flow<ExecutionServiceOutput> {
+    override suspend fun openSubscription(selector: Any, txId: String): Flow<ExecutionServiceOutput> {
 
-        if (!commChannels.containsKey(requestId)) {
+        if (!commChannels.containsKey(txId)) {
             /** Get GRPC Channel*/
             val grpcChannel = grpcChannel(selector)
 
             /** Get Send and Receive Channel for bidirectional process method*/
             val channels = clientCallBidiStreaming(BluePrintProcessingServiceGrpc.getProcessMethod(), grpcChannel)
-            commChannels[requestId] = channels
+            commChannels[txId] = channels
         }
 
-        val commChannel = commChannels[requestId]
-                ?: throw BluePrintException("failed to create response subscription for request($requestId) channel")
+        val commChannel = commChannels[txId]
+                ?: throw BluePrintException("failed to create response subscription for transactionId($txId) channel")
 
-        log.info("created subscription for request($requestId)")
+        log.info("created subscription for transactionId($txId)")
 
         return commChannel.responseChannel.consumeAsFlow()
     }
 
     /**
-     * Send the [input]request, by reusing same GRPC channel and Communication channel
+     * Send the [input] request, by reusing same GRPC channel and Communication channel
      * for the request Id.
      */
-    override suspend fun send(input: ExecutionServiceInput) {
-        val requestId = input.commonHeader.requestId
-        val subRequestId = input.commonHeader.subRequestId
-        val sendChannel = commChannels[requestId]?.requestChannel
-                ?: throw BluePrintException("failed to get request($requestId) send channel")
+    override suspend fun send(txId: String, input: ExecutionServiceInput) {
+        val sendChannel = commChannels[txId]?.requestChannel
+                ?: throw BluePrintException("failed to get transactionId($txId) send channel")
         coroutineScope {
             launch {
                 sendChannel.send(input)
-                log.trace("Message sent for request($requestId) : subRequest($subRequestId)")
+                log.trace("Message sent for transactionId($txId)")
             }
         }
     }
 
-    /** Cancel the Subscription for the [requestId], This closes communication channel **/
+    /**
+     * Simplified version of Streaming calls, Use this API only listing for actual response for [input]
+     * for the GRPC [selector] with execution [timeOutMill].
+     * Other state of the request will be skipped.
+     * The assumption here is you can call this API with same request Id and unique subrequest Id,
+     * so the correlation is sub request id to receive the response.
+     */
     @ExperimentalCoroutinesApi
-    override suspend fun cancelSubscription(requestId: String) {
-        commChannels[requestId]?.let {
+    override suspend fun sendNonInteractive(selector: Any, txId: String, input: ExecutionServiceInput, timeOutMill: Long)
+            : ExecutionServiceOutput {
+
+        var output: ExecutionServiceOutput? = null
+        val flow = openSubscription(selector, txId)
+
+        /** Send the request */
+        val sendChannel = commChannels[txId]?.requestChannel
+                ?: throw BluePrintException("failed to get transactionId($txId) send channel")
+        sendChannel.send(input)
+
+        /** Receive the response with timeout */
+        withTimeout(timeOutMill) {
+            flow.collect {
+                log.trace("Received non-interactive transactionId($txId) response : ${it.status.eventType}")
+                if (it.status.eventType == EventType.EVENT_COMPONENT_EXECUTED) {
+                    output = it
+                    cancelSubscription(txId)
+                }
+            }
+        }
+        return output!!
+    }
+
+    /** Cancel the Subscription for the [txId], This closes communication channel **/
+    @ExperimentalCoroutinesApi
+    override suspend fun cancelSubscription(txId: String) {
+        commChannels[txId]?.let {
             if (!it.requestChannel.isClosedForSend)
                 it.requestChannel.close()
             /** If receive channel has to close immediately, once the subscription has cancelled, then enable this */
             //it.responseChannel.cancel(CancellationException("subscription cancelled"))
-            commChannels.remove(requestId)
-            log.info("closed subscription for request($requestId)")
+            commChannels.remove(txId)
+            log.info("closed subscription for transactionId($txId)")
         }
     }
 
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt
index c9ff235..29d24c6 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionServiceTest.kt
@@ -36,6 +36,8 @@
 import org.onap.ccsdk.cds.controllerblueprints.core.logger
 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput
 import java.util.*
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
 
 
 class StreamingRemoteExecutionServiceTest {
@@ -69,25 +71,48 @@
 
             val spyStreamingRemoteExecutionService = spyk(streamingRemoteExecutionService)
             /** To test with real server, uncomment below line */
-            coEvery { spyStreamingRemoteExecutionService.createGrpcChannel(any()) } returns channel
+            coEvery() { spyStreamingRemoteExecutionService.createGrpcChannel(any()) } returns channel
 
+            /** Test Send and Receive non interactive transaction */
+            val nonInteractiveDeferred = arrayListOf<Deferred<*>>()
+            repeat(2) { count ->
+                val requestId = "1234-$count"
+                val request = getRequest(requestId)
+                val invocationId = request.commonHeader.subRequestId
+                val deferred = async {
+                    val response = spyStreamingRemoteExecutionService.sendNonInteractive(tokenAuthGrpcClientProperties,
+                            invocationId, request, 1000L)
+                    assertNotNull(response, "failed to get non interactive response")
+                    assertEquals(response.commonHeader.requestId, requestId,
+                            "failed to match non interactive response id")
+                    assertEquals(response.status.eventType, EventType.EVENT_COMPONENT_EXECUTED,
+                            "failed to match non interactive response type")
+                }
+                nonInteractiveDeferred.add(deferred)
+
+            }
+            nonInteractiveDeferred.awaitAll()
+
+            /** Test Send and Receive interactive transaction */
             val responseFlowsDeferred = arrayListOf<Deferred<*>>()
-
-            repeat(1) { count ->
+            repeat(2) { count ->
                 val requestId = "12345-$count"
-                val responseFlow = spyStreamingRemoteExecutionService.openSubscription(tokenAuthGrpcClientProperties, requestId)
+                val request = getRequest(requestId)
+                val invocationId = request.commonHeader.requestId
+                val responseFlow = spyStreamingRemoteExecutionService
+                        .openSubscription(tokenAuthGrpcClientProperties, invocationId)
 
                 val deferred = async {
                     responseFlow.collect {
-                        log.info("Received $count-response (${it.commonHeader.subRequestId}) : ${it.status.eventType}")
+                        log.info("Received $count-response ($invocationId) : ${it.status.eventType}")
                         if (it.status.eventType == EventType.EVENT_COMPONENT_EXECUTED) {
-                            spyStreamingRemoteExecutionService.cancelSubscription(it.commonHeader.requestId)
+                            spyStreamingRemoteExecutionService.cancelSubscription(invocationId)
                         }
                     }
                 }
                 responseFlowsDeferred.add(deferred)
                 /** Sending Multiple messages with same requestId  and different subRequestId */
-                spyStreamingRemoteExecutionService.send(getRequest(requestId))
+                spyStreamingRemoteExecutionService.send(invocationId, request)
             }
             responseFlowsDeferred.awaitAll()
             streamingRemoteExecutionService.closeChannel(tokenAuthGrpcClientProperties)
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt
index 16e4e61..2fc9a99 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/AbstractComponentFunctionTest.kt
@@ -95,7 +95,7 @@
     @Test
     fun testComponentFunctionPayload() {
         val sampleComponent = SampleComponent()
-        sampleComponent.operationName = "sample-action"
+        sampleComponent.workflowName = "sample-action"
         sampleComponent.executionServiceInput = JacksonUtils.readValueFromClassPathFile(
             "payload/requests/sample-execution-request.json", ExecutionServiceInput::class.java)!!
         val payload = sampleComponent.requestPayload()
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml
index 703a526..afe10b3 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml
@@ -19,7 +19,7 @@
         <!-- encoders are assigned the type
              ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
         <encoder>
-            <pattern>%d{HH:mm:ss.SSS} %-5level %logger{100} - %msg%n</pattern>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
         </encoder>
     </appender>
 
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContext.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContext.kt
new file mode 100644
index 0000000..001ec75
--- /dev/null
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContext.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core
+
+import kotlinx.coroutines.ThreadContextElement
+import org.slf4j.MDC
+import kotlin.coroutines.AbstractCoroutineContextElement
+import kotlin.coroutines.CoroutineContext
+
+typealias MDCContextMap = Map<String, String>?
+
+class MDCContext(private val contextMap: MDCContextMap = MDC.getCopyOfContextMap()) :
+        ThreadContextElement<MDCContextMap>, AbstractCoroutineContextElement(Key) {
+    /**
+     * Key of [MDCContext] in [CoroutineContext].
+     */
+    companion object Key : CoroutineContext.Key<MDCContext>
+
+    override fun updateThreadContext(context: CoroutineContext): MDCContextMap {
+        val oldState = MDC.getCopyOfContextMap()
+        setCurrent(contextMap)
+        return oldState
+    }
+
+    override fun restoreThreadContext(context: CoroutineContext, oldState: MDCContextMap) {
+        setCurrent(oldState)
+    }
+
+    private fun setCurrent(contextMap: MDCContextMap) {
+        if (contextMap == null) {
+            MDC.clear()
+        } else {
+            MDC.setContextMap(contextMap)
+        }
+    }
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt
new file mode 100644
index 0000000..2ddb450
--- /dev/null
+++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/MDCContextTest.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2018-2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core
+
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Before
+import org.slf4j.MDC
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class MDCContextTest {
+    val log = logger(MDCContextTest::class)
+    @Before
+    fun setup() {
+        MDC.clear()
+    }
+
+    @After
+    fun tearDow() {
+        MDC.clear()
+    }
+
+    @Test
+    fun testContextCanBePassedBetweenCoroutines() {
+        MDC.put(BluePrintConstants.RESPONSE_HEADER_TRANSACTION_ID, "12345")
+        runBlocking {
+            GlobalScope.launch {
+                assertEquals(null, MDC.get(BluePrintConstants.RESPONSE_HEADER_TRANSACTION_ID))
+            }
+            launch(MDCContext()) {
+                assertEquals("12345", MDC.get(BluePrintConstants.RESPONSE_HEADER_TRANSACTION_ID),
+                        "couldn't get request id")
+
+                MDC.put("client_id", "client-1")
+                assertEquals("client-1", MDC.get("client_id"), "couldn't get client id")
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ms/py-executor/requirements.txt b/ms/py-executor/requirements.txt
index 6051e04..b556369 100644
--- a/ms/py-executor/requirements.txt
+++ b/ms/py-executor/requirements.txt
@@ -2,5 +2,4 @@
 grpcio-tools==1.23.0
 configparser==4.0.2
 requests==2.22.0
-ncclient==0.6.6
-ciscoconfparse==1.4.7
\ No newline at end of file
+ncclient==0.6.6
\ No newline at end of file