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