3def276fa27807e6ac68b27df7116e6de8febc7f
[sdc/sdc-workflow-designer.git] /
1 /*******************************************************************************
2  * Copyright (c) 2017 ZTE Corporation.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * and the Apache License 2.0 which both accompany this distribution,
6  * and are available at http://www.eclipse.org/legal/epl-v10.html
7  * and http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Contributors:
10  *     ZTE - initial API and implementation and/or initial documentation
11  *******************************************************************************/
12 import { Component, Input, OnInit } from '@angular/core';
13 import { Subscription } from 'rxjs/Subscription';
14 import { TranslateService } from '@ngx-translate/core';
15
16 import { PlanTreeviewItem } from '../../../model/plan-treeview-item';
17 import { ValueSource } from '../../../model/value-source.enum';
18 import { ValueType } from '../../../model/value-type.enum';
19 import { RestParameter } from '../../../model/workflow/rest-parameter';
20 import { RestTask } from '../../../model/workflow/rest-task';
21 import { BroadcastService } from '../../../services/broadcast.service';
22 import { NoticeService } from '../../../services/notice.service';
23 import { RestService } from '../../../services/rest.service';
24 import { WorkflowUtil } from '../../../util/workflow-util';
25 import { NodeTypeService } from '../../../services/node-type.service';
26 import { NodeDataType } from '../../../model/node-data-type/node-data-type';
27 import { SwaggerBaseParameter } from "../../../model/workflow/swagger/swagger-base-parameter";
28 import { SwaggerResponse } from "../../../model/workflow/swagger/swagger-response";
29 import { Swagger, SwaggerMethod } from '../../../model/swagger';
30 import { SwaggerBodyParameter } from '../../../model/workflow/swagger/swagger-body-parameter';
31 import { SwaggerNormalParameter } from '../../../model/workflow/swagger/swagger-normal-parameter';
32 import { SwaggerSchema } from '../../../model/workflow/swagger/swagger-schema';
33 import { SwaggerIn } from '../../../model/workflow/swagger/swagger-in.enum';
34
35 @Component({
36     selector: 'wfm-rest-task',
37     templateUrl: 'rest-task.component.html',
38 })
39 export class RestTaskComponent implements OnInit {
40     @Input() public node: RestTask;
41     @Input() public planItems: PlanTreeviewItem[];
42
43     public swaggerJson: any = {};
44     public restInterfaces = [];
45     public restOperations = [];
46     public loadSwaggerByMSB = true;
47     // public dataTypeInput: SwaggerBaseParameter[] = [];
48     public dataTypeOutput: SwaggerResponse[] = [];
49     public definitions: SwaggerSchema;
50     private swagger: Swagger;
51
52     constructor(private nodeTypeService: NodeTypeService, private broadcastService: BroadcastService, public restService: RestService,
53         private noticeService: NoticeService, private translate: TranslateService) { }
54
55     public ngOnInit() {
56         const nodeDataType = this.nodeTypeService.getNodeDataTypeById(this.node.typeId);
57         // if (nodeDataType.content && nodeDataType.content.baseUrl && nodeDataType.content.serviceName && nodeDataType.content.version
58         //     && nodeDataType.content.path && nodeDataType.content.method && nodeDataType.content.consumes) {
59         if (nodeDataType && nodeDataType.content && nodeDataType.content.baseUrl && nodeDataType.content.serviceName
60             && nodeDataType.content.serviceVersion && nodeDataType.content.path && nodeDataType.content.method) {
61             this.loadSwaggerByMSB = false;
62         }
63         if (this.loadSwaggerByMSB) {
64             this.loadInterfaces();
65         } else {
66             this.setParametersByDataType(nodeDataType);
67         }
68     }
69
70     public serviceChanged(configId: string) {
71         this.node.restConfigId = configId;
72         this.pathChanged('');
73         this.loadInterfaces();
74     }
75
76     public pathChanged(path: string) {
77         this.node.path = path;
78         this.node.consumes = [];
79         this.node.produces = [];
80         this.methodChanged('');
81         this.loadOperations();
82     }
83
84     public methodChanged(method: string) {
85         this.node.method = method;
86         this.node.parameters = [];
87         this.node.responses = [];
88         this.updateMethodInfo();
89     }
90
91     private loadInterfaces(): void {
92         if (this.node.restConfigId) {
93             // this.swagger = this.restService.getSwaggerInfo(this.node.restConfigId);
94             let restConfig = this.restService.getRestConfig(this.node.restConfigId);
95             this.node.baseUrl = restConfig.url;
96             this.node.serviceName = restConfig.name;
97             this.node.serviceVersion = restConfig.version;
98
99             this.swagger = restConfig.swagger;
100             if (this.swagger) {
101                 this.restInterfaces = [];
102                 for (const key of Object.keys(this.swagger.paths)) {
103                     this.restInterfaces.push(key);
104                 }
105                 this.loadOperations();
106             } else {
107                 this.translate.get('WORKFLOW.MSG.SWAGGER_NOT_EXISTS').subscribe((res: string) => {
108                     this.noticeService.error(res);
109                 });
110             }
111         }
112     }
113
114     private loadOperations(): void {
115         if (this.node.path) {
116             const swaggerPath: any = this.swagger.paths[this.node.path];
117
118             this.restOperations = [];
119             for (const key of Object.keys(swaggerPath)) {
120                 this.restOperations.push(key);
121             }
122         }
123     }
124
125     private updateMethodInfo(): void {
126         if (this.node.method) {
127             const path: any = this.swagger.paths[this.node.path];
128             const method: SwaggerMethod = path[this.node.method];
129
130             this.node.consumes = WorkflowUtil.deepClone(method.consumes);
131             this.node.produces = WorkflowUtil.deepClone(method.produces);
132
133             let tempParameters: RestParameter[] = [];
134             method.parameters.forEach(param => {
135                 let defaultType = SwaggerIn[SwaggerIn.body] === param.position ? ValueType[ValueType.object] : ValueType[ValueType.string];
136                 const type = param.type ? param.type : defaultType;
137                 const nodeParam = new RestParameter(param.name, undefined, ValueSource[ValueSource.string],
138                     type, param.position, param.schema, param.required);
139                 tempParameters.push(WorkflowUtil.deepClone(nodeParam));
140             });
141             this.node.parameters = tempParameters;
142
143             const responseParams = this.restService.getResponseParameters(
144                 this.swagger, this.node.path, this.node.method);
145             this.node.responses = responseParams.map(param => WorkflowUtil.deepClone(param));
146         }
147     }
148
149     private setParametersByDataType(nodeDataType: NodeDataType): void {
150         this.node.serviceName = nodeDataType.content.serviceName;
151         this.node.serviceVersion = nodeDataType.content.serviceVersion;
152         this.node.restConfigId = this.node.serviceName;
153         if (this.node.serviceVersion) {
154             this.node.restConfigId += ('.' + this.node.serviceVersion);
155         }
156         this.node.baseUrl = nodeDataType.content.baseUrl;
157         this.node.path = nodeDataType.content.path;
158         this.node.method = nodeDataType.content.method;
159         this.node.consumes = nodeDataType.content.consumes;
160         this.node.produces = nodeDataType.content.produces;
161         this.definitions = nodeDataType.definitions;
162         if (nodeDataType.content.inputs) {
163             for (const key in nodeDataType.content.inputs) {
164                 if (nodeDataType.content.inputs.hasOwnProperty(key)) {
165                     // Set default value of dataType
166                     const element = nodeDataType.content.inputs[key];
167                     let param: SwaggerBaseParameter = this.getParameterByDataType(element, key);
168                     if (param) {
169                         // Set exist value
170                         let found = false;
171                         if (this.node.parameters) {
172                             for (let p = 0; p < this.node.parameters.length; p++) {
173                                 if (param.name === this.node.parameters[p].name) {
174                                     found = true;
175                                     let value = this.node.parameters[p].value;
176                                     let valueSource = this.node.parameters[p].valueSource;
177                                     param.value = value;
178                                     param.valueSource = valueSource;
179                                     this.node.parameters[p] = param;
180                                     break;
181                                 }
182                             }
183                         } else {
184                             this.node.parameters = [];
185                         }
186                         if (!found) {
187                             this.node.parameters.push(param);
188                         }
189                     }
190                 }
191             }
192         }
193         if (nodeDataType.content.outputs) {
194             for (const key in nodeDataType.content.outputs) {
195                 if (nodeDataType.content.outputs.hasOwnProperty(key)) {
196                     // Set default value of dataType
197                     const element = nodeDataType.content.outputs[key];
198                     this.dataTypeOutput.push(this.getResponseByDataType(element, key));
199                 }
200             }
201         }
202     }
203
204     private getParameterByDataType(dataTypeParameter: SwaggerBaseParameter, name: string): SwaggerBaseParameter {
205         if (!dataTypeParameter.name) {
206             dataTypeParameter.name = name;
207         }
208         if (SwaggerIn[SwaggerIn.body] === dataTypeParameter.in) {
209             return this.initBodyParam(dataTypeParameter as SwaggerBodyParameter);
210         } else {
211             return this.initNormalParam(dataTypeParameter as SwaggerNormalParameter);
212         }
213     }
214
215     private getResponseByDataType(dataTypeResponse: SwaggerResponse, name: string): SwaggerResponse {
216         let responseParam = dataTypeResponse;
217         if (!responseParam.name) {
218             responseParam.name = name;
219         }
220         return this.initResponseParam(responseParam);
221     }
222
223     private initNormalParam(normalParam: SwaggerNormalParameter): SwaggerNormalParameter {
224         let normal = WorkflowUtil.deepClone(normalParam);
225         // Set default value of dataType
226         if (undefined === normalParam.show) {
227             normal.show = true;
228         }
229         if ('path' === normalParam.in) {
230             normal.required = true;
231         } else if (undefined === normalParam.required) {
232             normal.required = false;
233         }
234         if (undefined === normalParam.allowEmptyValue) {
235             normal.allowEmptyValue = false;
236         }
237         if (undefined === normalParam.collectionFormat) {
238             normal.collectionFormat = 'csv';
239         }
240         if (undefined === normalParam.type) {
241             normal.type == ValueType[ValueType.string];
242         }
243         // editable not support
244         return normal;
245     }
246
247     private initBodyParam(bodyParam: SwaggerBodyParameter): SwaggerBodyParameter {
248         let body = WorkflowUtil.deepClone(bodyParam);
249         // Set default value of dataType
250         if (undefined === bodyParam.show) {
251             body.show = true;
252         }
253         if (undefined === bodyParam.required) {
254             body.required = false;
255         }
256         if (undefined === bodyParam.valueSource) {
257             body.valueSource = ValueSource[ValueSource.Definition];
258         }
259         if (undefined === bodyParam.schema.type) {
260             body.schema.type == ValueType[ValueType.string];
261         }
262         // $ref not support
263         if (bodyParam.$ref) {
264             console.warn('Do not support body parameter $ref.');
265         }
266         return body;
267     }
268
269     private initResponseParam(responseParam: SwaggerResponse): SwaggerResponse {
270         let response = responseParam;
271         return response;
272     }
273 }