Merge "Refractor rest log tracing filter for reuse."
[ccsdk/cds.git] / cds-ui / server / src / controllers / blueprint-rest.controller.ts
1 /*
2 ============LICENSE_START==========================================
3 ===================================================================
4 Copyright (C) 2018-19 IBM Intellectual Property. All rights reserved.
5 ===================================================================
6
7 Unless otherwise specified, all software contained herein is licensed
8 under the Apache License, Version 2.0 (the License);
9 you may not use this software except in compliance with the License.
10 You may obtain a copy of the License at
11
12     http://www.apache.org/licenses/LICENSE-2.0
13
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19 ============LICENSE_END============================================
20 */
21
22
23
24 import {
25   Count,
26   CountSchema,
27   Filter,
28   repository,
29   Where,
30 } from '@loopback/repository';
31 import {
32   post,
33   param,
34   get,
35   getFilterSchemaFor,
36   getWhereSchemaFor,
37   patch,
38   put,
39   del,
40   requestBody,
41   Request,
42   Response,
43   RestBindings,
44 } from '@loopback/rest';
45 import { Blueprint } from '../models';
46 import { inject } from '@loopback/core';
47 import { BlueprintService } from '../services';
48 import * as fs from 'fs';
49 import * as multiparty from 'multiparty';
50 import * as request_lib from 'request';
51 import { processorApiConfig, appConfig } from '../config/app-config';
52 import { bluePrintManagementServiceGrpcClient } from '../clients/blueprint-management-service-grpc-client';
53
54 export class BlueprintRestController {
55   constructor(
56     @inject('services.BlueprintService')
57     public bpservice: BlueprintService,
58   ) { }
59
60   @get('/controllerblueprint/all', {
61     responses: {
62       '200': {
63         description: 'Blueprint model instance',
64         content: { 'application/json': { schema: { 'x-ts-type': Blueprint } } },
65       },
66     },
67   })
68   async getall() {
69     return await this.bpservice.getAllblueprints();
70   }
71
72  @get('/controllerblueprint/meta-data/{keyword}', {
73     responses: {
74       '200': {
75         description: 'Blueprint model instance',
76         content: { 'application/json': { schema: { 'x-ts-type': Blueprint } } },
77       },
78     },
79   })
80   async getAllPacakgesByKeword(@param.path.string('keyword') keyword: string) {
81     return await this.bpservice.getBlueprintsByKeyword(keyword);
82   }
83
84
85
86   @get('/controllerblueprint/searchByTags/{tags}', {
87     responses: {
88       '200': {
89         content: { 'application/json': {} },
90       },
91     },
92   })
93   async getByTags(@param.path.string('tags') tags: string) {
94     return await this.bpservice.getByTags(tags);
95   }
96
97   @post('/controllerblueprint/create-blueprint')
98   async upload(
99     @requestBody({
100       description: 'multipart/form-data value.',
101       required: true,
102       content: {
103         'multipart/form-data': {
104           // Skip body parsing
105           'x-parser': 'stream',
106           schema: { type: 'object' },
107         },
108       },
109     })
110     request: Request,
111     @inject(RestBindings.Http.RESPONSE) response: Response,
112   ): Promise<Response> {
113     return new Promise((resolve, reject) => {
114       this.getFileFromMultiPartForm(request).then(file => {
115         // if (appConfig.action.deployBlueprint.grpcEnabled)
116         if (appConfig.action.grpcEnabled)
117           return this.uploadFileToBlueprintProcessorGrpc(file, "DRAFT", response);
118         else
119           return this.uploadFileToBlueprintController(file, "/blueprint-model/", response);
120       }, err => {
121         reject(err);
122       });
123     });
124     // return new Promise((resolve, reject) => {
125     //   this.getFileFromMultiPartForm(request).then(file => {
126     //     this.uploadFileToBlueprintController(file, "/blueprint-model/", response).then(resp => {
127     //       resolve(resp);
128     //     }, err => {
129     //       reject(err);
130     //     });
131     //   }, err => {
132     //     reject(err);
133     //   });
134     // });
135   }
136
137   @post('/controllerblueprint/publish')
138   async publish(
139     @requestBody({
140       description: 'multipart/form-data value.',
141       required: true,
142       content: {
143         'multipart/form-data': {
144           // Skip body parsing
145           'x-parser': 'stream',
146           schema: { type: 'object' },
147         },
148       },
149     })
150     request: Request,
151     @inject(RestBindings.Http.RESPONSE) response: Response,
152   ): Promise<Response> {
153     return new Promise((resolve, reject) => {
154       this.getFileFromMultiPartForm(request).then(file => {
155         // if (appConfig.action.deployBlueprint.grpcEnabled)
156         if (appConfig.action.grpcEnabled)
157           return this.uploadFileToBlueprintProcessorGrpc(file, "PUBLISH", response);
158         else
159           return this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response);
160       }, err => {
161         reject(err);
162       });
163     });
164     // return new Promise((resolve, reject) => {
165     //   this.getFileFromMultiPartForm(request).then(file => {
166     //     this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response).then(resp => {
167     //       resolve(resp);
168     //     }, err => {
169     //       reject(err);
170     //     });
171     //   }, err => {
172     //     reject(err);
173     //   });
174     // });
175   }
176
177   @post('/controllerblueprint/enrich-blueprint')
178   async enrich(
179     @requestBody({
180       description: 'multipart/form-data value.',
181       required: true,
182       content: {
183         'multipart/form-data': {
184           // Skip body parsing
185           'x-parser': 'stream',
186           schema: { type: 'object' },
187         },
188       },
189     })
190     request: Request,
191     @inject(RestBindings.Http.RESPONSE) response: Response,
192   ): Promise<Response> {
193     return new Promise((resolve, reject) => {
194       this.getFileFromMultiPartForm(request).then(file => {
195         if (appConfig.action.grpcEnabled)
196           return this.uploadFileToBlueprintProcessorGrpc(file, "ENRICH", response);
197         else
198           return this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response)
199         //   this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response).then(resp => {
200         //     resolve(resp);
201         //   }, err => {
202         //     reject(err);
203         //   });
204         // }, err => {
205         //   reject(err);
206       });
207     });
208   }
209
210   @get('/controllerblueprint/download-blueprint/{name}/{version}')
211   async download(
212     @param.path.string('name') name: string,
213     @param.path.string('version') version: string,
214     @inject(RestBindings.Http.RESPONSE) response: Response,
215   ): Promise<Response> {
216
217     if (appConfig.action.grpcEnabled)
218       return this.downloadFileFromBlueprintProcessorGrpc(name, version, response);
219     else
220       return this.downloadFileFromBlueprintController("/blueprint-model/download/by-name/" + name + "/version/" + version, response);
221   }
222
223
224   async getFileFromMultiPartForm(request: Request): Promise<multiparty.File> {
225     return new Promise((resolve, reject) => {
226       let form = new multiparty.Form();
227       form.parse(request, (err: any, fields: any, files: { [x: string]: any[]; }) => {
228         if (err) reject(err);
229         let file = files['file'][0]; // get the file from the returned files object
230         if (!file) {
231           reject('File was not found in form data.');
232         } else {
233           resolve(file);
234         }
235       });
236     })
237   }
238
239   @post('/controllerblueprint/deploy-blueprint')
240   async deploy(
241     @requestBody({
242       description: 'multipart/form-data value.',
243       required: true,
244       content: {
245         'multipart/form-data': {
246           // Skip body parsing
247           'x-parser': 'stream',
248           schema: { type: 'object' },
249         },
250       },
251     })
252     request: Request,
253     @inject(RestBindings.Http.RESPONSE) response: Response,
254   ): Promise<Response> {
255     return new Promise((resolve, reject) => {
256       this.getFileFromMultiPartForm(request).then(file => {
257         // if (appConfig.action.deployBlueprint.grpcEnabled)
258         if (appConfig.action.grpcEnabled)
259           return this.uploadFileToBlueprintProcessorGrpc(file, "PUBLISH", response);
260         else
261           return this.uploadFileToBlueprintProcessor(file, "/execution-service/upload/", response);
262       }, err => {
263         reject(err);
264       });
265     });
266   }
267
268   async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response> {
269     return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
270   }
271
272   async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<Response> {
273     return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
274   }
275
276   async uploadFileToBlueprintService(file: multiparty.File, url: string, authToken: string, response: Response): Promise<Response> {
277     let options = {
278       url: url,
279       headers: {
280         Authorization: authToken,
281         'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
282       },
283       formData: {
284         file: {
285           value: fs.createReadStream(file.path),
286           options: {
287             filename: 'cba.zip',
288             contentType: 'application/zip'
289           }
290         }
291       }
292     };
293
294     var removeTempFile = () => {
295       fs.unlink(file.path, (err: any) => {
296         if (err) {
297           console.error(err);
298         }
299       });
300     }
301
302     return new Promise((resolve, reject) => {
303       request_lib.post(options)
304         .on("error", err => {
305           reject(err);
306         })
307         .pipe(response)
308         .once("finish", () => {
309           removeTempFile();
310           resolve(response);
311         });
312     })
313   }
314
315   async downloadFileFromBlueprintController(uri: string, response: Response): Promise<Response> {
316     return this.downloadFileFromBlueprintService(processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
317   }
318
319   async downloadFileFromBlueprintService(url: string, authToken: string, response: Response): Promise<Response> {
320     let options = {
321       url: url,
322       headers: {
323         Authorization: authToken,
324       }
325     };
326     return new Promise((resolve, reject) => {
327       request_lib.get(options)
328         .on("error", err => {
329           reject(err);
330         })
331         .pipe(response)
332         .once("finish", () => {
333           resolve(response);
334         });
335     })
336   }
337
338   async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, actionName: string, response: Response): Promise<Response> {
339     return new Promise<Response>((resolve, reject) => {
340       bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path, actionName).then(output => {
341         response.send(output.status.message);
342         resolve(response);
343       }, err => {
344         response.status(500).send(err);
345         resolve(response);
346       });
347     });
348   }
349   async downloadFileFromBlueprintProcessorGrpc(blueprintName: string, blueprintVersion: string, response: Response): Promise<Response> {
350     return new Promise<Response>((resolve, reject) => {
351       bluePrintManagementServiceGrpcClient.downloadBlueprint(blueprintName, blueprintVersion)
352         .then(output => {
353           response.send(output.status.message);
354           resolve(response);
355         }, err => {
356           response.status(500).send(err);
357           resolve(response);
358         });
359     });
360   }
361 }