Merge "GUI for test blueprint"
diff --git a/cds-ui/client/package.json b/cds-ui/client/package.json
index 4ae5b68..158a822 100644
--- a/cds-ui/client/package.json
+++ b/cds-ui/client/package.json
@@ -27,7 +27,9 @@
"@ngrx/router-store": "^6.1.2",
"@ngrx/store": "^6.1.2",
"@ngrx/store-devtools": "^6.1.2",
+ "@types/d3": "^5.7.0",
"core-js": "^2.5.4",
+ "d3": "^5.9.1",
"font-awesome": "^4.7.0",
"hammerjs": "^2.0.8",
"material-design-icons": "^3.0.1",
diff --git a/cds-ui/client/src/app/common/shared/components/home/home.component.ts b/cds-ui/client/src/app/common/shared/components/home/home.component.ts
index d70da85..d5ea7f6 100644
--- a/cds-ui/client/src/app/common/shared/components/home/home.component.ts
+++ b/cds-ui/client/src/app/common/shared/components/home/home.component.ts
@@ -28,7 +28,7 @@
})
export class HomeComponent implements OnInit {
events: string[] = [];
- opened: boolean;
+ opened: boolean = true;
constructor() { }
ngOnInit() {
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/blueprint-routing.module.ts b/cds-ui/client/src/app/feature-modules/blueprint/blueprint-routing.module.ts
index 26ffa12..d0ce0c6 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/blueprint-routing.module.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/blueprint-routing.module.ts
@@ -27,29 +27,7 @@
const routes: Routes = [
{
path: '',
- component: BlueprintComponent,
- children: [
- {
- path: '',
- loadChildren: './select-template/select-template.module#SelectTemplateModule'
- },
- {
- path: 'selectTemplate',
- loadChildren: './select-template/select-template.module#SelectTemplateModule'
- },
- {
- path: 'modifyTemplate',
- loadChildren: './modify-template/modify-template.module#ModifyTemplateModule'
- },
- {
- path: 'testTemplate',
- loadChildren: './test-template/test-template.module#TestTemplateModule'
- },
- {
- path: 'deployTemplate',
- loadChildren: './deploy-template/deploy-template.module#DeployTemplateModule'
- }
- ]
+ component: BlueprintComponent
}
];
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/blueprint.component.html b/cds-ui/client/src/app/feature-modules/blueprint/blueprint.component.html
index 31c7a6a..9a3ba1e 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/blueprint.component.html
+++ b/cds-ui/client/src/app/feature-modules/blueprint/blueprint.component.html
@@ -40,7 +40,7 @@
<app-test-template></app-test-template>
</mat-step>
<mat-step [stepControl]="thirdFormGroup">
- <ng-template matStepLabel>Test</ng-template>
+ <ng-template matStepLabel>Deploy</ng-template>
<app-deploy-template></app-deploy-template>
</mat-step>
</mat-horizontal-stepper>
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.html b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.html
index 74c0fae..b1c8940 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.html
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.html
@@ -18,89 +18,5 @@
limitations under the License.
============LICENSE_END============================================ -->
-
-
-
-<!-- <div style="display: flex; flex-direction: row; height: 100%;width: 100%"> -->
- <div style="display: flex; flex-direction: row; height: 100%;width: 100%">
- <div class="outerDiv divone">
- <mat-accordion>
- <mat-expansion-panel>
- <mat-expansion-panel-header style="background-color: #f1f1f1">
- <mat-panel-title>
- Node types
- </mat-panel-title>
- </mat-expansion-panel-header>
- <div class="flex-container">
- <div>
- Node 1
- </div>
- <div>
- Node 2
- </div>
- <div>
- Node 3
- </div>
- <div>
- Node 4
- </div>
- <div>
-
- </div>
- </mat-expansion-panel>
- <mat-expansion-panel (opened)="panelOpenState = true"
- (closed)="panelOpenState = false">
- <mat-expansion-panel-header style="background-color: #f1f1f1">
- <mat-panel-title>
- Policy
- </mat-panel-title>
- </mat-expansion-panel-header>
- <div class="flex-container">
- <div>
- Node 1
- </div>
- <div>
- Node 2
- </div>
- <div>
- Node 3
- </div>
- <div>
- Node 4
- </div>
- <div>
- Node 3
- </div>
-
- </div>
- </mat-expansion-panel>
- </mat-accordion>
- </div>
- <div class="outerDiv divtwo" (click)="on = !on">
- <canvas class="cnv" height="500"></canvas>
- </div>
- <div *ngIf="on" id="overlay" class="outerDiv divThree">
- <mat-accordion style="width: 100%">
- <mat-expansion-panel>
- <mat-expansion-panel-header style="background-color: #f1f1f1">
- <mat-panel-title>
- Properties
- </mat-panel-title>
- </mat-expansion-panel-header>
- </mat-expansion-panel>
- <mat-expansion-panel (opened)="panelOpenState = true"
- (closed)="panelOpenState = false">
- <mat-expansion-panel-header style="background-color: #f1f1f1">
- <mat-panel-title>
- Interface
- </mat-panel-title>
- </mat-expansion-panel-header>
- </mat-expansion-panel>
- </mat-accordion>
- </div>
- </div>
-
-
-
- <!-- </div> -->
-
\ No newline at end of file
+<svg id="svgArea" width="1000px" height="100%" style="background-color:white">
+</svg>
\ No newline at end of file
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.ts
index 55c7dfb..5e86a7e 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/designer/designer.component.ts
@@ -19,7 +19,9 @@
============LICENSE_END============================================
*/
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
+import * as d3 from 'd3';
+import { text } from 'd3';
@Component({
selector: 'app-designer',
@@ -28,9 +30,219 @@
})
export class DesignerComponent implements OnInit {
- constructor() { }
+ @ViewChild('svgArea') graphContainer: ElementRef;
+ dataForsimulation;
+ svg;
+ svgWidth;
+ svgHeight;
+
+
+ simulation;
+
+ constructor() {
+ this.dataForsimulation = {"nodes" :[],
+ "links": []
+ }
+
+
+ d3.json("../../../../../assets/activation-blueprint.json")
+ .then((data)=>{
+ console.log(data);
+ this.buildD3DataNodes(data);
+ //this.buildD3DataLinks(data);
+ this.drawNode();
+ });
+ }
ngOnInit() {
}
+ ngAfterContentInit() {
+
+ }
+
+ drawNode() {
+ this.svg = d3.select('#svgArea')
+ .style('back-ground-color', 'white');
+
+ this.svgWidth = this.svg._groups[0][0].width.baseVal.value;
+ this.svgHeight = this.svg._groups[0][0].height.baseVal.value;
+
+ console.log('width', this.svgWidth);
+
+ let xbyMath;
+ let ybyMath;
+ let X= 10;
+ let Y=10;
+
+ let transformString = "translate(" + X + "," + Y + ")";
+ this.dataForsimulation.nodes.forEach((d, i)=> {
+ let id= 'g'+i;
+
+ // xbyMath = Math.random() * ( this.svgWidth - 50 - 105 ) + ( 105/2 + 10 );
+ // ybyMath = Math.random() * ( this.svgWidth - 20 - 100 ) + ( 100/2 + 10 );
+
+ xbyMath = Math.floor(Math.random() * ((this.svgWidth-110) - 100 + 1)) + 100;
+ ybyMath = Math.floor(Math.random() * ((this.svgHeight-110) - 100 + 1)) + 100;
+
+ transformString = "translate(" + xbyMath + "," + ybyMath + ")";
+
+ let gEleId = 'g'+i;
+ let nodeTemprectId = gEleId+name
+ let requirement = gEleId+name+'requirement';
+ this.svg.append('g')
+ .attr('id', gEleId);
+
+ let firstg = d3.select('#g'+i)
+ .attr('transform', transformString);
+
+ firstg.append('rect')
+ .attr('id', d.name)
+ .attr("x", 0)
+ .attr("y", 0)
+ .attr("rx", 20)
+ .attr("ry", 20)
+ .attr('width', 100)
+ .attr('height', 100)
+ .attr('fill', 'white')
+ .attr('stroke', 'black')
+ .attr('opacity', 0.6)
+ .on('mouseover', () => this.handleMouseOver());
+
+ d.x = xbyMath;
+ d.y = ybyMath;
+
+ firstg.append('rect')
+ .attr('x', 95)
+ .attr('y', 20)
+ // .attr('r', 10)
+ .attr('width', 10)
+ .attr('height', 10)
+ .attr('fill', 'orange')
+
+ if(d.requirementsArray) {
+ d.requirementsArray.forEach(requirement =>{
+ firstg.append('rect')
+ .attr('id', d.name+requirement.name)
+ .attr('x', 95)
+ .attr('y', 60)
+ // .attr('r', 10)
+ .attr('width', 10)
+ .attr('height', 10)
+ .attr('fill', 'blue')
+ requirement.x = xbyMath + 95;
+ requirement.y = ybyMath + 60;
+ });
+ }
+
+ if(d.capabilitiesArray) {
+ d.capabilitiesArray.forEach(capability =>{
+ firstg.append('rect')
+ .attr('id', d.name+capability.name)
+ .attr('x', 95)
+ .attr('y', 40)
+ // .attr('r', 10)
+ .attr('width', 10)
+ .attr('height', 10)
+ .attr('fill', 'green');
+ capability.x = xbyMath + 95;
+ capability.y = ybyMath + 60;
+ });
+ }
+
+
+ firstg.append('text')
+ .attr('x', 0)
+ .attr('y', 115)
+ .text(d.name);
+
+ // X = X +120;
+ // Y = 10;
+ });
+ this.buildD3DataLinks();
+ }
+
+ buildD3DataNodes(data) {
+ let d3data;
+ d3data = data.topology_template.node_templates;
+ console.log('d3data:', d3data);
+ let finalData = [];
+ for (var property1 in d3data) {
+ d3data[property1].name = property1;
+ this.dataForsimulation.nodes.push(d3data[property1]);
+ finalData.push(d3data[property1]);
+ }
+
+ this.dataForsimulation.nodes.forEach(node => {
+ for( var nodeProperty in node) {
+ if(nodeProperty == 'requirements' || nodeProperty == 'capabilities') {
+ let arrayName = nodeProperty + 'Array';
+ node[arrayName] = [];
+ for(var reqProperty in node[nodeProperty]) {
+ node[nodeProperty][reqProperty].name = reqProperty;
+ node[arrayName].push(node[nodeProperty][reqProperty])
+ }
+
+ console.log('node array:', + node[arrayName]);
+ }
+ }
+ });
+ console.log( this.dataForsimulation);
+
+
+ }
+
+ buildD3DataLinks() {
+ this.dataForsimulation.nodes.forEach((node) => {
+ if(node.requirementsArray && node.requirementsArray.length > 0) {
+ node.requirementsArray.forEach(requirement => {
+ let linkObject = {};
+ linkObject['sourceName'] = node.name + requirement.name;
+ linkObject['sourceid'] = node.name + requirement.name;
+ linkObject['sourceX'] = requirement.x;
+ linkObject['sourceY'] = requirement.y;
+ linkObject['targetNode'] = requirement.node;
+ linkObject['targetCapabilility'] = requirement.capability;
+ linkObject['ele'] = d3.select('#'+ linkObject['sourceid']);
+ this.dataForsimulation.links.push(linkObject);
+ });
+ }
+ });
+
+ this.capabilityTargets();
+ }
+
+ capabilityTargets() {
+ this.dataForsimulation.links.forEach(link=>{
+ this.dataForsimulation.nodes.forEach(node=>{
+ if(node.name == link.targetNode && node.capabilitiesArray) {
+ node.capabilitiesArray.forEach(capability=>{
+ if(capability.name == link.targetCapabilility) {
+ link['targetX'] = capability.x;
+ link['targetY'] = capability.y;
+ }
+ })
+ }
+ });
+ });
+
+ this.drawlink();
+ }
+
+ drawlink() {
+ this.dataForsimulation.links.forEach(link=>{
+ this.svg.append('line')
+ .attr('x1', link.sourceX)
+ .attr('y1', link.sourceY)
+ .attr('x2', link.targetX)
+ .attr('y2', link.targetY)
+ .attr('stroke','gray')
+ .attr('stroke-width', 5);
+ });
+ }
+
+ handleMouseOver() {
+ console.log('mouse over');
+ }
+
}
diff --git a/cds-ui/client/src/assets/activation-blueprint.json b/cds-ui/client/src/assets/activation-blueprint.json
new file mode 100644
index 0000000..822cc68
--- /dev/null
+++ b/cds-ui/client/src/assets/activation-blueprint.json
@@ -0,0 +1,336 @@
+{
+ "metadata": {
+ "template_author": "Brinda Santh Muthuramalingam",
+ "author-email": "brindasanth@in.ibm.com",
+ "user-groups": "ADMIN, OPERATION",
+ "template_name": "baseconfiguration",
+ "template_version": "1.0.0",
+ "template_tags": "brinda, tosca"
+ },
+ "imports": [
+ {
+ "file": "Definitions/data_types.json"
+ },
+ {
+ "file": "Definitions/relationship_types.json"
+ },
+ {
+ "file": "Definitions/artifact_types.json"
+ },
+ {
+ "file": "Definitions/node_types.json"
+ },
+ {
+ "file": "Definitions/policy_types.json"
+ }
+ ],
+ "topology_template": {
+ "inputs": {
+ "request-id": {
+ "required": true,
+ "type": "string"
+ },
+ "action-name": {
+ "required": true,
+ "type": "string"
+ },
+ "scope-type": {
+ "required": true,
+ "type": "string"
+ },
+ "hostname": {
+ "required": true,
+ "type": "string"
+ }
+ },
+ "node_templates": {
+ "resource-assignment-process": {
+ "type": "dg-generic",
+ "properties": {
+ "content": {
+ "get_artifact": [
+ "SELF",
+ "dg-resource-assignment-process"
+ ]
+ },
+ "dependency-node-templates": [
+ "resource-assignment"
+ ]
+ },
+ "artifacts": {
+ "dg-resource-assignment-process": {
+ "type": "artifact-directed-graph",
+ "file": "Plans/CONFIG_ResourceAssignment_1.0.0.xml"
+ }
+ }
+ },
+ "activate-process": {
+ "type": "dg-generic",
+ "properties": {
+ "content": {
+ "get_artifact": [
+ "SELF",
+ "dg-activate-process"
+ ]
+ },
+ "dependency-node-templates": [
+ "activate-jython"
+ ]
+ },
+ "artifacts": {
+ "dg-activate-process": {
+ "type": "artifact-directed-graph",
+ "file": "Plans/CONFIG_ActivateNetconf_1.0.0.xml"
+ }
+ }
+ },
+ "assign-activate-process": {
+ "type": "dg-generic",
+ "properties": {
+ "content": {
+ "get_artifact": [
+ "SELF",
+ "dg-assign-activate-process"
+ ]
+ },
+ "dependency-node-templates": [
+ "resource-assignment",
+ "activate-jython"
+ ]
+ },
+ "artifacts": {
+ "dg-assign-activate-process": {
+ "type": "artifact-directed-graph",
+ "file": "Plans/CONFIG_AssignActivateNetconf_1.0.0.xml"
+ }
+ }
+ },
+ "resource-assignment": {
+ "type": "component-resource-assignment",
+ "interfaces": {
+ "ResourceAssignmentComponent": {
+ "operations": {
+ "process": {
+ "inputs": {
+ "action-name": {
+ "get_input": "action-name"
+ },
+ "resource-type": "vnf-type",
+ "request-id": {
+ "get_input": "request-id"
+ },
+ "resource-id": {
+ "get_input": "hostname"
+ },
+ "artifact-prefix-names": [
+ "baseconfig"
+ ]
+ },
+ "outputs": {
+ "resource-assignment-params": {
+ "get_attribute": [
+ "SELF",
+ "assignment-params"
+ ]
+ },
+ "status": "success"
+ }
+ }
+ }
+ }
+ },
+ "artifacts": {
+ "baseconfig-template": {
+ "type": "artifact-template-velocity",
+ "file": "Templates/baseconfig-template.vtl"
+ },
+ "baseconfig-mapping": {
+ "type": "artifact-mapping-resource",
+ "file": "Definitions/baseconfig-mapping.json"
+ }
+ }
+ },
+ "resource-assignment-py": {
+ "type": "component-resource-assignment",
+ "interfaces": {
+ "ResourceAssignmentComponent": {
+ "operations": {
+ "process": {
+ "implementation": {
+ "primary": "component-script"
+ },
+ "inputs": {
+ "action-name": {
+ "get_input": "action-name"
+ }
+ },
+ "outputs": {
+ "resource-assignment-params": "",
+ "status": ""
+ }
+ }
+ }
+ }
+ },
+ "artifacts": {
+ "component-script": {
+ "type": "artifact-script-jython",
+ "file": "Scripts/python/SamplePythonComponentNode.py"
+ }
+ }
+ },
+ "activate-jython": {
+ "type": "component-jython-executor",
+ "interfaces": {
+ "JythonExecutorComponent": {
+ "operations": {
+ "process": {
+ "implementation": {
+ "primary": "component-script"
+ },
+ "inputs": {
+ "instance-dependencies": [
+ "json-parser-service",
+ "netconf-rpc-service"
+ ]
+ },
+ "outputs": {
+ "response-data": "",
+ "status": ""
+ }
+ }
+ }
+ }
+ },
+ "artifacts": {
+ "component-script": {
+ "type": "artifact-script-jython",
+ "file": "Scripts/python/SamplePythonComponentNode.py"
+ }
+ }
+ },
+ "activate-netconf": {
+ "type": "component-netconf-executor",
+ "interfaces": {
+ "NetconfExecutorComponent": {
+ "operations": {
+ "process": {
+ "implementation": {
+ "primary": "component-script"
+ },
+ "inputs": {
+ "instance-dependencies": [
+ "json-parser-service",
+ "netconf-rpc-service"
+ ]
+ },
+ "outputs": {
+ "response-data": "",
+ "status": ""
+ }
+ }
+ }
+ }
+ },
+ "requirements": {
+ "netconf-connection": {
+ "capability": "netconf",
+ "node": "sample-netconf-device",
+ "relationship": "tosca.relationships.ConnectsTo"
+ }
+ },
+ "artifacts": {
+ "component-script": {
+ "type": "artifact-script-jython",
+ "file": "Scripts/python/DefaultGetNetConfig.py"
+ }
+ }
+ },
+ "sample-netconf-device": {
+ "type": "vnf-netconf-device",
+ "capabilities": {
+ "netconf": {
+ "properties": {
+ "login-key": "sample-key",
+ "login-account": "sample-account",
+ "target-ip-address": "localhost",
+ "port-number": 830,
+ "connection-time-out": 30
+ }
+ }
+ }
+ }
+ },
+ "workflows": {
+ "resource-assignment": {
+ "inputs": {
+ "resource-assignment-properties": {
+ "required": true,
+ "type": "dt-resource-assignment-properties"
+ }
+ },
+ "steps": {
+ "call-resource-assignment": {
+ "description": "Resource Assignment Workflow",
+ "target": "resource-assignment-process",
+ "activities": [
+ {
+ "call_operation": "CONFIG.ResourceAssignment"
+ }
+ ]
+ }
+ }
+ },
+ "activate": {
+ "inputs": {
+ "request-id": {
+ "required": true,
+ "type": "string"
+ },
+ "action-name": {
+ "required": true,
+ "type": "string"
+ },
+ "scope-type": {
+ "required": true,
+ "type": "string"
+ },
+ "hostname": {
+ "required": true,
+ "type": "string"
+ }
+ },
+ "steps": {
+ "activate-process": {
+ "description": "Netconf Activation Workflow",
+ "target": "activate-process",
+ "activities": [
+ {
+ "call_operation": "CONFIG.ActivateProcess"
+ }
+ ]
+ }
+ }
+ },
+ "assign-activate": {
+ "inputs": {
+ "assign-activate-properties": {
+ "required": true,
+ "type": "dt-assign-activate-properties"
+ }
+ },
+ "steps": {
+ "activate-process": {
+ "description": "Resource Assign and Netconf Activation Workflow",
+ "target": "assign-activate-process",
+ "activities": [
+ {
+ "call_operation": "CONFIG.AssignActivateProcess"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file