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