From d8ce82793dce222b3f79dba3bcf0715e0739715d Mon Sep 17 00:00:00 2001 From: Gabriel Rosa Date: Thu, 11 Aug 2022 17:39:50 -0300 Subject: [PATCH] REFACTOR: removed inputs separated client service --- src/clients/inputs/client.config.ts | 25 -- src/clients/inputs/client.service.ts | 239 --------------- .../inputs/dtos/old_interfaces.ts} | 0 src/modules/inputs/inputs.controller.ts | 7 +- src/modules/inputs/inputs.module.ts | 3 +- src/modules/inputs/inputs.service.ts | 276 ++++++++++++++++-- src/modules/oauth/oauth.controller.ts | 1 - 7 files changed, 257 insertions(+), 294 deletions(-) delete mode 100644 src/clients/inputs/client.config.ts delete mode 100644 src/clients/inputs/client.service.ts rename src/{clients/inputs/interfaces.d.ts => modules/inputs/dtos/old_interfaces.ts} (100%) diff --git a/src/clients/inputs/client.config.ts b/src/clients/inputs/client.config.ts deleted file mode 100644 index 525b5eb..0000000 --- a/src/clients/inputs/client.config.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { credentials } from '@grpc/grpc-js'; -import { ClientOptions, Transport } from '@nestjs/microservices'; - -import { InputPackages, InputProtoFilePath } from 'protospack'; - -export class InputsClientConfiguration { - config(): ClientOptions { - return { - transport: Transport.GRPC, - options: { - url: process.env.INFACTORY_URL, - package: InputPackages, - credentials: process.env.LOCAL_ENV - ? undefined - : credentials.createSsl(), - protoPath: InputProtoFilePath, - loader: { - enums: String, - objects: true, - arrays: true, - }, - }, - }; - } -} diff --git a/src/clients/inputs/client.service.ts b/src/clients/inputs/client.service.ts deleted file mode 100644 index 758213a..0000000 --- a/src/clients/inputs/client.service.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { - OnModuleInit, - Inject, - HttpException, - HttpStatus, - NotFoundException, - InternalServerErrorException, -} from '@nestjs/common'; -import { ClientGrpc } from '@nestjs/microservices'; -import { - DecodeGrpcStruct, - EncodeJsonToGrpcStruct, - InputCreateS3Request, - InputNewCreateRequest, - InputService, - TestConnectionGetColumnsRequest, - TestConnectionRequest, -} from 'protospack'; -import { lastValueFrom } from 'rxjs'; -import { - objectCamelToSnake, - objectSnakeToCamel, -} from 'src/utils/CaseConverter'; -import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { IIdRequest, UpdateInputRequest } from './interfaces'; - -export class InputsClientService implements OnModuleInit { - private inputService: InputService; - logger: DadosferaLogger; - constructor( - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, - @Inject('InputsGrpcClient') private readonly grpcClient: ClientGrpc, - ) { - this.logger = dadosferaLogger.logger; - } - - async onModuleInit() { - this.inputService = - this.grpcClient.getService('InputService'); - } - - async newCreate(createInputDto: InputNewCreateRequest) { - this.logger.info('InputClientService - Create'); - - const input = await lastValueFrom( - this.inputService.NewCreate(objectSnakeToCamel(createInputDto)), - ); - objectCamelToSnake(input); - return input; - } - - async createGeneric(createInputGeneric) { - this.logger.info('InputClientService - Create'); - const { info, ...data } = createInputGeneric; - if (data.options) delete data.options; - if (data.credentials.oauth_code) delete data.credentials.oauth_code; - const grpcPayload = { - input: EncodeJsonToGrpcStruct(data), - info, - }; - objectSnakeToCamel(grpcPayload); - - const structReturn = await lastValueFrom( - this.inputService.Create(grpcPayload), - ).catch((err: { details: string }) => { - if (err.details === 'Item Not found!') { - throw new NotFoundException('Input not found'); - } - throw new InternalServerErrorException(err.details); - }); - objectCamelToSnake(structReturn); - const inputCreated = DecodeGrpcStruct(structReturn.input); - return { input: inputCreated }; - } - - async createS3Inputs(createInputDto: InputCreateS3Request) { - this.logger.info('InputClientService - Create'); - objectSnakeToCamel(createInputDto); - const createInputResponse = await lastValueFrom( - this.inputService.CreateS3(createInputDto), - ).catch((e) => { - throw new HttpException(e.details, 500); - }); - this.logger.info('Done'); - objectCamelToSnake(createInputResponse); - return createInputResponse; - } - - async findOne(data: IIdRequest) { - this.logger.info('InputClientService - FindOne'); - const findOneInputResponse = await lastValueFrom( - this.inputService.FindOne(objectSnakeToCamel(data)), - ).catch((e) => { - this.logger.error(e.details); - throw new HttpException(e.details, HttpStatus.INTERNAL_SERVER_ERROR); - }); - objectCamelToSnake(findOneInputResponse); - return findOneInputResponse; - } - - async findAll(data) { - this.logger.info('InputClientService - FindAll'); - const findAllInputResponse = await lastValueFrom( - this.inputService.FindAll(objectSnakeToCamel(data)), - ).catch((e) => { - this.logger.error(e.details); - throw new HttpException(e.details, HttpStatus.INTERNAL_SERVER_ERROR); - }); - findAllInputResponse.inputs.forEach((input) => objectCamelToSnake(input)); - - return findAllInputResponse; - } - - async update(updateInputDTO: UpdateInputRequest) { - this.logger.info('InputClientService - Update'); - const updateInputResponse = await new Promise((resolve, reject) => { - this.inputService.Update(objectSnakeToCamel(updateInputDTO)).subscribe({ - next(x) { - resolve(objectCamelToSnake(x)); - }, - error(err) { - reject(err); - }, - complete() { - // console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err.message); - throw new Error(err); - }); - - return updateInputResponse; - } - - async remove(idRequest: IIdRequest) { - this.logger.info('InputClientService - Remove'); - - const removeInputResponse = await new Promise((resolve, reject) => { - this.inputService.Remove(objectSnakeToCamel(idRequest)).subscribe({ - next(x) { - resolve(objectCamelToSnake(x)); - }, - error(err) { - reject(err); - }, - complete() { - // console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err.message); - throw new Error(err); - }); - - return removeInputResponse; - } - - async testConnection(data: TestConnectionRequest) { - this.logger.info('InputClientService - TestConnection'); - const testConnectionResponse = await new Promise((resolve, reject) => { - this.inputService.NewTestConnection(objectSnakeToCamel(data)).subscribe({ - next(x) { - resolve(objectCamelToSnake(x)); - }, - error(err) { - reject(err); - }, - complete() { - // console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err.message); - throw new Error(err); - }); - - return testConnectionResponse; - } - - async getColumns(data: TestConnectionGetColumnsRequest) { - this.logger.info('InputClientService - TestConnection/Get-Columns'); - const getColumnsResponse = await new Promise((resolve, reject) => { - this.inputService.GetColumns(objectSnakeToCamel(data)).subscribe({ - next(x) { - resolve(objectCamelToSnake(x)); - }, - error(err) { - reject(err); - }, - complete() { - // console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err.message); - throw new Error(err); - }); - - return getColumnsResponse; - } - - async getAvailableEntities(data) { - this.logger.info('InputClientService - GetAvailableEntities'); - objectSnakeToCamel(data); - const response = await lastValueFrom( - this.inputService.GetAvailableEntities(data), - ).catch((err) => { - this.logger.info(err.details); - if (err.details && err.details.includes('400')) - throw new HttpException('Plugin inválido', HttpStatus.BAD_REQUEST); - throw new HttpException(err.details, HttpStatus.INTERNAL_SERVER_ERROR); - }); - objectCamelToSnake(response); - - return response; - } -} diff --git a/src/clients/inputs/interfaces.d.ts b/src/modules/inputs/dtos/old_interfaces.ts similarity index 100% rename from src/clients/inputs/interfaces.d.ts rename to src/modules/inputs/dtos/old_interfaces.ts diff --git a/src/modules/inputs/inputs.controller.ts b/src/modules/inputs/inputs.controller.ts index c464b9d..a512056 100644 --- a/src/modules/inputs/inputs.controller.ts +++ b/src/modules/inputs/inputs.controller.ts @@ -10,8 +10,6 @@ import { } from '@nestjs/common'; import { InputsService } from './inputs.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { InputsClientService } from 'src/clients/inputs/client.service'; -import { UpdateInputRequest } from 'src/clients/inputs/interfaces'; import { PERMISSIONS } from '../../authentication/permissions.enum'; import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; @@ -25,6 +23,7 @@ import { TestConnectionReq, TestConnectionRes, } from './dtos/input.model'; +import { UpdateInputRequest } from './dtos/old_interfaces'; @ApiTags('inputs') @Controller('inputs') @@ -58,15 +57,13 @@ import { return user.permissions.includes(PERMISSIONS.INPUT.permissions[action].seqid); }) export class InputsController { - inputService: InputsService; logger: DadosferaLogger; constructor( @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, - private inputsClientService: InputsClientService, + private inputService: InputsService, ) { this.logger = dadosferaLogger.logger; - this.inputService = new InputsService(this.inputsClientService); } @Get('available-entities/:plugin') diff --git a/src/modules/inputs/inputs.module.ts b/src/modules/inputs/inputs.module.ts index 3dcc052..4f961c6 100644 --- a/src/modules/inputs/inputs.module.ts +++ b/src/modules/inputs/inputs.module.ts @@ -4,13 +4,12 @@ import { InputsGrpcClient } from './inputs-client.config'; import { InputsController } from './inputs.controller'; import { InputsService } from './inputs.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { InputsClientService } from 'src/clients/inputs/client.service'; const client = new InputsGrpcClient(); @Module({ controllers: [InputsController], - providers: [InputsService, InputsClientService, DadosferaLogger], + providers: [InputsService, DadosferaLogger], imports: [ClientsModule.register([client.providerOptions])], exports: [InputsService], }) diff --git a/src/modules/inputs/inputs.service.ts b/src/modules/inputs/inputs.service.ts index 2cc63b9..e7d4353 100644 --- a/src/modules/inputs/inputs.service.ts +++ b/src/modules/inputs/inputs.service.ts @@ -1,14 +1,247 @@ -import { Body, HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { + Body, + ForbiddenException, + HttpException, + HttpStatus, + Inject, + Injectable, + InternalServerErrorException, + NotFoundException, +} from '@nestjs/common'; import { Timeout } from '@nestjs/schedule'; -import { DecodeGrpcStruct } from 'protospack'; +import { + DecodeGrpcStruct, + EncodeJsonToGrpcStruct, + InputCreateS3Request, + InputNewCreateRequest, + InputService, + InputServicesNames, + TestConnectionGetColumnsRequest, + TestConnectionRequest, +} from 'protospack'; import CronParser, { CronExpression } from 'cron-parser'; -import { InputsClientService } from 'src/clients/inputs/client.service'; -import { IIdRequest } from 'src/clients/inputs/interfaces'; import { Info } from 'protospack/dist/lib/interfaces'; +import { ClientGrpc } from '@nestjs/microservices'; +import DadosferaLogger from '@dadosfera/dadosfera-logs/dist'; +import { lastValueFrom } from 'rxjs'; +import { + objectSnakeToCamel, + objectCamelToSnake, +} from 'src/utils/CaseConverter'; +import { IIdRequest, UpdateInputRequest } from './dtos/old_interfaces'; @Injectable() + +//TODO refactor this class to remove OLD_inputClient export class InputsService { - constructor(private inputClient: InputsClientService) {} + logger: DadosferaLogger; + inputService: InputService; + OLD_inputClient = { + newCreate: async (createInputDto: InputNewCreateRequest) => { + this.logger.info('InputClientService - Create'); + + const input = await lastValueFrom( + this.inputService.NewCreate(objectSnakeToCamel(createInputDto)), + ); + objectCamelToSnake(input); + return input; + }, + createGeneric: async (createInputGeneric) => { + this.logger.info('InputClientService - Create'); + const { info, ...data } = createInputGeneric; + if (data.options) delete data.options; + if (data.credentials.oauth_code) delete data.credentials.oauth_code; + const grpcPayload = { + input: EncodeJsonToGrpcStruct(data), + info, + }; + objectSnakeToCamel(grpcPayload); + + const structReturn = await lastValueFrom( + this.inputService.Create(grpcPayload), + ).catch((err: { details: string }) => { + if (err.details === 'Item Not found!') { + throw new NotFoundException('Input not found'); + } + throw new InternalServerErrorException(err.details); + }); + objectCamelToSnake(structReturn); + const inputCreated = DecodeGrpcStruct(structReturn.input); + return { input: inputCreated }; + }, + createS3Inputs: async (createInputDto: InputCreateS3Request) => { + this.logger.info('InputClientService - Create'); + objectSnakeToCamel(createInputDto); + const createInputResponse = await lastValueFrom( + this.inputService.CreateS3(createInputDto), + ).catch((e) => { + throw new HttpException(e.details, 500); + }); + this.logger.info('Done'); + objectCamelToSnake(createInputResponse); + return createInputResponse; + }, + findOne: async (data: IIdRequest) => { + this.logger.info('InputClientService - FindOne'); + const findOneInputResponse = await lastValueFrom( + this.inputService.FindOne(objectSnakeToCamel(data)), + ).catch((e) => { + this.logger.error(e.details); + throw new HttpException(e.details, HttpStatus.INTERNAL_SERVER_ERROR); + }); + objectCamelToSnake(findOneInputResponse); + return findOneInputResponse; + }, + findAll: async (data) => { + this.logger.info('InputClientService - FindAll'); + const findAllInputResponse = await lastValueFrom( + this.inputService.FindAll(objectSnakeToCamel(data)), + ).catch((e) => { + this.logger.error(e.details); + throw new HttpException(e.details, HttpStatus.INTERNAL_SERVER_ERROR); + }); + findAllInputResponse.inputs.forEach((input) => objectCamelToSnake(input)); + + return findAllInputResponse; + }, + update: async (updateInputDTO: UpdateInputRequest) => { + this.logger.info('InputClientService - Update'); + const updateInputResponse = await new Promise((resolve, reject) => { + this.inputService.Update(objectSnakeToCamel(updateInputDTO)).subscribe({ + next(x) { + resolve(objectCamelToSnake(x)); + }, + error(err) { + reject(err); + }, + complete() { + // console.log('done'); + }, + }); + }) + .then((res) => { + this.logger.info('Done'); + return res; + }) + .catch((err) => { + this.logger.error(err.message); + throw new Error(err); + }); + + return updateInputResponse; + }, + remove: async (idRequest: IIdRequest) => { + this.logger.info('InputClientService - Remove'); + + const removeInputResponse = await new Promise((resolve, reject) => { + this.inputService.Remove(objectSnakeToCamel(idRequest)).subscribe({ + next(x) { + resolve(objectCamelToSnake(x)); + }, + error(err) { + reject(err); + }, + complete() { + // console.log('done'); + }, + }); + }) + .then((res) => { + this.logger.info('Done'); + return res; + }) + .catch((err) => { + this.logger.error(err.message); + throw new Error(err); + }); + + return removeInputResponse; + }, + testConnection: async (data: TestConnectionRequest) => { + this.logger.info('InputClientService - TestConnection'); + const testConnectionResponse = await new Promise((resolve, reject) => { + this.inputService + .NewTestConnection(objectSnakeToCamel(data)) + .subscribe({ + next(x) { + resolve(objectCamelToSnake(x)); + }, + error(err) { + reject(err); + }, + complete() { + // console.log('done'); + }, + }); + }) + .then((res) => { + this.logger.info('Done'); + return res; + }) + .catch((err) => { + this.logger.error(err.message); + throw new Error(err); + }); + + return testConnectionResponse; + }, + getColumns: async (data: TestConnectionGetColumnsRequest) => { + this.logger.info('InputClientService - TestConnection/Get-Columns'); + const getColumnsResponse = await new Promise((resolve, reject) => { + this.inputService.GetColumns(objectSnakeToCamel(data)).subscribe({ + next(x) { + resolve(objectCamelToSnake(x)); + }, + error(err) { + reject(err); + }, + complete() { + // console.log('done'); + }, + }); + }) + .then((res) => { + this.logger.info('Done'); + return res; + }) + .catch((err) => { + this.logger.error(err.message); + throw new Error(err); + }); + + return getColumnsResponse; + }, + getAvailableEntities: async (data) => { + this.logger.info('InputClientService - GetAvailableEntities'); + objectSnakeToCamel(data); + const response = await lastValueFrom( + this.inputService.GetAvailableEntities(data), + ).catch((err) => { + this.logger.info(err.details); + if (err.details && err.details.includes('400')) + throw new HttpException('Plugin inválido', HttpStatus.BAD_REQUEST); + throw new HttpException(err.details, HttpStatus.INTERNAL_SERVER_ERROR); + }); + objectCamelToSnake(response); + + return response; + }, + }; + + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + @Inject('InputsGrpcClient') private readonly grpcClient: ClientGrpc, + ) { + this.logger = dadosferaLogger.logger; + } + + async onModuleInit() { + this.inputService = this.grpcClient.getService( + InputServicesNames.InputService, + ); + } + secondsInADay = 60 * 60 * 24; secondsInAnHour = 60 * 60; @@ -38,14 +271,12 @@ export class InputsService { const afterNextDate = interval.next().toDate(); const secondsApart = this.getDifferenceInSeconds(nextDate, afterNextDate); if (customer_tier === 'BASIC' && secondsApart < this.secondsInADay) { - throw new HttpException( + throw new ForbiddenException( 'Intervalo de tempo não pode ser inferior a um dia.', - HttpStatus.FORBIDDEN, ); } else if (secondsApart < this.secondsInAnHour) { - throw new HttpException( + throw new ForbiddenException( 'Intervalo de tempo não pode ser inferior a uma hora.', - HttpStatus.FORBIDDEN, ); } } @@ -58,7 +289,7 @@ export class InputsService { case 'parquet': { const { info, ...input } = data; const inputPayload = this.generateInputS3Payload(input); - response = await this.inputClient.createS3Inputs({ + response = await this.OLD_inputClient.createS3Inputs({ input: inputPayload, info, }); @@ -68,10 +299,10 @@ export class InputsService { case 'mysql': case 'postgresql': case 'sqlserver': - response = await this.inputClient.newCreate(data); + response = await this.OLD_inputClient.newCreate(data); break; default: - response = await this.inputClient.createGeneric(data); + response = await this.OLD_inputClient.createGeneric(data); break; } const adjustedInput = this.adjustInputPayload(response.input); @@ -80,16 +311,18 @@ export class InputsService { async reCreate(data) { const { info, cron } = data; if (cron) this.validateCron({ info, cron }); - const response = await this.inputClient.createGeneric(data); + const response = await this.OLD_inputClient.createGeneric(data); const adjustedInput = this.adjustInputPayload(response.input); return { ...response, input: adjustedInput }; } async getAvailableEntities(data): Promise<{ entities: string[] }> { - return await this.inputClient.getAvailableEntities(data); + return await this.OLD_inputClient.getAvailableEntities(data); } async findAll(body) { try { - const findAllInputResponse: any = await this.inputClient.findAll(body); + const findAllInputResponse: any = await this.OLD_inputClient.findAll( + body, + ); if (findAllInputResponse?.inputs?.length) { findAllInputResponse.inputs = findAllInputResponse.inputs.map((input) => this.adjustInputPayload(input), @@ -103,7 +336,7 @@ export class InputsService { async findOne(idRequest: IIdRequest) { try { - const findOneInputResponse: any = await this.inputClient.findOne( + const findOneInputResponse: any = await this.OLD_inputClient.findOne( idRequest, ); findOneInputResponse.input = this.adjustInputPayload( @@ -118,7 +351,7 @@ export class InputsService { async update(id: string, data, info: Info) { this.validateCron({ ...data, info }); try { - const updateInputResponse: any = await this.inputClient.update({ + const updateInputResponse: any = await this.OLD_inputClient.update({ id, info, ...data, @@ -135,7 +368,7 @@ export class InputsService { async remove(idRequest: IIdRequest) { try { - const removeInputResponse = await this.inputClient.remove(idRequest); + const removeInputResponse = await this.OLD_inputClient.remove(idRequest); return removeInputResponse; } catch (err) { @@ -146,9 +379,8 @@ export class InputsService { @Timeout(60000 * 10) // Timeout set for 10 minutes async testConnection(data) { try { - const testConnectionInputResponse = await this.inputClient.testConnection( - data, - ); + const testConnectionInputResponse = + await this.OLD_inputClient.testConnection(data); return testConnectionInputResponse; } catch (err) { @@ -159,7 +391,7 @@ export class InputsService { async getColumns(data) { try { const testConnectionGetColumnsResponse = - await this.inputClient.getColumns(data); + await this.OLD_inputClient.getColumns(data); return testConnectionGetColumnsResponse; } catch (err) { diff --git a/src/modules/oauth/oauth.controller.ts b/src/modules/oauth/oauth.controller.ts index b02baa7..c879389 100644 --- a/src/modules/oauth/oauth.controller.ts +++ b/src/modules/oauth/oauth.controller.ts @@ -1,7 +1,6 @@ import { Controller, Get, Redirect, Req, UseGuards } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { AuthGuard } from '@nestjs/passport'; -import { InputsClientService } from 'src/clients/inputs/client.service'; import { InputsService } from '../inputs/inputs.service'; import { Request } from 'express';