diff options
90 files changed, 3540 insertions, 389 deletions
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 000000000..d425c6f56 --- /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 000000000..da05dd563 --- /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 000000000..68d06fbe7 --- /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 000000000..8de310a78 --- /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 000000000..289a57766 --- /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 000000000..15eb6d5fc --- /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/app-routing.module.ts b/cds-ui/client/src/app/app-routing.module.ts index 96dfce18e..01ecfe48b 100644 --- a/cds-ui/client/src/app/app-routing.module.ts +++ b/cds-ui/client/src/app/app-routing.module.ts @@ -2,6 +2,8 @@ ============LICENSE_START========================================== =================================================================== Copyright (C) 2018 IBM Intellectual Property. All rights reserved. + +Modifications Copyright (C) 2019 TechMahindra =================================================================== Unless otherwise specified, all software contained herein is licensed @@ -36,6 +38,10 @@ const routes: Routes = [ { path: 'resource-definition', loadChildren: './feature-modules/resource-definition/resource-definition.module#ResourceDefinitionModule' + }, + { + path: 'controller-catalog', + loadChildren: './feature-modules/controller-catalog/controller-catalog.module#ControllerCatalogModule' } ] } diff --git a/cds-ui/client/src/app/common/constants/app-constants.ts b/cds-ui/client/src/app/common/constants/app-constants.ts index 78fefd803..5beb6af74 100644 --- a/cds-ui/client/src/app/common/constants/app-constants.ts +++ b/cds-ui/client/src/app/common/constants/app-constants.ts @@ -2,6 +2,8 @@ ============LICENSE_START========================================== =================================================================== Copyright (C) 2018 IBM Intellectual Property. All rights reserved. + +Modifications Copyright (C) 2019 TechMahindra =================================================================== Unless otherwise specified, all software contained herein is licensed @@ -110,4 +112,11 @@ export const ResourceDictionaryURLs = { getSources: '/resourcedictionary/source-mapping', getModelType: '/resourcedictionary/model-type', getDataType: '/resourcedictionary/model-type/by-definition/data_type' +} + +export const ControllerCatalogURLs = { + searchControllerCatalogByTags: '/controllercatalog/search', + saveControllerCatalog: '/controllercatalog/save', + getDefinition: '/controllercatalog/model-type/by-definition', + getDerivedFrom: '/controllercatalog/model-type/by-derivedfrom' }
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/core.module.ts b/cds-ui/client/src/app/common/core/core.module.ts index 7207178a9..3743ab3b1 100644 --- a/cds-ui/client/src/app/common/core/core.module.ts +++ b/cds-ui/client/src/app/common/core/core.module.ts @@ -25,13 +25,13 @@ import { StoreModule, Store } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { StoreRouterConnectingModule } from '@ngrx/router-store'; import { HttpClientModule } from '@angular/common/http'; - import { appReducers } from './store/reducers/app.reducer'; import { BlueprintEffects } from './store/effects/blueprint.effects'; import { ResourcesEffects } from './store/effects/resources.effects'; import { ApiService } from './services/api.service'; import { NotificationHandlerService } from './services/notification-handler.service'; import { LoaderService } from './services/loader.service'; +import { CatalogEffects } from './store/effects/catalog.effect'; // import { BlueprintService } from './services/blueprint.service'; @NgModule({ @@ -40,7 +40,7 @@ import { LoaderService } from './services/loader.service'; imports: [ CommonModule, StoreModule.forRoot(appReducers), - EffectsModule.forRoot([BlueprintEffects, ResourcesEffects]), + EffectsModule.forRoot([BlueprintEffects, ResourcesEffects, CatalogEffects]), StoreRouterConnectingModule.forRoot({ stateKey: 'router' }), HttpClientModule ], diff --git a/cds-ui/client/src/app/common/core/store/actions/catalog.action.ts b/cds-ui/client/src/app/common/core/store/actions/catalog.action.ts new file mode 100644 index 000000000..938cdb110 --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/actions/catalog.action.ts @@ -0,0 +1,77 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Injectable } from '@angular/core'; +import { Action, Store } from '@ngrx/store'; +import { ICatalog } from '../models/catalog.model'; +import { ICatalogState } from '../models/catalogState.model'; + +export const LOAD_CATALOG = 'LOAD_CATALOG'; +export const LOAD_CATALOG_SUCCESS = 'LOAD_CATALOG_SUCCESS'; +export const LOAD_CATALOG_FAILURE = 'LOAD_CATALOG_FAILURE'; +export const UPDATE_CATALOG ='UPDATE_CATALOG'; +export const UPDATE_CATALOG_SUCCESS = 'UPDATE_CATALOG_SUCCESS'; +export const UPDATE_CATALOG_FAILURE = 'UPDATE_CATALOG_FAILURE'; +export const SAVE_CATALOG = 'SAVE_CATALOG'; +export const SAVE_CATALOG_SUCCESS = 'SAVE_CATALOG_SUCCESS'; +export const SAVE_CATALOG_FAILURE = 'SAVE_CATALOG_FAILURE'; + +export const SET_CATALOG = 'SET CATALOG'; +export const REMOVE_CATALOG = 'Remove CATALOG'; + +export const SET_CATALOG_STATE = 'SET CATALOG state'; + + +export class LoadCatalog implements Action { + readonly type = LOAD_CATALOG; + constructor(public startLoadSuccess?: boolean) {} +} + +export class LoadCatalogSuccess implements Action { + readonly type = LOAD_CATALOG_SUCCESS; + constructor(public payload: ICatalog) {} +} + +export class LoadCatalogFailure implements Action { + readonly type = LOAD_CATALOG_FAILURE; + constructor(public error: any) {} +} + +export class SetCatalogState implements Action { + readonly type = SET_CATALOG_STATE; + constructor(public payload: ICatalogState) {} +} + +// export class SetCatalog implements Action { +// readonly type = SET_CATALOG; +// constructor(public payload: Catalog) {} +// } + +// export class RemoveCatalog implements Action { +// readonly type = REMOVE_CATALOG; +// constructor(public payload: Catalog) {} +// } + +export class UpdateCatalog implements Action { + readonly type = UPDATE_CATALOG; + constructor(public payload: ICatalog) {} +} + +export type Actions = LoadCatalog | LoadCatalogSuccess | LoadCatalogFailure | SetCatalogState;
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/effects/catalog.effect.ts b/cds-ui/client/src/app/common/core/store/effects/catalog.effect.ts new file mode 100644 index 000000000..db2296eb7 --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/effects/catalog.effect.ts @@ -0,0 +1,37 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
+
+import { Injectable } from '@angular/core';
+import { Effect, ofType, Actions } from '@ngrx/effects';
+import { Store, select } from '@ngrx/store';
+import { of } from 'rxjs';
+import { switchMap, map, withLatestFrom, catchError } from 'rxjs/operators';
+
+import { IAppState } from '../state/app.state';
+import * as CatalogActions from '../actions/catalog.action';
+
+@Injectable()
+export class CatalogEffects {
+
+ constructor(
+ private _actions$: Actions,
+ private _store: Store<IAppState>
+ ) {}
+}
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/models/catalog-http.model.ts b/cds-ui/client/src/app/common/core/store/models/catalog-http.model.ts new file mode 100644 index 000000000..dde1f979c --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/models/catalog-http.model.ts @@ -0,0 +1,25 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { ICatalog } from './catalog.model'; + +export interface ICatalogHttp { + catalog: ICatalog; +}
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/models/catalog.model.ts b/cds-ui/client/src/app/common/core/store/models/catalog.model.ts new file mode 100644 index 000000000..2344f3336 --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/models/catalog.model.ts @@ -0,0 +1,29 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
+
+export interface ICatalog {
+ Model_Name: string;
+ User_id: string;
+ _tags: string;
+ _type: string;
+ Derived_From: string;
+ _description : string;
+ definition: object[];
+}
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/models/catalogState.model.ts b/cds-ui/client/src/app/common/core/store/models/catalogState.model.ts new file mode 100644 index 000000000..937dd87e0 --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/models/catalogState.model.ts @@ -0,0 +1,28 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { ICatalog } from './catalog.model'; + +export interface ICatalogState { + catalog: ICatalog, + isLoadSuccess?: boolean; + isUpdateSuccess?: boolean; + isSaveSuccess?: boolean; +}
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/reducers/app.reducer.ts b/cds-ui/client/src/app/common/core/store/reducers/app.reducer.ts index 6f583202c..785939040 100644 --- a/cds-ui/client/src/app/common/core/store/reducers/app.reducer.ts +++ b/cds-ui/client/src/app/common/core/store/reducers/app.reducer.ts @@ -21,13 +21,14 @@ limitations under the License. import { ActionReducerMap } from '@ngrx/store'; import { routerReducer } from '@ngrx/router-store'; - import { IAppState } from '../state/app.state'; import { blueprintReducer } from '../reducers/blueprint.reducer'; import { resourcesReducer } from '../reducers/resources.reducer'; +import { catalogReducer } from '../reducers/catalog.reducer'; export const appReducers: ActionReducerMap<IAppState, any> = { router: routerReducer, blueprint: blueprintReducer, - resources:resourcesReducer + resources:resourcesReducer, + catalog: catalogReducer };
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/reducers/catalog.reducer.ts b/cds-ui/client/src/app/common/core/store/reducers/catalog.reducer.ts new file mode 100644 index 000000000..ae5ca4e1e --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/reducers/catalog.reducer.ts @@ -0,0 +1,39 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Action } from '@ngrx/store'; +import { initialCatalogState } from '../state/catalog.state'; +import * as CatalogActions from '../actions/catalog.action'; +import { ICatalogState } from '../models/catalogState.model'; + +export function catalogReducer(state: ICatalogState = initialCatalogState, action: CatalogActions.Actions) : ICatalogState { + switch(action.type) { + case CatalogActions.LOAD_CATALOG_SUCCESS: + return {...state, + catalog: action.payload + } + case CatalogActions.SET_CATALOG_STATE: + return {...state, + catalog: action.payload.catalog + } + default: + return state; + } +} diff --git a/cds-ui/client/src/app/common/core/store/selectors/catalog.selectors.ts b/cds-ui/client/src/app/common/core/store/selectors/catalog.selectors.ts new file mode 100644 index 000000000..172448f53 --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/selectors/catalog.selectors.ts @@ -0,0 +1,31 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { createSelector } from '@ngrx/store'; + +import { IAppState } from '../state/app.state'; +import { ICatalogState } from '../models/catalogState.model'; + +const selectCatalogFromAppState = (state: IAppState) => state.catalog; + +export const selectCatalog = createSelector( + selectCatalogFromAppState, + (state: ICatalogState) => state.catalog +);
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/state/app.state.ts b/cds-ui/client/src/app/common/core/store/state/app.state.ts index 052eb2c5b..c08edce1e 100644 --- a/cds-ui/client/src/app/common/core/store/state/app.state.ts +++ b/cds-ui/client/src/app/common/core/store/state/app.state.ts @@ -24,14 +24,17 @@ import { IBlueprintState } from '../models/blueprintState.model'; import { initialBlueprintState } from './blueprint.state'; import { IResourcesState } from '../models/resourcesState.model'; import { initialResourcesState } from './resources.state'; +import { ICatalogState } from '../models/catalogState.model'; +import { initialCatalogState } from './catalog.state'; export interface IAppState { router? : RouterReducerState, blueprint: IBlueprintState, - resources: IResourcesState + resources: IResourcesState, + catalog: ICatalogState } - export const initialAppState: IAppState = { blueprint: initialBlueprintState, - resources: initialResourcesState + resources: initialResourcesState, + catalog: initialCatalogState }
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/core/store/state/catalog.state.ts b/cds-ui/client/src/app/common/core/store/state/catalog.state.ts new file mode 100644 index 000000000..a780269c5 --- /dev/null +++ b/cds-ui/client/src/app/common/core/store/state/catalog.state.ts @@ -0,0 +1,29 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { ICatalogState } from '../models/catalogState.model'; +import { ICatalog } from '../models/catalog.model'; + +export const initialCatalogState : ICatalogState = { + catalog : {} as ICatalog, + isLoadSuccess: false, + isUpdateSuccess: false, + isSaveSuccess: false, +}
\ No newline at end of file diff --git a/cds-ui/client/src/app/common/shared/components/home/home.component.html b/cds-ui/client/src/app/common/shared/components/home/home.component.html index f73f0e863..beff353ef 100644 --- a/cds-ui/client/src/app/common/shared/components/home/home.component.html +++ b/cds-ui/client/src/app/common/shared/components/home/home.component.html @@ -1,6 +1,8 @@ <!-- ============LICENSE_START========================================== =================================================================== Copyright (C) 2018 IBM Intellectual Property. All rights reserved. + +Modifications Copyright (C) 2019 TechMahindra =================================================================== Unless otherwise specified, all software contained herein is licensed @@ -50,6 +52,7 @@ limitations under the License. </ul> </nav> --> <a mat-list-item [routerLink]="['/resource-definition']">Resource Definition</a> + <a mat-list-item [routerLink]="['/controller-catalog']">Controller Catalog</a> </mat-nav-list> </mat-sidenav> diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog-routing.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog-routing.module.ts new file mode 100644 index 000000000..e8bf86cf4 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog-routing.module.ts @@ -0,0 +1,35 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { ControllerCatalogComponent } from './controller-catalog.component'; +import { Routes, RouterModule } from '@angular/router'; + +const routes: Routes = [ + { + path: '', + component: ControllerCatalogComponent + } +]; +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ControllerCatalogRoutingModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.html new file mode 100644 index 000000000..06dfadee6 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.html @@ -0,0 +1,41 @@ +<!--/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/--> + +<mat-card class="RDform"> + <mat-card-content> + <mat-horizontal-stepper [linear]="isLinear" #stepper> + <mat-step [stepControl]="firstFormGroup"> + <ng-template matStepLabel>Catalog Creation Method</ng-template> + <app-select-template (option)="selectedOption($event)"></app-select-template><br><br> + <div> + <button mat-button matStepperNext class="matStepNextBtn">Proceed</button> + </div> + </mat-step> + <mat-step [stepControl]="secondFormGroup"> + <ng-template matStepLabel>Catalog Create/Search</ng-template> + <app-create-catalog *ngIf="selectedValue == 1"></app-create-catalog><br> + <app-search-catalog *ngIf="selectedValue == 2"></app-search-catalog><br> + <div> + <button mat-button matStepperPrevious class="matStepNextBtn">Back</button> + </div> + </mat-step> + </mat-horizontal-stepper> + </mat-card-content> +</mat-card>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.scss new file mode 100644 index 000000000..ea304fb2a --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.scss @@ -0,0 +1,32 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
+
+.mat-card {
+ padding: 0px !important;
+}
+
+.matStepNextBtn{
+ color:white;
+ background:#3f51b5;
+ margin-top: 10px;
+ position: absolute;
+ margin-bottom: 5px;
+ border-radius: 4px;
+}
diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.spec.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.spec.ts new file mode 100644 index 000000000..69b702726 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.spec.ts @@ -0,0 +1,46 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ControllerCatalogComponent } from './controller-catalog.component'; + +describe('ControllerCatalogComponent', () => { + let component: ControllerCatalogComponent; + let fixture: ComponentFixture<ControllerCatalogComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ControllerCatalogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ControllerCatalogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.ts new file mode 100644 index 000000000..ed0886924 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.component.ts @@ -0,0 +1,42 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + + +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-controller-catalog', + templateUrl: './controller-catalog.component.html', + styleUrls: ['./controller-catalog.component.scss'] +}) +export class ControllerCatalogComponent implements OnInit { + + selectedValue: any; + constructor() { } + + ngOnInit() { + } + + selectedOption(value){ + this.selectedValue=value; + console.log(this.selectedValue); + } + +} diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts new file mode 100644 index 000000000..9f5e1400f --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/controller-catalog.module.ts @@ -0,0 +1,67 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ControllerCatalogRoutingModule } from './controller-catalog-routing.module'; +import { ControllerCatalogComponent } from './controller-catalog.component'; +import { SharedModule } from '../../../app/common/shared/shared.module'; +import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule, MatAutocompleteModule} from '@angular/material'; +import { MatIconModule } from '@angular/material/icon'; +import { SelectTemplateComponent } from './select-template/select-template.component'; +import { TemplateOptionsComponent } from './select-template/template-options/template-options.component'; +import { SearchCatalogComponent } from './search-catalog/search-catalog.component'; +import { CreateCatalogComponent } from './create-catalog/create-catalog.component'; +import { CreateCatalogModule } from './create-catalog/create-catalog.module'; +import { SearchCatalogModule } from './search-catalog/search-catalog.module'; +import { FormsModule,ReactiveFormsModule } from '@angular/forms'; +import { NgJsonEditorModule } from 'ang-jsoneditor'; + +@NgModule({ + declarations: [ ControllerCatalogComponent, SelectTemplateComponent, TemplateOptionsComponent, SearchCatalogComponent, CreateCatalogComponent ], + imports: [ + CommonModule, + ControllerCatalogRoutingModule, + CreateCatalogModule, + SearchCatalogModule, + SharedModule, + MatToolbarModule, + MatButtonModule, + MatSidenavModule, + MatIconModule, + MatListModule, + MatGridListModule, + MatCardModule, + MatMenuModule, + MatTableModule, + MatPaginatorModule, + MatSortModule, + MatInputModule, + MatSelectModule, + MatRadioModule, + MatFormFieldModule, + MatStepperModule, + MatAutocompleteModule, + FormsModule, + ReactiveFormsModule, + NgJsonEditorModule + ] +}) +export class ControllerCatalogModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog-routing.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog-routing.module.ts new file mode 100644 index 000000000..68d13b214 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog-routing.module.ts @@ -0,0 +1,34 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { CreateCatalogComponent } from './create-catalog.component'; + +const routes: Routes = [ + { + path: '', + component: CreateCatalogComponent + } +]; +@NgModule({ +imports: [RouterModule.forChild(routes)], +exports: [RouterModule] +}) +export class CreateCatalogRoutingModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.html new file mode 100644 index 000000000..8c71edfa7 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.html @@ -0,0 +1,56 @@ +<!--/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/--> +<mat-card class="ver-card"> + <mat-card-header><div class="mat-card-header">Create Catalog</div> + </mat-card-header> + <mat-card-content> +<form [formGroup]="CatalogFormData" (ngSubmit)="CreateCatalog()"> + <mat-form-field class="form-field"> + <input matInput placeholder="Model Name" formControlName="Model_Name"> + </mat-form-field> + <mat-form-field class="form-field" > + <input matInput placeholder="User Id" formControlName="User_id"> +</mat-form-field> + <mat-form-field class="form-field"> + <input matInput placeholder="Tags" formControlName="_tags"> + </mat-form-field> + <mat-form-field class="form-field"> + <mat-select matInput placeholder="Definition Type" formControlName="_type"> + <mat-option [value]="item" *ngFor="let item of definitionType">{{item.definitionType}}</mat-option> + </mat-select> + </mat-form-field> + <mat-form-field class="form-field" > + <mat-select matInput placeholder="Derived From" formControlName="Derived_From"> + <mat-option [value]="item" *ngFor="let item of derivedFrom">{{item.derivedFrom}}</mat-option> + </mat-select> + </mat-form-field> + <mat-form-field class="form-field" > + <textarea matInput placeholder="Description" formControlName="_description"></textarea> + </mat-form-field> + <br> + <div > + <json-editor placeholder="Definition" class="jsoneditor" [options]="options" [data]="resources" on-change="onChange($event)"></json-editor> + </div> + <div> + <button mat-button class="matStepNextBtn" type="submit">Save</button> + </div> +</form> +</mat-card-content> +</mat-card>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.scss new file mode 100644 index 000000000..cc8e292aa --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.scss @@ -0,0 +1,60 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
+.matStepNextBtn{
+ color:white;
+ background:#3f51b5;
+ margin-top: 10px;
+ position: absolute;
+ margin-bottom: 5px;
+ border-radius: 4px;
+}
+.meta-form {
+ width: 100%;
+}
+
+.form-field {
+ width: 40%;
+ padding:20px;
+}
+
+.form-table {
+ width: 100%;
+}
+.ver-card {
+ width: 100%;
+ background-color: #f1f1f1;
+ padding: 0.01em 16px;
+ margin: 20px 0;
+ box-shadow: 0 2px 2px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)!important;
+ height: 800px;
+ }
+ .mat-card-header{
+ height:35px;
+ padding-top: 4px;
+ }
+ .mat-card-content{
+ width: auto;
+ background-color: #fff;
+ padding: 8px 8px;
+ // border-left: 4px solid #4CAF50;
+ word-wrap: break-word;
+ min-height:350px;
+ height: auto;
+ }
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.spec.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.spec.ts new file mode 100644 index 000000000..8a96b6d8b --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateCatalogComponent } from './create-catalog.component'; + +describe('CreateCatalogComponent', () => { + let component: CreateCatalogComponent; + let fixture: ComponentFixture<CreateCatalogComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateCatalogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateCatalogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.ts new file mode 100644 index 000000000..91c6f2835 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.component.ts @@ -0,0 +1,114 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Component, OnInit, ViewChild, ɵConsole } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { JsonEditorComponent, JsonEditorOptions } from 'ang-jsoneditor'; +import { Observable } from 'rxjs'; +import { ICatalogState } from 'src/app/common/core/store/models/catalogState.model'; +import { ICatalog } from 'src/app/common/core/store/models/catalog.model'; +import { Store } from '@ngrx/store'; +import { IAppState } from 'src/app/common/core/store/state/app.state'; +import { SetCatalogState } from 'src/app/common/core/store/actions/catalog.action'; +import { CreateCatalogService } from './create-catalog.service'; +import { NotificationHandlerService } from 'src/app/common/core/services/notification-handler.service'; + +@Component({ + selector: 'app-create-catalog', + templateUrl: './create-catalog.component.html', + styleUrls: ['./create-catalog.component.scss'] +}) +export class CreateCatalogComponent implements OnInit { + + CatalogFormData: FormGroup; + @ViewChild(JsonEditorComponent) editor: JsonEditorComponent; + options = new JsonEditorOptions(); + data:any; + derivedFrom: any[] = [{derivedFrom: 'tosca.nodes.Component'},{derivedFrom:'tosca.nodes.VNF'},{derivedFrom:'tosca.nodes.Artifact'},{derivedFrom:'tosca.nodes.ResourceSource'}, {derivedFrom:'tosca.nodes.Workflow'},{derivedFrom:'tosca.nodes.Root'}]; + definitionType: any[] = [{definitionType: 'node_type'}]; + ccState: Observable<ICatalogState>; + catalog: ICatalog; + + constructor(private formBuilder: FormBuilder, private store: Store<IAppState>, private catalogCreateService: CreateCatalogService, private alertService: NotificationHandlerService) { + this.ccState = this.store.select('catalog'); + this.CatalogFormData = this.formBuilder.group({ + Model_Name: ['', Validators.required], + User_id: ['', Validators.required], + _tags: ['', Validators.required], + _type: ['', Validators.required], + Derived_From: ['', Validators.required], + _description : ['', Validators.required] + }); + } + ngOnInit() { + this.options.mode = 'text'; + this.options.modes = [ 'text', 'tree', 'view']; + this.options.statusBar = false; + + this.ccState.subscribe( + catalogdata => { + var catalogState: ICatalogState = { catalog: catalogdata.catalog, isLoadSuccess: catalogdata.isLoadSuccess, isSaveSuccess: catalogdata.isSaveSuccess, isUpdateSuccess: catalogdata.isUpdateSuccess }; + this.catalog = catalogState.catalog; + console.log( this.catalog ); + }); + +// this.catalogCreateService.getDefinition() +// .subscribe(data=>{ +// console.log(data); +// data.forEach(element => { +// this.definitionType.push(element) +// }); +// }, error=>{ +// window.alert('error' + error); +// }) +// +// this.catalogCreateService.getDerivedFrom() +// .subscribe(data=>{ +// console.log(data); +// data.forEach(element => { +// this.derivedFrom.push(element) +// }); +// }, error=>{ +// window.alert('error' + error); +// }) + } + CreateCatalog(){ + this.catalog = Object.assign({}, this.CatalogFormData.value); + this.catalog.definition=this.data; + let catalogState = { + catalog: this.catalog + } + this.store.dispatch(new SetCatalogState(catalogState)); + + this.catalogCreateService.saveCatalog(this.catalog) + .subscribe(response=>{ + this.alertService.success("save success") + }, + error=>{ + this.alertService.error('Error saving resources'); + }) + + } + + onChange($event) { + this.data=JSON.parse($event.srcElement.value); + console.log(this.data); + }; +} diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.module.ts new file mode 100644 index 000000000..e0ae0dc42 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.module.ts @@ -0,0 +1,57 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { CreateCatalogRoutingModule } from './create-catalog-routing.module'; +import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule} from '@angular/material'; +import { MatIconModule } from '@angular/material/icon'; +import { SharedModule } from 'src/app/common/shared/shared.module'; +import { NgJsonEditorModule } from 'ang-jsoneditor'; +import { CreateCatalogService } from './create-catalog.service'; + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + CreateCatalogRoutingModule, + SharedModule, + MatToolbarModule, + MatButtonModule, + MatSidenavModule, + MatIconModule, + MatListModule, + MatGridListModule, + MatCardModule, + MatMenuModule, + MatTableModule, + MatPaginatorModule, + MatSortModule, + MatInputModule, + MatSelectModule, + MatRadioModule, + MatFormFieldModule, + MatStepperModule, + NgJsonEditorModule + ], + providers: [ CreateCatalogService ] +}) + +export class CreateCatalogModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.service.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.service.ts new file mode 100644 index 000000000..fd582cc98 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/create-catalog/create-catalog.service.ts @@ -0,0 +1,44 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { ApiService } from 'src/app/common/core/services/api.service'; +import { ControllerCatalogURLs } from 'src/app/common/constants/app-constants'; + +@Injectable() +export class CreateCatalogService { + + + constructor(private _http: HttpClient, private api: ApiService) { + } + + saveCatalog(catalog) { + return this.api.post(ControllerCatalogURLs.saveControllerCatalog, catalog); + } + + getDefinition() { + return this.api.get(ControllerCatalogURLs.getDefinition); + } + getDerivedFrom() { + return this.api.get(ControllerCatalogURLs.getDerivedFrom); + } +} + diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog-routing.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog-routing.module.ts new file mode 100644 index 000000000..1785ef86c --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog-routing.module.ts @@ -0,0 +1,35 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { SearchCatalogComponent } from './search-catalog.component'; + +const routes: Routes = [ + { + path: '', + component: SearchCatalogComponent + } +]; +@NgModule({ +imports: [RouterModule.forChild(routes)], +exports: [RouterModule] +}) +export class SearchCatalogRoutingModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html new file mode 100644 index 000000000..47813829d --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.html @@ -0,0 +1,41 @@ +<!-- /* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/--> +<form class="search-form" [formGroup]="myControl"> + <mat-form-field class="search-full-width"> + <input matInput type="text" [(ngModel)]="searchText" placeholder="Search Resources" formControlName="search_input"> + <button matSuffix mat-icon-button (click)="fetchCatalogByName()"> + <mat-icon>search</mat-icon> + </button> + </mat-form-field> +</form> +<div class="searchcontainer"> + <div class="flexBox"> + <div *ngFor="let option of options" style="position: relative !important;width:20% !important"> + <mat-card class="example-card"> + <mat-card-content class="card-content"> + {{option.modelName}} + </mat-card-content> + <mat-card-actions class="flexBox"> + <button matStepperNext mat-menu-item (click)="editInfo(option.blueprintModel.artifactName,option.blueprintModel.artifactVersion,3)">Info</button> + </mat-card-actions> + </mat-card> + </div> + </div> +</div>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss new file mode 100644 index 000000000..a24aebed0 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.scss @@ -0,0 +1,78 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
+
+.example-card {
+ // min-width: 300px;
+ max-height: 200px;
+ background-color: #ebebeb;
+ position: relative;
+ width: 250px;
+ margin: 5px;
+}
+
+.mat-grid-tile {
+ position: absolute;
+ width: 240px !important;
+}
+
+.mat-grid-list div {
+ position: relative;
+}
+
+button.mat-menu-item {
+ width: auto;
+ float: left;
+ border-radius: 4px;
+ background-color: #3f51b5;
+ margin: 5px;
+ cursor: pointer;
+ color: white;
+}
+
+.flexBox {
+ display: flex;
+ flex-flow: row;
+ flex-wrap: wrap;
+}
+
+.card-deck-container {
+ position: relative;
+ border-radius: 1px;
+ padding: 2px;
+ margin: 2px;
+ // background-color: #f5f5f5;
+}
+
+.searchcontainer {
+ // min-height: 300px;
+ overflow-x: hidden;
+ overflow-y: scroll;
+}
+
+.card-content {
+ text-align: center;
+ margin: 5px;
+}
+
+.mat-card-actions {
+ margin-left: 0px !important;
+ margin-right: 0px !important;
+ padding: 0px 0 !important;
+}
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.spec.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.spec.ts new file mode 100644 index 000000000..661246ebb --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchCatalogComponent } from './search-catalog.component'; + +describe('SearchCatalogComponent', () => { + let component: SearchCatalogComponent; + let fixture: ComponentFixture<SearchCatalogComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchCatalogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchCatalogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts new file mode 100644 index 000000000..b30fc3a78 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.component.ts @@ -0,0 +1,58 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { SearchCatalogService } from './search-catalog.service'; +import { MatAutocompleteTrigger } from '@angular/material'; + +@Component({ + selector: 'app-search-catalog', + templateUrl: './search-catalog.component.html', + styleUrls: ['./search-catalog.component.scss'] +}) +export class SearchCatalogComponent implements OnInit { + myControl: FormGroup; + searchText: string = ''; + options: any[] = []; + @ViewChild('catalogSelect', { read: MatAutocompleteTrigger }) catalogSelect: MatAutocompleteTrigger; + constructor(private _formBuilder: FormBuilder, private searchCatalogService: SearchCatalogService) { } + + ngOnInit() { + this.myControl = this._formBuilder.group({ + search_input: ['', Validators.required] + }); + } + fetchCatalogByName() { + this.searchCatalogService.searchByTags(this.searchText) + .subscribe(data=>{ + console.log(data); + data.forEach(element => { + this.options.push(element) + }); + this.catalogSelect.openPanel(); + }, error=>{ + window.alert('Catalog not matching the search tag' + error); + }) + } + + editInfo(artifactName: string, artifactVersion: string, option: string) { + } +} diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts new file mode 100644 index 000000000..2aa1a509e --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.module.ts @@ -0,0 +1,58 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SearchCatalogRoutingModule } from './search-catalog-routing.module'; +import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule, MatAutocompleteModule} from '@angular/material'; +import { MatIconModule } from '@angular/material/icon'; +import { SharedModule } from 'src/app/common/shared/shared.module'; +import { FormsModule,ReactiveFormsModule } from '@angular/forms'; +import { SearchCatalogService } from './search-catalog.service'; + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + SearchCatalogRoutingModule, + FormsModule, + ReactiveFormsModule, + SharedModule, + MatToolbarModule, + MatButtonModule, + MatSidenavModule, + MatIconModule, + MatListModule, + MatGridListModule, + MatCardModule, + MatMenuModule, + MatTableModule, + MatPaginatorModule, + MatSortModule, + MatInputModule, + MatSelectModule, + MatRadioModule, + MatFormFieldModule, + MatStepperModule, + MatAutocompleteModule + ], + providers: [ SearchCatalogService ] +}) +export class SearchCatalogModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts new file mode 100644 index 000000000..47896058a --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/search-catalog/search-catalog.service.ts @@ -0,0 +1,36 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable, observable } from 'rxjs'; +import { ControllerCatalogURLs } from 'src/app/common/constants/app-constants'; +import { ApiService } from 'src/app/common/core/services/api.service'; + +@Injectable() +export class SearchCatalogService { + + constructor(private _http: HttpClient, private api: ApiService) { + } + + searchByTags(tag) { + return this.api.get(ControllerCatalogURLs.searchControllerCatalogByTags + '/' + tag); + } +} diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template-routing.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template-routing.module.ts new file mode 100644 index 000000000..0da5b1661 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template-routing.module.ts @@ -0,0 +1,38 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { SelectTemplateComponent } from './select-template.component'; +import { TemplateOptionsComponent } from './template-options/template-options.component'; + +const routes: Routes = [ + { + path: '', + component: SelectTemplateComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) + +export class SelectTemplateRoutingModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.html new file mode 100644 index 000000000..8a51b4e09 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.html @@ -0,0 +1,33 @@ +<!--/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/--> + +<mat-card class="ver-card"> +<mat-card-header> +</mat-card-header> +<mat-card-content> +<mat-vertical-stepper linear> + <mat-step [stepControl]="step1FormGroup"> + <ng-template matStepLabel>Choose Option</ng-template> + <br> + <app-template-options (option)="selectedOption($event)"></app-template-options> + </mat-step> + </mat-vertical-stepper> + </mat-card-content> +</mat-card>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.scss new file mode 100644 index 000000000..62b6f5d03 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.scss @@ -0,0 +1,52 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
+.matStepNextBtn{
+ color:white;
+ background:#3f51b5;
+ margin-top: 10px;
+ position: absolute;
+ border-radius: 4px;
+}
+.ver-card {
+ width: 100%;
+ background-color: #f1f1f1;
+ padding: 0.01em 16px;
+ margin: 20px 0;
+ box-shadow: 0 2px 2px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)!important;
+ height: auto;
+}
+.mat-card-header{
+ height:35px;
+}
+.mat-card-content{
+ width: auto;
+ background-color: #fff;
+ padding: 8px 8px;
+ // border-left: 4px solid #4CAF50;
+ word-wrap: break-word;
+ min-height:350px;
+ height: auto;
+}
+.success{
+color:green;
+}
+.comp-disabled {
+ display: none;
+}
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.spec.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.spec.ts new file mode 100644 index 000000000..c0c7b50fb --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SelectTemplateComponent } from './select-template.component'; + +describe('SelectTemplateComponent', () => { + let component: SelectTemplateComponent; + let fixture: ComponentFixture<SelectTemplateComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SelectTemplateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SelectTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.ts new file mode 100644 index 000000000..ed44e0cf4 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.component.ts @@ -0,0 +1,43 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'app-select-template', + templateUrl: './select-template.component.html', + styleUrls: ['./select-template.component.scss'] +}) +export class SelectTemplateComponent implements OnInit { + + selectedValue: any; + @Output() option = new EventEmitter(); + + constructor() { } + + ngOnInit() { + } + + selectedOption(value){ + this.selectedValue=value; + this.option.emit(value); + } + +} diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.module.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.module.ts new file mode 100644 index 000000000..8853b5bd2 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/select-template.module.ts @@ -0,0 +1,71 @@ +/* +* ============LICENSE_START======================================================= +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { TemplateOptionsComponent } from './template-options/template-options.component'; +import { SelectTemplateComponent } from './select-template.component'; +import { SelectTemplateRoutingModule } from './select-template-routing.module'; +import { AppMaterialModule } from 'src/app/common/modules/app-material.module'; +import { MatAutocompleteModule,MatToolbarModule,MatIconModule, MatButtonModule, MatSidenavModule, MatCheckboxModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule} from '@angular/material'; +import { SharedModule } from '../../../../app/common/shared/shared.module'; +import { FormsModule,ReactiveFormsModule } from '@angular/forms'; + +@NgModule({ + declarations: [ + TemplateOptionsComponent, + SelectTemplateComponent + ], + exports: [ + TemplateOptionsComponent, + SelectTemplateComponent + ], + imports: [ + CommonModule, + SelectTemplateRoutingModule, + ReactiveFormsModule, + AppMaterialModule, + FormsModule, + ReactiveFormsModule, + MatToolbarModule, + MatIconModule, + MatButtonModule, + MatSidenavModule, + MatCheckboxModule, + MatListModule, + MatGridListModule, + MatCardModule, + MatMenuModule, + MatTableModule, + MatPaginatorModule, + MatSortModule, + MatInputModule, + MatSelectModule, + MatRadioModule, + MatFormFieldModule, + MatStepperModule, + MatAutocompleteModule + ], + providers: [ + ] +}) +export class SelectTemplateModule { } diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.html b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.html new file mode 100644 index 000000000..185a112e4 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.html @@ -0,0 +1,24 @@ +<!--/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/--> + +<mat-radio-group> + <mat-radio-button value="1" (click)="selected(1)">Create New Catalog</mat-radio-button><br><br> + <mat-radio-button value="2" (click)="selected(2)">Search existing catalog</mat-radio-button><br><br> +</mat-radio-group>
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.scss b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.scss new file mode 100644 index 000000000..d0f182d40 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.scss @@ -0,0 +1,19 @@ +/*
+* ============LICENSE_START=======================================================
+* ONAP : CDS
+* ================================================================================
+* Copyright (C) 2019 TechMahindra
+*=================================================================================
+* 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.
+* ============LICENSE_END=========================================================
+*/
\ No newline at end of file diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.spec.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.spec.ts new file mode 100644 index 000000000..03e799838 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.spec.ts @@ -0,0 +1,45 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateOptionsComponent } from './template-options.component'; + +describe('TemplateOptionsComponent', () => { + let component: TemplateOptionsComponent; + let fixture: ComponentFixture<TemplateOptionsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TemplateOptionsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TemplateOptionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.ts b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.ts new file mode 100644 index 000000000..dc9513bc9 --- /dev/null +++ b/cds-ui/client/src/app/feature-modules/controller-catalog/select-template/template-options/template-options.component.ts @@ -0,0 +1,40 @@ +/* +* ============LICENSE_START======================================================= +* ONAP : CDS +* ================================================================================ +* Copyright (C) 2019 TechMahindra +*================================================================================= +* 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. +* ============LICENSE_END========================================================= +*/ + +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'app-template-options', + templateUrl: './template-options.component.html', + styleUrls: ['./template-options.component.scss'] +}) +export class TemplateOptionsComponent implements OnInit { + + @Output() option = new EventEmitter(); + + constructor() { } + + ngOnInit() { + } + + selected(value){ + this.option.emit(value); + } +} diff --git a/cds-ui/server/src/config/app-config.ts b/cds-ui/server/src/config/app-config.ts index dcca629f2..a2cebe59d 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 appConfig = Object.freeze({ }) }); -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 c73f7a6f8..789589837 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 { BlueprintService } from '../services'; 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 @@ export class BlueprintRestController { } 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 @@ export class BlueprintRestController { } 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 1188d9bcf..85e0aa342 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 @@ export default { { "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 9f9d754d1..f839bb225 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 @@ export default { { "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 @@ export default { { "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 @@ export default { { "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 @@ export default { { "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 @@ export default { { "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 @@ export default { { "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/vLB/Definitions/data_types.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json index 346bc4b2c..b3d719faa 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/data_types.json @@ -144,7 +144,6 @@ "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "", "entry_schema" : { "type" : "" } @@ -293,6 +292,16 @@ "type" : "" } }, + "flavor_name" : { + "description" : "", + "required" : false, + "type" : "string", + "status" : "", + "constraints" : [ { } ], + "entry_schema" : { + "type" : "" + } + }, "dcae_collector_ip" : { "description" : "", "required" : false, @@ -497,7 +506,6 @@ "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "", "entry_schema" : { "type" : "" } @@ -523,13 +531,13 @@ "type" : "" } }, - "vf_module_name" : { + "vf-module-name" : { "description" : "", "required" : false, "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "${vf_module_name}", + "default" : "${vf-module-name}", "entry_schema" : { "type" : "" } @@ -551,7 +559,6 @@ "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "m1.medium", "entry_schema" : { "type" : "" } @@ -593,7 +600,6 @@ "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "m1.medium", "entry_schema" : { "type" : "" } @@ -624,7 +630,6 @@ "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "", "entry_schema" : { "type" : "" } @@ -708,7 +713,6 @@ "type" : "string", "status" : "", "constraints" : [ { } ], - "default" : "", "entry_schema" : { "type" : "" } diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/node_types.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/node_types.json index 7a44860e2..e3f915e33 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/node_types.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/node_types.json @@ -3,6 +3,12 @@ "component-netconf-executor" : { "description" : "This is Netconf Transaction Configuration Component API", "version" : "1.0.0", + "attributes" : { + "response-data" : { + "required" : false, + "type" : "json" + } + }, "capabilities" : { "component-node" : { "type" : "tosca.capabilities.Node" @@ -90,6 +96,12 @@ "required" : false, "type" : "string" }, + "occurrence" : { + "description" : "Number of time to perform the resolution.", + "required" : false, + "type" : "integer", + "default" : 1 + }, "store-result" : { "description" : "Whether or not to store the output.", "required" : false, @@ -200,18 +212,6 @@ }, "derived_from" : "tosca.nodes.ResourceSource" }, - "source-default" : { - "description" : "This is Default Resource Source Node Type", - "version" : "1.0.0", - "properties" : { }, - "derived_from" : "tosca.nodes.ResourceSource" - }, - "source-input" : { - "description" : "This is Input Resource Source Node Type", - "version" : "1.0.0", - "properties" : { }, - "derived_from" : "tosca.nodes.ResourceSource" - }, "source-db" : { "description" : "This is Database Resource Source Node Type", "version" : "1.0.0", @@ -256,6 +256,18 @@ }, "derived_from" : "tosca.nodes.ResourceSource" }, + "source-default" : { + "description" : "This is Default Resource Source Node Type", + "version" : "1.0.0", + "properties" : { }, + "derived_from" : "tosca.nodes.ResourceSource" + }, + "source-input" : { + "description" : "This is Input Resource Source Node Type", + "version" : "1.0.0", + "properties" : { }, + "derived_from" : "tosca.nodes.ResourceSource" + }, "source-rest" : { "description" : "This is Rest Resource Source Node Type", "version" : "1.0.0", @@ -387,4 +399,4 @@ "derived_from" : "tosca.nodes.Vnf" } } -} +}
\ 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 ef1c5e24f..aa49e1ee9 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 @@ -75,7 +75,7 @@ "key-dependencies" : [ "vf-module-id", "service-instance-id", "vnf-id" ] } }, - "aai-data" : { + "primary-aai-data" : { "type" : "source-rest", "properties" : { "verb" : "PATCH", @@ -197,6 +197,41 @@ } } }, + "flavor_name" : { + "tags" : "flavor_name", + "name" : "flavor_name", + "property" : { + "description" : "flavor_name", + "type" : "string" + }, + "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>", + "sources" : { + "input" : { + "type" : "source-input" + }, + "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/flavor_name", + "path" : "/param/0/value", + "input-key-mapping" : { + "service-instance-id" : "service-instance-id", + "vnf-id" : "vnf-id" + }, + "output-key-mapping" : { + "flavor_name" : "value" + }, + "key-dependencies" : [ "service-instance-id", "vnf-id" ] + } + } + } + }, "gre_ipaddr" : { "tags" : "gre_ipaddr", "name" : "gre_ipaddr", @@ -1076,7 +1111,7 @@ "any-db" : { "type" : "source-db", "properties" : { - "query" : "SELECT artifact_name FROM BLUEPRINT_MODEL where artifact_version=\"1.0.0\"", + "query" : "SELECT artifact_name FROM BLUEPRINT_RUNTIME where artifact_version=\"1.0.0\"", "input-key-mapping" : { }, "output-key-mapping" : { "service-instance-id" : "artifact_name" @@ -1086,7 +1121,7 @@ "processor-db" : { "type" : "source-db", "properties" : { - "query" : "SELECT artifact_name FROM BLUEPRINT_MODEL where artifact_version=\"1.0.0\"", + "query" : "SELECT artifact_name FROM BLUEPRINT_RUNTIME where artifact_version=\"1.0.0\"", "input-key-mapping" : { }, "output-key-mapping" : { "service-instance-id" : "artifact_name" @@ -1103,41 +1138,6 @@ } } }, - "vdns_flavor_name" : { - "tags" : "vdns_flavor_name", - "name" : "vdns_flavor_name", - "property" : { - "description" : "vdns_flavor_name", - "type" : "string" - }, - "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources" : { - "input" : { - "type" : "source-input" - }, - "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/vdns_flavor_name", - "path" : "/param/0/value", - "input-key-mapping" : { - "service-instance-id" : "service-instance-id", - "vnf-id" : "vnf-id" - }, - "output-key-mapping" : { - "vdns_flavor_name" : "value" - }, - "key-dependencies" : [ "service-instance-id", "vnf-id" ] - } - } - } - }, "vdns_int_private_ip_0" : { "tags" : "vdns_int_private_ip_0", "name" : "vdns_int_private_ip_0", @@ -1275,7 +1275,7 @@ "key-dependencies" : [ "service-instance-id", "vnf-id" ] } }, - "aai-data" : { + "primary-aai-data" : { "type" : "source-rest", "properties" : { "verb" : "GET", @@ -1439,11 +1439,11 @@ } } }, - "vf_module_name" : { - "tags" : "vf_module_name", - "name" : "vf_module_name", + "vf-module-name" : { + "tags" : "vf-module-name", + "name" : "vf-module-name", "property" : { - "description" : "vf_module_name", + "description" : "vf-module-name", "type" : "string" }, "updated-by" : "Singal, Kapil <ks220y@att.com>", @@ -1525,41 +1525,6 @@ } } }, - "vlb_flavor_name" : { - "tags" : "vlb_flavor_name", - "name" : "vlb_flavor_name", - "property" : { - "description" : "vlb_flavor_name", - "type" : "string" - }, - "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources" : { - "input" : { - "type" : "source-input" - }, - "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/vlb_flavor_name", - "path" : "/param/0/value", - "input-key-mapping" : { - "service-instance-id" : "service-instance-id", - "vnf-id" : "vnf-id" - }, - "output-key-mapping" : { - "vlb_flavor_name" : "value" - }, - "key-dependencies" : [ "service-instance-id", "vnf-id" ] - } - } - } - }, "vlb_int_pktgen_private_ip_0" : { "tags" : "vlb_int_pktgen_private_ip_0", "name" : "vlb_int_pktgen_private_ip_0", @@ -1716,18 +1681,6 @@ "type" : "source-default", "properties" : { } }, - "processor-db" : { - "type" : "source-db", - "properties" : { - "endpoint-selector" : "dynamic-db-source", - "type" : "SQL", - "query" : "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private1\"", - "input-key-mapping" : { }, - "output-key-mapping" : { - "vlb_private_net_cidr" : "prefix" - } - } - }, "sdnc" : { "type" : "source-rest", "properties" : { @@ -1744,6 +1697,18 @@ }, "key-dependencies" : [ "service-instance-id", "vnf-id" ] } + }, + "processor-db" : { + "type" : "source-db", + "properties" : { + "endpoint-selector" : "dynamic-db-source", + "type" : "SQL", + "query" : "select sdnctl.IPAM_IP_POOL.prefix as prefix from sdnctl.IPAM_IP_POOL where description = \"private1\"", + "input-key-mapping" : { }, + "output-key-mapping" : { + "vlb_private_net_cidr" : "prefix" + } + } } } }, @@ -1917,51 +1882,16 @@ "processor-db" : { "type" : "source-db", "properties" : { - "endpoint-selector" : "dynamic-db-source", "type" : "SQL", "query" : "select VFC_MODEL.version as vnfc_model_version from VFC_MODEL where customization_uuid=:vfccustomizationuuid", - "input-key-mapping" : { - "vfccustomizationuuid" : "vfccustomizationuuid" - }, "output-key-mapping" : { "vnfc-model-version" : "vnfc_model_version" }, - "key-dependencies" : [ "vfccustomizationuuid" ] - } - } - } - }, - "vpg_flavor_name" : { - "tags" : "vpg_flavor_name", - "name" : "vpg_flavor_name", - "property" : { - "description" : "vpg_flavor_name", - "type" : "string" - }, - "updated-by" : "MALAKOV, YURIY <yuriy.malakov@att.com>", - "sources" : { - "input" : { - "type" : "source-input" - }, - "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/vpg_flavor_name", - "path" : "/param/0/value", + "endpoint-selector" : "dynamic-db-source", "input-key-mapping" : { - "service-instance-id" : "service-instance-id", - "vnf-id" : "vnf-id" - }, - "output-key-mapping" : { - "vpg_flavor_name" : "value" + "vfccustomizationuuid" : "vfccustomizationuuid" }, - "key-dependencies" : [ "service-instance-id", "vnf-id" ] + "key-dependencies" : [ "vfccustomizationuuid" ] } } } @@ -2071,4 +2001,4 @@ } } } -} +}
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/vDNS-CDS.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/vLB_CDS.json index fa9f69f37..9b03a5ef3 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/vDNS-CDS.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Definitions/vLB_CDS.json @@ -4,7 +4,7 @@ "template_author" : "Abdelmuhaimen Seaudi", "author-email" : "abdelmuhaimen.seaudi@orange.com", "user-groups" : "ADMIN, OPERATION", - "template_name" : "test", + "template_name" : "vLB_CDS", "template_version" : "1.0.0", "template_tags" : "test, vDNS-CDS, SCALE-OUT, MARCO" }, @@ -167,13 +167,13 @@ "type" : "artifact-mapping-resource", "file" : "Templates/vdns-mapping.json" }, - "vdns-vnf-template" : { + "vnf-template" : { "type" : "artifact-template-velocity", - "file" : "Templates/vdns-vnf-template.vtl" + "file" : "Templates/vnf-template.vtl" }, - "vdns-vnf-mapping" : { + "vnf-mapping" : { "type" : "artifact-mapping-resource", - "file" : "Templates/vdns-vnf-mapping.json" + "file" : "Templates/vnf-mapping.json" }, "vlb-template" : { "type" : "artifact-template-velocity", diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Plans/CONFIG_ConfigDeploy.xml b/components/model-catalog/blueprint-model/service-blueprint/vLB/Plans/CONFIG_ConfigDeploy.xml index 519aecf4d..92fb2aa48 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Plans/CONFIG_ConfigDeploy.xml +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Plans/CONFIG_ConfigDeploy.xml @@ -1,27 +1,27 @@ -<service-logic - xmlns='http://www.onap.org/sdnc/svclogic' - xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' - xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='CONFIG' version='1.0.0'> - <method rpc='ConfigDeploy' mode='sync'> - <block atomic="true"> - <execute plugin="nf-account-collection" method="process"> - <outcome value='failure'> - <return status="failure"> - </return> - </outcome> - <outcome value='success'> - <execute plugin="execute" method="process"> - <outcome value='failure'> - <return status="failure"> - </return> - </outcome> - <outcome value='success'> - <return status='success'> - </return> - </outcome> - </execute> - </outcome> - </execute> - </block> - </method> +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='CONFIG' version='1.0.0'>
+ <method rpc='ConfigDeploy' mode='sync'>
+ <block atomic="true">
+ <execute plugin="nf-account-collection" method="process">
+ <outcome value='failure'>
+ <return status="failure">
+ </return>
+ </outcome>
+ <outcome value='success'>
+ <execute plugin="execute" method="process">
+ <outcome value='failure'>
+ <return status="failure">
+ </return>
+ </outcome>
+ <outcome value='success'>
+ <return status='success'>
+ </return>
+ </outcome>
+ </execute>
+ </outcome>
+ </execute>
+ </block>
+ </method>
</service-logic>
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py b/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py index 04ea82ea9..34fd1404d 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Scripts/python/ConfigDeploy.py @@ -1,54 +1,54 @@ -# Copyright (c) 2019 Bell Canada. -# -# 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. - -import netconf_constant -from common import ResolutionHelper -from time import sleep -from netconfclient import NetconfClient -from org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor import \ - NetconfComponentFunction - - -class ConfigDeploy(NetconfComponentFunction): - - def process(self, execution_request): - log = globals()[netconf_constant.SERVICE_LOG] - print(globals()) - print("Waiting 4 minutes until NETCONF server is UP on vLB ...") - sleep (240) - nc = NetconfClient(log, self, "netconf-connection") - rr = ResolutionHelper(self) - - # Get meshed template from DB - resolution_key = self.getDynamicProperties("resolution-key").asText() - payloadHostname = rr.retrieve_resolved_template_from_database(resolution_key, "baseconfig") - payloadInterface = rr.retrieve_resolved_template_from_database(resolution_key, "incremental-config") - - nc.connect() - nc.lock() - #if not response.isSuccess(): - # og.error(response.errorMessage) - nc.discard_change() - nc.edit_config(message_content=payloadInterface, edit_default_peration="none") - nc.edit_config(message_content=payloadHostname, edit_default_peration="none") - nc.validate() - nc.commit() - #nc.commit(confirmed = True, confirm_timeout=15) - nc.unlock() - nc.disconnect() - - def recover(self, runtime_exception, execution_request): - log.error("Exception in the script {}", runtime_exception) - print self.addError(runtime_exception.cause.message) +# Copyright (c) 2019 Bell Canada.
+#
+# 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.
+
+import netconf_constant
+from common import ResolutionHelper
+from time import sleep
+from netconfclient import NetconfClient
+from org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor import \
+ NetconfComponentFunction
+
+
+class ConfigDeploy(NetconfComponentFunction):
+
+ def process(self, execution_request):
+ log = globals()[netconf_constant.SERVICE_LOG]
+ print(globals())
+# print("Waiting 4 minutes until NETCONF server is UP on vLB ...")
+# sleep (240)
+ nc = NetconfClient(log, self, "netconf-connection")
+ rr = ResolutionHelper(self)
+
+ # Get meshed template from DB
+ resolution_key = self.getDynamicProperties("resolution-key").asText()
+ payloadHostname = rr.retrieve_resolved_template_from_database(resolution_key, "baseconfig")
+ payloadInterface = rr.retrieve_resolved_template_from_database(resolution_key, "incremental-config")
+
+ nc.connect()
+ nc.lock()
+ #if not response.isSuccess():
+ # og.error(response.errorMessage)
+ nc.discard_change()
+ nc.edit_config(message_content=payloadInterface, edit_default_peration="none")
+ nc.edit_config(message_content=payloadHostname, edit_default_peration="none")
+ nc.validate()
+ nc.commit()
+ #nc.commit(confirmed = True, confirm_timeout=15)
+ nc.unlock()
+ nc.disconnect()
+
+ def recover(self, runtime_exception, execution_request):
+ log.error("Exception in the script {}", runtime_exception)
+ print self.addError(runtime_exception.cause.message)
return None
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/service-blueprint/vLB/TOSCA-Metadata/TOSCA.meta index ea1a90340..37c59ee56 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/TOSCA-Metadata/TOSCA.meta +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/TOSCA-Metadata/TOSCA.meta @@ -1,6 +1,6 @@ TOSCA-Meta-File-Version: 1.0.0 CSAR-Version: 1.0 Created-By: PLATANIA, MARCO <platania@research.att.com> -Entry-Definitions: Definitions/vDNS-CDS.json +Entry-Definitions: Definitions/vLB_CDS.json Template-Tags: vDNS-CDS-test1 Content-Type: application/vnd.oasis.bpmn
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-mapping.json index 62d1b966b..43b0f9dd0 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-mapping.json @@ -20,7 +20,7 @@ "version": 0 }, { - "name": "vf_module_name", + "name": "vf-module-name", "property": { "description": "", "required": false, @@ -32,10 +32,10 @@ "entry_schema": { "type": "" }, - "default": "${vf_module_name}" + "default": "${vf-module-name}" }, "input-param": false, - "dictionary-name": "vf_module_name", + "dictionary-name": "vf-module-name", "dictionary-source": "default", "dependencies": [], "version": 0 @@ -406,4 +406,4 @@ ], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-template.vtl index 8055030c2..58512be2f 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/base_template-template.vtl @@ -81,15 +81,15 @@ "payload": [ { "param-name": "resource-name", - "param-value": "vf_module_name" + "param-value": "vf-module-name" }, { "param-name": "resource-value", - "param-value": "${vf_module_name}" + "param-value": "${vf-module-name}" }, { "param-name": "external-key", - "param-value": "${vf-module-id}_vf_module_name" + "param-value": "${vf-module-id}_vf-module-name" }, { "param-name": "policy-instance-name", @@ -114,8 +114,8 @@ ], "output-key-mapping": [ { - "resource-name": "vf_module_name", - "resource-value": "${vf_module_name}" + "resource-name": "vf-module-name", + "resource-value": "${vf-module-name}" } ] } diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-mapping.json index 000cbd039..ad12a6cb9 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/baseconfig-mapping.json @@ -110,4 +110,4 @@ ], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-mapping.json index 1aece7315..99218d213 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/incremental-config-mapping.json @@ -110,4 +110,4 @@ ], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/nf-params-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/nf-params-mapping.json index 30004521b..9cf71fc59 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/nf-params-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/nf-params-mapping.json @@ -62,4 +62,4 @@ ], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-mapping.json index cf3099467..2dee19ccb 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-mapping.json @@ -113,7 +113,7 @@ "version": 0 }, { - "name": "vf_module_name", + "name": "vf-module-name", "property": { "description": "", "required": false, @@ -125,10 +125,10 @@ "entry_schema": { "type": "" }, - "default": "${vf_module_name}" + "default": "${vf-module-name}" }, "input-param": false, - "dictionary-name": "vf_module_name", + "dictionary-name": "vf-module-name", "dictionary-source": "default", "dependencies": [], "version": 0 @@ -370,9 +370,12 @@ "default": "m1.medium" }, "input-param": false, - "dictionary-name": "vdns_flavor_name", - "dictionary-source": "default", - "dependencies": [], + "dictionary-name": "flavor_name", + "dictionary-source": "sdnc", + "dependencies": [ + "service-instance-id", + "vnf-id" + ], "version": 0 }, @@ -811,4 +814,4 @@ ], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-template.vtl index 9c493dc45..84fab0d63 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-template.vtl @@ -182,15 +182,15 @@ "payload": [ { "param-name": "resource-name", - "param-value": "vf_module_name" + "param-value": "vf-module-name" }, { "param-name": "resource-value", - "param-value": "${vf_module_name}" + "param-value": "${vf-module-name}" }, { "param-name": "external-key", - "param-value": "${vf-module-id}_vf_module_name" + "param-value": "${vf-module-id}_vf-module-name" }, { "param-name": "policy-instance-name", @@ -215,8 +215,8 @@ ], "output-key-mapping": [ { - "resource-name": "vf_module_name", - "resource-value": "${vf_module_name}" + "resource-name": "vf-module-name", + "resource-value": "${vf-module-name}" } ] } diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-mapping.json index 9e3b693ca..0104579c3 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-mapping.json @@ -21,7 +21,7 @@ "version": 0 }, { - "name": "vf_module_name", + "name": "vf-module-name", "property": { "description": "", "required": false, @@ -33,10 +33,10 @@ "entry_schema": { "type": "" }, - "default": "${vf_module_name}" + "default": "${vf-module-name}" }, "input-param": false, - "dictionary-name": "vf_module_name", + "dictionary-name": "vf-module-name", "dictionary-source": "default", "dependencies": [], "version": 0 @@ -610,13 +610,15 @@ ], "entry_schema": { "type": "" - }, - "default": "m1.medium" - }, + } + }, "input-param": false, - "dictionary-name": "vlb_flavor_name", - "dictionary-source": "default", - "dependencies": [], + "dictionary-name": "flavor_name", + "dictionary-source": "sdnc", + "dependencies": [ + "service-instance-id", + "vnf-id" + ], "version": 0 }, { @@ -924,4 +926,4 @@ "dependencies": [], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-template.vtl index bc495bd2d..458423e6f 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vlb-template.vtl @@ -209,15 +209,15 @@ "payload": [ { "param-name": "resource-name", - "param-value": "vf_module_name" + "param-value": "vf-module-name" }, { "param-name": "resource-value", - "param-value": "${vf_module_name}" + "param-value": "${vf-module-name}" }, { "param-name": "external-key", - "param-value": "${vf-module-id}_vf_module_name" + "param-value": "${vf-module-id}_vf-module-name" }, { "param-name": "policy-instance-name", @@ -242,8 +242,8 @@ ], "output-key-mapping": [ { - "resource-name": "vf_module_name", - "resource-value": "${vf_module_name}" + "resource-name": "vf-module-name", + "resource-value": "${vf-module-name}" } ] } diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-vnf-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vnf-mapping.json index 20e2a2720..82dbe66a2 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-vnf-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vnf-mapping.json @@ -40,6 +40,26 @@ "dependencies": [], "version": 0 }, + { + "name": "flavor_name", + "property": { + "description": "", + "required": false, + "type": "string", + "status": "", + "constraints": [ + {} + ], + "entry_schema": { + "type": "" + } + }, + "input-param": false, + "dictionary-name": "flavor_name", + "dictionary-source": "input", + "dependencies": [], + "version": 0 + }, { "name": "image_name", "property": { diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-vnf-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vnf-template.vtl index ec43a5a4a..0080e2b2d 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vdns-vnf-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vnf-template.vtl @@ -44,6 +44,10 @@ "param-name": "cloud_env", "param-value": "${cloud_env}" }, + { + "param-name": "flavor_name", + "param-value": "${flavor_name}" + }, { "param-name": "install_script_version", "param-value": "${install_script_version}" diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-mapping.json b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-mapping.json index 554d45fc2..25721e299 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-mapping.json +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-mapping.json @@ -21,7 +21,7 @@ "version": 0 }, { - "name": "vf_module_name", + "name": "vf-module-name", "property": { "description": "", "required": false, @@ -33,10 +33,10 @@ "entry_schema": { "type": "" }, - "default": "${vf_module_name}" + "default": "${vf-module-name}" }, "input-param": false, - "dictionary-name": "vf_module_name", + "dictionary-name": "vf-module-name", "dictionary-source": "default", "dependencies": [], "version": 0 @@ -538,13 +538,15 @@ ], "entry_schema": { "type": "" - }, - "default": "m1.medium" + } }, "input-param": false, - "dictionary-name": "vpg_flavor_name", - "dictionary-source": "default", - "dependencies": [], + "dictionary-name": "flavor_name", + "dictionary-source": "sdnc", + "dependencies": [ + "service-instance-id", + "vnf-id" + ], "version": 0 }, { @@ -829,4 +831,4 @@ ], "version": 0 } -] +]
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-template.vtl b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-template.vtl index 98d541d69..bd745b179 100644 --- a/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-template.vtl +++ b/components/model-catalog/blueprint-model/service-blueprint/vLB/Templates/vpkg-template.vtl @@ -175,15 +175,15 @@ "payload": [ { "param-name": "resource-name", - "param-value": "vf_module_name" + "param-value": "vf-module-name" }, { "param-name": "resource-value", - "param-value": "${vf_module_name}" + "param-value": "${vf-module-name}" }, { "param-name": "external-key", - "param-value": "${vf-module-id}_vf_module_name" + "param-value": "${vf-module-id}_vf-module-name" }, { "param-name": "policy-instance-name", @@ -212,8 +212,8 @@ ], "output-key-mapping": [ { - "resource-name": "vf_module_name", - "resource-value": "${vf_module_name}" + "resource-name": "vf-module-name", + "resource-value": "${vf-module-name}" } ] } 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 000000000..5ed5ff450 --- /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 e40ccba09..faabb80e7 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.blueprintArchivePath=blueprints/archive 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 6f917096d..9d2b82f25 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 ab04054fe..1cd8a2af7 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 @@ open class KafkaMessageConsumerProperties : MessageConsumerProperties() { 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 5a9e61bfd..b5d444a49 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 @@ class KafkaBasicAuthMessageConsumerService( 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 @@ class KafkaBasicAuthMessageConsumerService( 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 2b84eaa78..f4e85a94b 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 @@ import kotlin.test.assertTrue "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 @@ open class BlueprintMessageConsumerServiceTest { .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 000000000..cdf6ce195 --- /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 000000000..4da7dcd0e --- /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 4d13486c3..a6bff7051 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 @@ package org.onap.ccsdk.cds.blueprintsprocessor.designer.api 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.ResponseEntity 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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint @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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint @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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint @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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint @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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint @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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint @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 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint 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 4441d2b4b..f14f61e60 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 @@ open class ExecutionServiceController { 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 @@ open class ExecutionServiceController { @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/StreamingRemoteExecutionService.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/StreamingRemoteExecutionService.kt index 07848164e..adb1d67d2 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.fasterxml.jackson.databind.JsonNode 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 @@ import org.springframework.stereotype.Service 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 @@ class StreamingRemoteExecutionServiceImpl(private val bluePrintGrpcLibPropertySe /** - * 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)") + } + } + } + + /** + * 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 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 [requestId], This closes communication channel **/ + /** Cancel the Subscription for the [txId], This closes communication channel **/ @ExperimentalCoroutinesApi - override suspend fun cancelSubscription(requestId: String) { - commChannels[requestId]?.let { + 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 c9ff23573..29d24c6ad 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.common.api.EventType 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 @@ class StreamingRemoteExecutionServiceTest { 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) - val responseFlowsDeferred = arrayListOf<Deferred<*>>() + } + nonInteractiveDeferred.awaitAll() - repeat(1) { count -> + /** Test Send and Receive interactive transaction */ + val responseFlowsDeferred = arrayListOf<Deferred<*>>() + 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/resources/logback-test.xml b/ms/blueprintsprocessor/modules/services/execution-service/src/test/resources/logback-test.xml index 703a52642..afe10b39d 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 000000000..001ec751e --- /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 000000000..2ddb4503d --- /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 6051e04c1..b55636918 100644 --- a/ms/py-executor/requirements.txt +++ b/ms/py-executor/requirements.txt @@ -2,5 +2,4 @@ grpcio==1.23.0 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 |