Merge "create palette on the right side menu draw function elements to the palette...
[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 import {
24   Count,
25   CountSchema,
26   Filter,
27   repository,
28   Where,
29 } from '@loopback/repository';
30 import {
31   post,
32   param,
33   get,
34   getFilterSchemaFor,
35   getWhereSchemaFor,
36   patch,
37   put,
38   del,
39   requestBody,
40   Request,
41   Response,
42   RestBindings,
43 } from '@loopback/rest';
44 import {Blueprint} from '../models';
45 import {inject} from '@loopback/core';
46 import {BlueprintService} from '../services';
47 import * as fs from 'fs';
48 import * as multiparty from 'multiparty';
49 import * as request_lib from 'request';
50 import {processorApiConfig, appConfig} from '../config/app-config';
51 import {bluePrintManagementServiceGrpcClient} from '../clients/blueprint-management-service-grpc-client';
52 import {BlueprintDetail} from '../models/blueprint.detail.model';
53
54 export class BlueprintRestController {
55   constructor(
56     @inject('services.BlueprintService')
57     public bpservice: BlueprintService,
58   ) {
59   }
60
61   @get('/controllerblueprint/all', {
62     responses: {
63       '200': {
64         description: 'Blueprint model instance',
65         content: {'application/json': {schema: {'x-ts-type': Blueprint}}},
66       },
67     },
68   })
69   async getall() {
70     return await this.bpservice.getAllblueprints();
71   }
72
73   @get('/controllerblueprint/{id}', {
74     responses: {
75       '200': {
76         description: 'Blueprint model instance',
77         content: {'application/json': {schema: {'x-ts-type': BlueprintDetail}}},
78       },
79     },
80   })
81   async getOneBluePrint(@param.path.string('id') id: string) {
82     return await this.bpservice.getOneBluePrint(id);
83   }
84
85
86   @get('/controllerblueprint/paged', {
87     responses: {
88       '200': {
89         description: 'Blueprint model instance with pagination',
90         content: {'application/json': {schema: {'x-ts-type': Blueprint}}},
91       },
92     },
93   })
94   async getPagedBlueprints(
95     @param.query.number('limit') limit: number,
96     @param.query.number('offset') offset: number,
97     @param.query.string('sort') sort: string) {
98     return await this.bpservice.getPagedBueprints(limit, offset, sort);
99   }
100
101   @get('/controllerblueprint/metadata/paged/{keyword}', {
102     responses: {
103       '200': {
104         description: 'Blueprint model instance with pagination',
105         content: {'application/json': {schema: {'x-ts-type': Blueprint}}},
106       },
107     },
108   })
109   async getMetaDataPagedBlueprints(
110     @param.path.string('keyword') keyword: string,
111     @param.query.number('limit') limit: number,
112     @param.query.number('offset') offset: number,
113     @param.query.string('sort') sort: string) {
114     return await this.bpservice.getMetaDataPagedBlueprints(limit, offset, sort, keyword);
115   }
116
117   @get('/controllerblueprint/meta-data/{keyword}', {
118     responses: {
119       '200': {
120         description: 'Blueprint model instance',
121         content: {'application/json': {schema: {'x-ts-type': Blueprint}}},
122       },
123     },
124   })
125   async getAllPacakgesByKeword(@param.path.string('keyword') keyword: string) {
126     return await this.bpservice.getBlueprintsByKeyword(keyword);
127   }
128
129   @get('/controllerblueprint/by-name/{name}/version/{version}', {
130     responses: {
131       '200': {
132         description: 'Blueprint model instance',
133         content: {'application/json': {schema: {'x-ts-type': Blueprint}}},
134       },
135     },
136   })
137   async getPacakgesByNameAndVersion(@param.path.string('name') name: string, @param.path.string('version') version: string) {
138     return await this.bpservice.getBlueprintByNameAndVersion(name, version);
139   }
140
141   @get('/controllerblueprint/searchByTags/{tags}', {
142     responses: {
143       '200': {
144         content: {'application/json': {}},
145       },
146     },
147   })
148   async getByTags(@param.path.string('tags') tags: string) {
149     return await this.bpservice.getByTags(tags);
150   }
151
152   @post('/controllerblueprint/create-blueprint')
153   async upload(
154     @requestBody({
155       description: 'multipart/form-data value.',
156       required: true,
157       content: {
158         'multipart/form-data': {
159           // Skip body parsing
160           'x-parser': 'stream',
161           schema: {type: 'object'},
162         },
163       },
164     })
165       request: Request,
166     @inject(RestBindings.Http.RESPONSE) response: Response,
167   ): Promise<Response> {
168     return new Promise((resolve, reject) => {
169       this.getFileFromMultiPartForm(request).then(file => {
170         // if (appConfig.action.deployBlueprint.grpcEnabled)
171         if (appConfig.action.grpcEnabled)
172           return this.uploadFileToBlueprintProcessorGrpc(file, 'DRAFT', response);
173         else
174           return this.uploadFileToBlueprintController(file, '/blueprint-model/', response);
175       }, err => {
176         reject(err);
177       });
178     });
179     // return new Promise((resolve, reject) => {
180     //   this.getFileFromMultiPartForm(request).then(file => {
181     //     this.uploadFileToBlueprintController(file, "/blueprint-model/", response).then(resp => {
182     //       resolve(resp);
183     //     }, err => {
184     //       reject(err);
185     //     });
186     //   }, err => {
187     //     reject(err);
188     //   });
189     // });
190   }
191
192   @post('/controllerblueprint/publish')
193   async publish(
194     @requestBody({
195       description: 'multipart/form-data value.',
196       required: true,
197       content: {
198         'multipart/form-data': {
199           // Skip body parsing
200           'x-parser': 'stream',
201           schema: {type: 'object'},
202         },
203       },
204     })
205       request: Request,
206     @inject(RestBindings.Http.RESPONSE) response: Response,
207   ): Promise<Response> {
208     return new Promise((resolve, reject) => {
209       this.getFileFromMultiPartForm(request).then(file => {
210         // if (appConfig.action.deployBlueprint.grpcEnabled)
211         if (appConfig.action.grpcEnabled)
212           return this.uploadFileToBlueprintProcessorGrpc(file, 'PUBLISH', response);
213         else
214           return this.uploadFileToBlueprintController(file, '/blueprint-model/publish/', response);
215       }, err => {
216         reject(err);
217       });
218     });
219     // return new Promise((resolve, reject) => {
220     //   this.getFileFromMultiPartForm(request).then(file => {
221     //     this.uploadFileToBlueprintController(file, "/blueprint-model/publish/", response).then(resp => {
222     //       resolve(resp);
223     //     }, err => {
224     //       reject(err);
225     //     });
226     //   }, err => {
227     //     reject(err);
228     //   });
229     // });
230   }
231
232   @post('/controllerblueprint/enrich-blueprint')
233   async enrich(
234     @requestBody({
235       description: 'multipart/form-data value.',
236       required: true,
237       content: {
238         'multipart/form-data': {
239           // Skip body parsing
240           'x-parser': 'stream',
241           schema: {type: 'object'},
242         },
243       },
244     })
245       request: Request,
246     @inject(RestBindings.Http.RESPONSE) response: Response,
247   ): Promise<Response> {
248     return new Promise((resolve, reject) => {
249       this.getFileFromMultiPartForm(request).then(file => {
250         if (appConfig.action.grpcEnabled)
251           return this.uploadFileToBlueprintProcessorGrpc(file, 'ENRICH', response);
252         else
253           return this.uploadFileToBlueprintController(file, '/blueprint-model/enrich/', response);
254         //   this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/", response).then(resp => {
255         //     resolve(resp);
256         //   }, err => {
257         //     reject(err);
258         //   });
259         // }, err => {
260         //   reject(err);
261       });
262     });
263   }
264
265   @get('/controllerblueprint/download-blueprint/{name}/{version}')
266   async download(
267     @param.path.string('name') name: string,
268     @param.path.string('version') version: string,
269     @inject(RestBindings.Http.RESPONSE) response: Response,
270   ): Promise<Response> {
271
272     if (appConfig.action.grpcEnabled)
273       return this.downloadFileFromBlueprintProcessorGrpc(name, version, response);
274     else
275       return this.downloadFileFromBlueprintController('/blueprint-model/download/by-name/' + name + '/version/' + version, response);
276   }
277
278
279   async getFileFromMultiPartForm(request: Request): Promise<multiparty.File> {
280     return new Promise((resolve, reject) => {
281       let form = new multiparty.Form();
282       form.parse(request, (err: any, fields: any, files: {[x: string]: any[];}) => {
283         if (err) reject(err);
284         let file = files['file'][0]; // get the file from the returned files object
285         if (!file) {
286           reject('File was not found in form data.');
287         } else {
288           resolve(file);
289         }
290       });
291     });
292   }
293
294   @post('/controllerblueprint/deploy-blueprint')
295   async deploy(
296     @requestBody({
297       description: 'multipart/form-data value.',
298       required: true,
299       content: {
300         'multipart/form-data': {
301           // Skip body parsing
302           'x-parser': 'stream',
303           schema: {type: 'object'},
304         },
305       },
306     })
307       request: Request,
308     @inject(RestBindings.Http.RESPONSE) response: Response,
309   ): Promise<Response> {
310     return new Promise((resolve, reject) => {
311       this.getFileFromMultiPartForm(request).then(file => {
312         // if (appConfig.action.deployBlueprint.grpcEnabled)
313         if (appConfig.action.grpcEnabled)
314           return this.uploadFileToBlueprintProcessorGrpc(file, 'PUBLISH', response);
315         else
316           return this.uploadFileToBlueprintProcessor(file, '/execution-service/upload/', response);
317       }, err => {
318         reject(err);
319       });
320     });
321   }
322
323   async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response> {
324     return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
325   }
326
327   async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<Response> {
328     return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
329   }
330
331   async uploadFileToBlueprintService(file: multiparty.File, url: string, authToken: string, response: Response): Promise<Response> {
332     let options = {
333       url: url,
334       headers: {
335         Authorization: authToken,
336         'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW',
337       },
338       formData: {
339         file: {
340           value: fs.createReadStream(file.path),
341           options: {
342             filename: 'cba.zip',
343             contentType: 'application/zip',
344           },
345         },
346       },
347     };
348
349     var removeTempFile = () => {
350       fs.unlink(file.path, (err: any) => {
351         if (err) {
352           console.error(err);
353         }
354       });
355     };
356
357     return new Promise((resolve, reject) => {
358       request_lib.post(options)
359         .on('error', err => {
360           reject(err);
361         })
362         .pipe(response)
363         .once('finish', () => {
364           removeTempFile();
365           resolve(response);
366         });
367     });
368   }
369
370   async downloadFileFromBlueprintController(uri: string, response: Response): Promise<Response> {
371     return this.downloadFileFromBlueprintService(processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
372   }
373
374   async downloadFileFromBlueprintService(url: string, authToken: string, response: Response): Promise<Response> {
375     let options = {
376       url: url,
377       headers: {
378         Authorization: authToken,
379       },
380     };
381     return new Promise((resolve, reject) => {
382       request_lib.get(options)
383         .on('error', err => {
384           reject(err);
385         })
386         .pipe(response)
387         .once('finish', () => {
388           resolve(response);
389         });
390     });
391   }
392
393   async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, actionName: string, response: Response): Promise<Response> {
394     return new Promise<Response>((resolve, reject) => {
395       bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path, actionName).then(output => {
396         response.send(output.status.message);
397         resolve(response);
398       }, err => {
399         response.status(500).send(err);
400         resolve(response);
401       });
402     });
403   }
404
405   async downloadFileFromBlueprintProcessorGrpc(blueprintName: string, blueprintVersion: string, response: Response): Promise<Response> {
406     return new Promise<Response>((resolve, reject) => {
407       bluePrintManagementServiceGrpcClient.downloadBlueprint(blueprintName, blueprintVersion)
408         .then(output => {
409           response.send(output.status.message);
410           resolve(response);
411         }, err => {
412           response.status(500).send(err);
413           resolve(response);
414         });
415     });
416   }
417 }