From 7f4d1836df509a1a06e4b7635a84a71b79084d6e Mon Sep 17 00:00:00 2001 From: Lvbo163 Date: Thu, 7 Sep 2017 10:02:49 +0800 Subject: support quote output of rest task rest task's parameters can quote output parameter of previous rest tasks. Issue-ID: SDC-121 Change-Id: I94f2058f7b8b2ad600ffb99c8838b37da5bb5b9d Signed-off-by: Lvbo163 --- sdc-workflow-designer-ui/src/app/app.module.ts | 2 + .../parameter-tree/parameter-tree.component.ts | 1 - .../components/parameter/parameter.component.ts | 1 - .../components/property/properties.component.ts | 8 +- .../src/app/services/jsplumb.service.ts | 10 +- .../src/app/services/workflow-process.service.ts | 206 +++++++++++++++++++++ .../src/app/services/workflow.service.ts | 131 ------------- 7 files changed, 217 insertions(+), 142 deletions(-) create mode 100644 sdc-workflow-designer-ui/src/app/services/workflow-process.service.ts (limited to 'sdc-workflow-designer-ui/src') diff --git a/sdc-workflow-designer-ui/src/app/app.module.ts b/sdc-workflow-designer-ui/src/app/app.module.ts index 0bf4b14c..047f4683 100644 --- a/sdc-workflow-designer-ui/src/app/app.module.ts +++ b/sdc-workflow-designer-ui/src/app/app.module.ts @@ -42,6 +42,7 @@ import { RestTaskParametersComponent } from "./components/property/rest-task/res import { ParameterTreeComponent } from "./components/parameter-tree/parameter-tree.component"; import { EditablePropertyComponent } from "./components/editable-property/editable-property.component"; import { SwaggerTreeConverterService } from "./services/swagger-tree-converter.service"; +import { WorkflowProcessService } from "./services/workflow-process.service"; @NgModule({ declarations: [ @@ -85,6 +86,7 @@ import { SwaggerTreeConverterService } from "./services/swagger-tree-converter.s JsPlumbService, SwaggerTreeConverterService, WorkflowConfigService, + WorkflowProcessService, WorkflowService ], bootstrap: [AppComponent] diff --git a/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts b/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts index d0e04e39..0de35b94 100644 --- a/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts +++ b/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts @@ -186,7 +186,6 @@ export class ParameterTreeComponent implements OnChanges { } private formatParam(params: any[]): void { - console.log(params); params.forEach(param => this.initParam(param)); } diff --git a/sdc-workflow-designer-ui/src/app/components/parameter/parameter.component.ts b/sdc-workflow-designer-ui/src/app/components/parameter/parameter.component.ts index 2cd5a0fd..3539c8f0 100644 --- a/sdc-workflow-designer-ui/src/app/components/parameter/parameter.component.ts +++ b/sdc-workflow-designer-ui/src/app/components/parameter/parameter.component.ts @@ -45,7 +45,6 @@ export class ParameterComponent implements OnInit { constructor(private dataAccessService: DataAccessService) { } public ngOnInit(): void { - console.log(this.planItems); if (1 === this.valueSource.length) { this.showValueSource = false; } diff --git a/sdc-workflow-designer-ui/src/app/components/property/properties.component.ts b/sdc-workflow-designer-ui/src/app/components/property/properties.component.ts index f3f784a1..2aa552ed 100644 --- a/sdc-workflow-designer-ui/src/app/components/property/properties.component.ts +++ b/sdc-workflow-designer-ui/src/app/components/property/properties.component.ts @@ -15,8 +15,8 @@ import { AfterViewInit, Component } from '@angular/core'; import { WorkflowNode } from '../../model/workflow/workflow-node'; import { BroadcastService } from '../../services/broadcast.service'; import { JsPlumbService } from '../../services/jsplumb.service'; -import { WorkflowService } from '../../services/workflow.service'; import { PlanTreeviewItem } from "../../model/plan-treeview-item"; +import { WorkflowProcessService } from "../../services/workflow-process.service"; /** * property component presents information of a workflow node. @@ -36,7 +36,7 @@ export class PropertiesComponent implements AfterViewInit { constructor(private broadcastService: BroadcastService, private jsPlumnService: JsPlumbService, - private workflowService: WorkflowService) { + private processService: WorkflowProcessService) { } @@ -44,7 +44,7 @@ export class PropertiesComponent implements AfterViewInit { this.broadcastService.showProperty$.subscribe(show => this.show = show); this.broadcastService.nodeProperty$.subscribe(node => { this.node = node; - this.planItems = this.workflowService.getPlanParameters(this.node.id); + this.planItems = this.processService.getPlanParameters(this.node.id); }); } @@ -57,6 +57,6 @@ export class PropertiesComponent implements AfterViewInit { this.show = false; this.jsPlumnService.remove(this.node.id); - this.workflowService.deleteNode(this.node.id); + this.processService.deleteNode(this.node.id); } } diff --git a/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts b/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts index ffd00c6a..543b09f3 100644 --- a/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts +++ b/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts @@ -12,7 +12,7 @@ import { Injectable } from '@angular/core'; import * as jsp from 'jsplumb'; -import { WorkflowService } from "./workflow.service"; +import { WorkflowProcessService } from "./workflow-process.service"; /** * JsPlumbService @@ -22,7 +22,7 @@ import { WorkflowService } from "./workflow.service"; export class JsPlumbService { public jsplumbInstance; - constructor(private workflowService: WorkflowService) { + constructor(private processService: WorkflowProcessService) { this.initJsPlumbInstance(); } @@ -58,11 +58,11 @@ export class JsPlumbService { // add connection to model data while a new connection is build this.jsplumbInstance.bind('connection', info => { - this.workflowService.addSequenceFlow(info.connection.sourceId, info.connection.targetId); + this.processService.addSequenceFlow(info.connection.sourceId, info.connection.targetId); info.connection.bind('click', connection => { this.jsplumbInstance.select({ connections: [connection] }).delete(); - this.workflowService.deleteSequenceFlow(connection.sourceId, connection.targetId); + this.processService.deleteSequenceFlow(connection.sourceId, connection.targetId); }); }); @@ -117,7 +117,7 @@ export class JsPlumbService { const left = event.e.clientX - 220 - (event.e.offsetX / 2); const top = event.e.clientY - 70 - (event.e.offsetY / 2); - this.workflowService.addNode(type, type, top, left); + this.processService.addNode(type, type, top, left); }, }); } diff --git a/sdc-workflow-designer-ui/src/app/services/workflow-process.service.ts b/sdc-workflow-designer-ui/src/app/services/workflow-process.service.ts new file mode 100644 index 00000000..4c701ec3 --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/services/workflow-process.service.ts @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2017 ZTE Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * ZTE - initial API and implementation and/or initial documentation + */ + +import { Injectable } from '@angular/core'; +import { WorkflowNode } from "../model/workflow/workflow-node"; +import { Workflow } from "../model/workflow/workflow"; +import { Position } from "../model/workflow/position"; +import { NodeType } from "../model/workflow/node-type.enum"; +import { StartEvent } from "../model/workflow/start-event"; +import { SequenceFlow } from "../model/workflow/sequence-flow"; +import { RestTask } from "../model/workflow/rest-task"; +import { PlanTreeviewItem } from "../model/plan-treeview-item"; +import { WorkflowConfigService } from "./workflow-config.service"; +import { Swagger, SwaggerModelSimple, SwaggerReferenceObject } from "../model/swagger"; +import { WorkflowService } from "./workflow.service"; + +/** + * WorkflowService + * provides all of the operations about workflow operations. + */ +@Injectable() +export class WorkflowProcessService { + + constructor(private workflowService: WorkflowService, private configService: WorkflowConfigService) { + + } + + public getProcess(): WorkflowNode[] { + return this.workflowService.workflow.nodes; + } + + public addNode(name: string, type: string, top: number, left: number): WorkflowNode { + let node: WorkflowNode; + switch (type) { + case NodeType[NodeType.startEvent]: + node = new StartEvent(this.createId(), name, type, new Position(top, left), []); + break; + case NodeType[NodeType.restTask]: + node = new RestTask(this.createId(), name, type, new Position(top, left), []); + break; + default: + node = new WorkflowNode(this.createId(), name, type, new Position(top, left), []); + break; + } + + this.getProcess().push(node); + return node; + } + + public deleteNode(nodeId: string): WorkflowNode { + // delete related connections + this.getProcess().forEach(node => this.deleteSequenceFlow(node.id, nodeId)); + + // delete current node + const index = this.getProcess().findIndex(node => node.id === nodeId); + if (index !== -1) { + const node = this.getProcess().splice(index, 1)[0]; + node.sequenceFlows = []; + return node; + } + + return undefined; + } + + public addSequenceFlow(sourceId: string, targetId: string) { + const node = this.getNodeById(sourceId); + if (node) { + const index = node.sequenceFlows.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId); + if (index === -1) { + node.sequenceFlows.push(new SequenceFlow(sourceId, targetId)); + } + } + } + + public deleteSequenceFlow(sourceId: string, targetId: string) { + const node = this.getNodeById(sourceId); + if (node) { + const index = node.sequenceFlows.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId); + if (index !== -1) { + node.sequenceFlows.splice(index, 1); + } + } + } + + public getPlanParameters(nodeId: string): PlanTreeviewItem[] { + const preNodeList = new Array(); + this.getPreNodes(nodeId, preNodeList); + + return this.loadNodeOutputs(preNodeList); + } + + private loadNodeOutputs(nodes: WorkflowNode[]): PlanTreeviewItem[] { + const params = new Array(); + nodes.forEach(node => { + switch (node.type) { + case NodeType[NodeType.startEvent]: + params.push(this.loadOutput4StartEvent(node)); + break; + case NodeType[NodeType.restTask]: + params.push(this.loadOutput4RestTask(node)); + break; + default: + break; + } + }); + + return params; + } + + private loadOutput4StartEvent(node: StartEvent): PlanTreeviewItem { + const startItem = new PlanTreeviewItem(node.name, `[${node.id}]`, []); + node.parameters.map(param => + startItem.children.push(new PlanTreeviewItem(param.name, `[${param.name}]`, []))); + return startItem; + } + + private loadOutput4RestTask(node: RestTask): PlanTreeviewItem { + const item = new PlanTreeviewItem(node.name, `[${node.id}]`, []); + item.children.push(this.createStatusCodeTreeViewItem(node.id)); + + if (node.responses.length !== 0) { // load rest responses + const responseItem = this.createResponseTreeViewItem(node.id); + item.children.push(responseItem); + if (node.responses[0]) { + const swagger = this.configService.getSwaggerInfo(node.serviceName, node.serviceVersion); + const swaggerDefinition = this.configService.getDefinition(swagger, node.responses[0].schema.$ref); + this.loadParamsBySwaggerDefinition(responseItem, swagger, swaggerDefinition); + } + } + + return item; + } + + private createStatusCodeTreeViewItem(nodeId: string): PlanTreeviewItem { + return new PlanTreeviewItem('statusCode', `[${nodeId}].[statusCode]`, []); + } + + private createResponseTreeViewItem(nodeId: string): PlanTreeviewItem { + return new PlanTreeviewItem('response', `[${nodeId}].[responseBody]`, []); + } + + private loadParamsBySwaggerDefinition(parentItem: PlanTreeviewItem, swagger: Swagger, definition: SwaggerModelSimple) { + Object.getOwnPropertyNames(definition.properties).map(key => { + const property = definition.properties[key]; + const value = `${parentItem.value}.[${key}]`; + const propertyItem = new PlanTreeviewItem(key, value, []); + parentItem.children.push(propertyItem); + + if (property instanceof SwaggerReferenceObject) { + const propertyDefinition = this.configService.getDefinition(swagger, property.$ref); + this.loadParamsBySwaggerDefinition(propertyItem, swagger, + propertyDefinition); + } + + return propertyItem; + }); + } + + public getPreNodes(nodeId: string, preNodes: WorkflowNode[]) { + const preNode4CurrentNode = []; + this.getProcess().forEach(node => { + if (this.isPreNode(node, nodeId)) { + const existNode = preNodes.find(tmpNode => tmpNode.id === node.id); + if (existNode) { + // current node already exists in preNodes. this could avoid loop circle. + } else { + preNode4CurrentNode.push(node); + preNodes.push(node); + } + } + }); + + preNode4CurrentNode.forEach(node => this.getPreNodes(node.id, preNodes)); + } + + public isPreNode(preNode: WorkflowNode, id: string): boolean { + const targetNode = preNode.sequenceFlows.find(connection => connection.targetRef === id); + return targetNode !== undefined; + } + + public getNodeById(sourceId: string): WorkflowNode { + return this.getProcess().find(node => node.id === sourceId); + } + + private createId() { + const idSet = new Set(); + this.getProcess().forEach(node => idSet.add(node.id)); + + for (let i = 0; i < idSet.size; i++) { + if (!idSet.has('node' + i)) { + return 'node' + i; + } + } + + return 'node' + idSet.size; + } +} diff --git a/sdc-workflow-designer-ui/src/app/services/workflow.service.ts b/sdc-workflow-designer-ui/src/app/services/workflow.service.ts index 4bcd43b0..7d751923 100644 --- a/sdc-workflow-designer-ui/src/app/services/workflow.service.ts +++ b/sdc-workflow-designer-ui/src/app/services/workflow.service.ts @@ -11,16 +11,9 @@ */ import { Injectable } from '@angular/core'; -import { WorkflowNode } from "../model/workflow/workflow-node"; import { DataAccessService } from "./data-access/data-access.service"; import { Observable } from "rxjs/Observable"; import { Workflow } from "../model/workflow/workflow"; -import { Position } from "../model/workflow/position"; -import { NodeType } from "../model/workflow/node-type.enum"; -import { StartEvent } from "../model/workflow/start-event"; -import { SequenceFlow } from "../model/workflow/sequence-flow"; -import { RestTask } from "../model/workflow/rest-task"; -import { PlanTreeviewItem } from "../model/plan-treeview-item"; /** * WorkflowService @@ -39,128 +32,4 @@ export class WorkflowService { console.log(this.workflow); return this.dataAccessService.catalogService.saveWorkflow(this.workflow); } - - public addNode(name: string, type: string, top: number, left: number): WorkflowNode { - let node: WorkflowNode; - switch (type) { - case NodeType[NodeType.startEvent]: - node = new StartEvent(this.createId(), name, type, new Position(top, left), []); - break; - case NodeType[NodeType.restTask]: - node = new RestTask(this.createId(), name, type, new Position(top, left), []); - break; - default: - node = new WorkflowNode(this.createId(), name, type, new Position(top, left), []); - break; - } - - this.workflow.nodes.push(node); - return node; - } - - public deleteNode(nodeId: string): WorkflowNode { - // delete related connections - this.workflow.nodes.forEach(node => this.deleteSequenceFlow(node.id, nodeId)); - - // delete current node - const index = this.workflow.nodes.findIndex(node => node.id === nodeId); - if (index !== -1) { - const node = this.workflow.nodes.splice(index, 1)[0]; - node.sequenceFlows = []; - return node; - } - - return undefined; - } - - public addSequenceFlow(sourceId: string, targetId: string) { - const node = this.getNodeById(sourceId); - if (node) { - const index = node.sequenceFlows.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId); - if (index === -1) { - node.sequenceFlows.push(new SequenceFlow(sourceId, targetId)); - } - } - } - - public deleteSequenceFlow(sourceId: string, targetId: string) { - const node = this.getNodeById(sourceId); - if (node) { - const index = node.sequenceFlows.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId); - if (index !== -1) { - node.sequenceFlows.splice(index, 1); - } - } - } - - public getPlanParameters(nodeId: string): PlanTreeviewItem[] { - const preNodeList = new Array(); - this.getPreNodes(nodeId, preNodeList); - - return this.loadNodeOutputs(preNodeList); - } - - private loadNodeOutputs(nodes: WorkflowNode[]): PlanTreeviewItem[] { - const params = new Array(); - nodes.forEach(node => { - switch (node.type) { - case NodeType[NodeType.startEvent]: - params.push(this.loadOutput4StartEvent(node)); - break; - case NodeType[NodeType.restTask]: - // TODO for rest task - break; - default: - break; - } - }); - - return params; - } - - private loadOutput4StartEvent(node: StartEvent): PlanTreeviewItem { - const startItem = new PlanTreeviewItem(node.name, `[${node.id}]`, []); - node.parameters.map(param => - startItem.children.push(new PlanTreeviewItem(param.name, `[${param.name}]`, []))); - return startItem; - } - - public getPreNodes(nodeId: string, preNodes: WorkflowNode[]) { - const preNode4CurrentNode = []; - this.workflow.nodes.forEach(node => { - if (this.isPreNode(node, nodeId)) { - const existNode = preNodes.find(tmpNode => tmpNode.id === node.id); - if (existNode) { - // current node already exists in preNodes. this could avoid loop circle. - } else { - preNode4CurrentNode.push(node); - preNodes.push(node); - } - } - }); - - preNode4CurrentNode.forEach(node => this.getPreNodes(node.id, preNodes)); - } - - public isPreNode(preNode: WorkflowNode, id: string): boolean { - const targetNode = preNode.sequenceFlows.find(connection => connection.targetRef === id); - return targetNode !== undefined; - } - - public getNodeById(sourceId: string): WorkflowNode { - return this.workflow.nodes.find(node => node.id === sourceId); - } - - private createId() { - const idSet = new Set(); - this.workflow.nodes.forEach(node => idSet.add(node.id)); - - for (let i = 0; i < idSet.size; i++) { - if (!idSet.has('node' + i)) { - return 'node' + i; - } - } - - return 'node' + idSet.size; - } } -- cgit 1.2.3-korg