870f9793fa7a531c153c93635e937026b5ab8d39
[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.getPagedBueprints(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   @get('/controllerblueprint/download-blueprint/{name}/{version}')
260   async download(
261     @param.path.string('name') name: string,
262     @param.path.string('version') version: string,
263     @inject(RestBindings.Http.RESPONSE) response: Response,
264   ): Promise<Response> {
265
266     if (appConfig.action.grpcEnabled)
267       return this.downloadFileFromBlueprintProcessorGrpc(name, version, response);
268     else
269       return this.downloadFileFromBlueprintController('/blueprint-model/download/by-name/' + name + '/version/' + version, response);
270   }
271
272
273   async getFileFromMultiPartForm(request: Request): Promise<multiparty.File> {
274     return new Promise((resolve, reject) => {
275       let form = new multiparty.Form();
276       form.parse(request, (err: any, fields: any, files: { [x: string]: any[]; }) => {
277         if (err) reject(err);
278         let file = files['file'][0]; // get the file from the returned files object
279         if (!file) {
280           reject('File was not found in form data.');
281         } else {
282           resolve(file);
283         }
284       });
285     });
286   }
287
288   @post('/controllerblueprint/deploy-blueprint')
289   async deploy(
290     @requestBody({
291       description: 'multipart/form-data value.',
292       required: true,
293       content: {
294         'multipart/form-data': {
295           // Skip body parsing
296           'x-parser': 'stream',
297           schema: { type: 'object' },
298         },
299       },
300     })
301     request: Request,
302     @inject(RestBindings.Http.RESPONSE) response: Response,
303   ): Promise<Response> {
304     return new Promise((resolve, reject) => {
305       this.getFileFromMultiPartForm(request).then(file => {
306         // if (appConfig.action.deployBlueprint.grpcEnabled)
307         if (appConfig.action.grpcEnabled)
308           return this.uploadFileToBlueprintProcessorGrpc(file, 'PUBLISH', response);
309         else
310           return this.uploadFileToBlueprintProcessor(file, '/execution-service/upload/', response);
311       }, err => {
312         reject(err);
313       });
314     });
315   }
316
317   async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response> {
318     return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
319   }
320
321   async uploadFileToBlueprintProcessor(file: multiparty.File, uri: string, response: Response): Promise<Response> {
322     return this.uploadFileToBlueprintService(file, processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
323   }
324
325   async uploadFileToBlueprintService(file: multiparty.File, url: string, authToken: string, response: Response): Promise<Response> {
326     let options = {
327       url: url,
328       headers: {
329         Authorization: authToken,
330         'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW',
331       },
332       formData: {
333         file: {
334           value: fs.createReadStream(file.path),
335           options: {
336             filename: 'cba.zip',
337             contentType: 'application/zip',
338           },
339         },
340       },
341     };
342
343     var removeTempFile = () => {
344       fs.unlink(file.path, (err: any) => {
345         if (err) {
346           console.error(err);
347         }
348       });
349     };
350
351     return new Promise((resolve, reject) => {
352       request_lib.post(options)
353         .on('error', err => {
354           reject(err);
355         })
356         .pipe(response)
357         .once('finish', () => {
358           removeTempFile();
359           resolve(response);
360         });
361     });
362   }
363
364   async downloadFileFromBlueprintController(uri: string, response: Response): Promise<Response> {
365     return this.downloadFileFromBlueprintService(processorApiConfig.http.url + uri, processorApiConfig.http.authToken, response);
366   }
367
368   async downloadFileFromBlueprintService(url: string, authToken: string, response: Response): Promise<Response> {
369     let options = {
370       url: url,
371       headers: {
372         Authorization: authToken,
373       },
374     };
375     return new Promise((resolve, reject) => {
376       request_lib.get(options)
377         .on('error', err => {
378           reject(err);
379         })
380         .pipe(response)
381         .once('finish', () => {
382           resolve(response);
383         });
384     });
385   }
386
387   async uploadFileToBlueprintProcessorGrpc(file: multiparty.File, actionName: string, response: Response): Promise<Response> {
388     return new Promise<Response>((resolve, reject) => {
389       bluePrintManagementServiceGrpcClient.uploadBlueprint(file.path, actionName).then(output => {
390         response.send(output.status.message);
391         resolve(response);
392       }, err => {
393         response.status(500).send(err);
394         resolve(response);
395       });
396     });
397   }
398
399   async downloadFileFromBlueprintProcessorGrpc(blueprintName: string, blueprintVersion: string, response: Response): Promise<Response> {
400     return new Promise<Response>((resolve, reject) => {
401       bluePrintManagementServiceGrpcClient.downloadBlueprint(blueprintName, blueprintVersion)
402         .then(output => {
403           response.send(output.status.message);
404           resolve(response);
405         }, err => {
406           response.status(500).send(err);
407           resolve(response);
408         });
409     });
410   }
411 }