diff --git a/.env.dist b/.env.dist index 4b27c80..eeede43 100644 --- a/.env.dist +++ b/.env.dist @@ -7,6 +7,7 @@ DATABASE_URL="postgresql://auth:auth@v3-auth-db:5432/auth?schema=public" # RABBIT MQ RMQ_URI=amqp://v3-broker:5672 +RMQ_EXCHANGE=mobicoop # POSTGRES POSTGRES_IMAGE=postgres:15.0 diff --git a/.env.test b/.env.test index 73b84ba..243a253 100644 --- a/.env.test +++ b/.env.test @@ -5,9 +5,6 @@ SERVICE_PORT=5002 # PRISMA DATABASE_URL="postgresql://auth:auth@localhost:5602/auth?schema=public" -# RABBIT MQ -RMQ_URI=amqp://v3-broker:5672 - # POSTGRES POSTGRES_IMAGE=postgres:15.0 diff --git a/src/modules/authentication/adapters/primaries/authentication-messager.controller.ts b/src/modules/authentication/adapters/primaries/authentication-messager.controller.ts index 1f64072..baa2d89 100644 --- a/src/modules/authentication/adapters/primaries/authentication-messager.controller.ts +++ b/src/modules/authentication/adapters/primaries/authentication-messager.controller.ts @@ -12,9 +12,7 @@ export class AuthenticationMessagerController { constructor(private readonly _commandBus: CommandBus) {} @RabbitSubscribe({ - exchange: 'user', - routingKey: 'update', - queue: 'authentication-user-update', + name: 'user-update', }) public async userUpdatedHandler(message: string) { const updatedUser = JSON.parse(message); @@ -40,9 +38,7 @@ export class AuthenticationMessagerController { } @RabbitSubscribe({ - exchange: 'user', - routingKey: 'delete', - queue: 'authentication-user-delete', + name: 'user-delete', }) public async userDeletedHandler(message: string) { const deletedUser = JSON.parse(message); diff --git a/src/modules/authentication/adapters/secondaries/logging.messager.ts b/src/modules/authentication/adapters/secondaries/logging.messager.ts deleted file mode 100644 index 00988ec..0000000 --- a/src/modules/authentication/adapters/secondaries/logging.messager.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { Injectable } from '@nestjs/common'; -import { IMessageBroker } from '../../domain/interfaces/message-broker'; - -@Injectable() -export class LoggingMessager extends IMessageBroker { - constructor(private readonly _amqpConnection: AmqpConnection) { - super('logging'); - } - - publish(routingKey: string, message: string): void { - this._amqpConnection.publish(this.exchange, routingKey, message); - } -} diff --git a/src/modules/authentication/adapters/secondaries/authentication.messager.ts b/src/modules/authentication/adapters/secondaries/messager.ts similarity index 56% rename from src/modules/authentication/adapters/secondaries/authentication.messager.ts rename to src/modules/authentication/adapters/secondaries/messager.ts index 7364946..0ee32e3 100644 --- a/src/modules/authentication/adapters/secondaries/authentication.messager.ts +++ b/src/modules/authentication/adapters/secondaries/messager.ts @@ -1,11 +1,15 @@ import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; import { Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; import { IMessageBroker } from '../../domain/interfaces/message-broker'; @Injectable() -export class AuthenticationMessager extends IMessageBroker { - constructor(private readonly _amqpConnection: AmqpConnection) { - super('auth'); +export class Messager extends IMessageBroker { + constructor( + private readonly _amqpConnection: AmqpConnection, + configService: ConfigService, + ) { + super(configService.get('RMQ_EXCHANGE')); } publish(routingKey: string, message: string): void { diff --git a/src/modules/authentication/authentication.module.ts b/src/modules/authentication/authentication.module.ts index 7ea4794..a6a1386 100644 --- a/src/modules/authentication/authentication.module.ts +++ b/src/modules/authentication/authentication.module.ts @@ -15,7 +15,7 @@ import { DeleteAuthenticationUseCase } from './domain/usecases/delete-authentica import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { AuthenticationMessagerController } from './adapters/primaries/authentication-messager.controller'; -import { LoggingMessager } from './adapters/secondaries/logging.messager'; +import { Messager } from './adapters/secondaries/messager'; @Module({ imports: [ @@ -27,14 +27,20 @@ import { LoggingMessager } from './adapters/secondaries/logging.messager'; useFactory: async (configService: ConfigService) => ({ exchanges: [ { - name: 'user', - type: 'topic', - }, - { - name: 'logging', + name: configService.get('RMQ_EXCHANGE'), type: 'topic', }, ], + handlers: { + userUpdate: { + exchange: configService.get('RMQ_EXCHANGE'), + routingKey: 'user.update', + }, + userDelete: { + exchange: configService.get('RMQ_EXCHANGE'), + routingKey: 'user.delete', + }, + }, uri: configService.get('RMQ_URI'), connectionInitOptions: { wait: false }, enableControllerDiscovery: true, @@ -46,7 +52,7 @@ import { LoggingMessager } from './adapters/secondaries/logging.messager'; AuthenticationProfile, UsernameProfile, AuthenticationRepository, - LoggingMessager, + Messager, ValidateAuthenticationUseCase, CreateAuthenticationUseCase, AddUsernameUseCase, diff --git a/src/modules/authentication/domain/usecases/add-username.usecase.ts b/src/modules/authentication/domain/usecases/add-username.usecase.ts index 57752d5..e4bf622 100644 --- a/src/modules/authentication/domain/usecases/add-username.usecase.ts +++ b/src/modules/authentication/domain/usecases/add-username.usecase.ts @@ -1,5 +1,5 @@ import { CommandHandler } from '@nestjs/cqrs'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { AddUsernameCommand } from '../../commands/add-username.command'; import { Username } from '../entities/username'; @@ -8,7 +8,7 @@ import { Username } from '../entities/username'; export class AddUsernameUseCase { constructor( private readonly _usernameRepository: UsernameRepository, - private readonly _loggingMessager: LoggingMessager, + private readonly _messager: Messager, ) {} async execute(command: AddUsernameCommand): Promise { @@ -20,8 +20,8 @@ export class AddUsernameUseCase { username, }); } catch (error) { - this._loggingMessager.publish( - 'auth.username.add.warning', + this._messager.publish( + 'logging.auth.username.add.warning', JSON.stringify({ command, error, diff --git a/src/modules/authentication/domain/usecases/create-authentication.usecase.ts b/src/modules/authentication/domain/usecases/create-authentication.usecase.ts index 7c83ff3..261ff87 100644 --- a/src/modules/authentication/domain/usecases/create-authentication.usecase.ts +++ b/src/modules/authentication/domain/usecases/create-authentication.usecase.ts @@ -4,14 +4,14 @@ import { CreateAuthenticationCommand } from '../../commands/create-authenticatio import { Authentication } from '../entities/authentication'; import * as bcrypt from 'bcrypt'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; @CommandHandler(CreateAuthenticationCommand) export class CreateAuthenticationUseCase { constructor( private readonly _authenticationRepository: AuthenticationRepository, private readonly _usernameRepository: UsernameRepository, - private readonly _loggingMessager: LoggingMessager, + private readonly _messager: Messager, ) {} async execute(command: CreateAuthenticationCommand): Promise { @@ -31,8 +31,8 @@ export class CreateAuthenticationUseCase { return auth; } catch (error) { - this._loggingMessager.publish( - 'auth.create.crit', + this._messager.publish( + 'logging.auth.create.crit', JSON.stringify({ command, error, diff --git a/src/modules/authentication/domain/usecases/delete-authentication.usecase.ts b/src/modules/authentication/domain/usecases/delete-authentication.usecase.ts index 791d05e..d0b3f8b 100644 --- a/src/modules/authentication/domain/usecases/delete-authentication.usecase.ts +++ b/src/modules/authentication/domain/usecases/delete-authentication.usecase.ts @@ -1,6 +1,6 @@ import { CommandHandler } from '@nestjs/cqrs'; import { AuthenticationRepository } from '../../adapters/secondaries/authentication.repository'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { DeleteAuthenticationCommand } from '../../commands/delete-authentication.command'; @@ -9,7 +9,7 @@ export class DeleteAuthenticationUseCase { constructor( private readonly _authenticationRepository: AuthenticationRepository, private readonly _usernameRepository: UsernameRepository, - private readonly _loggingMessager: LoggingMessager, + private readonly _messager: Messager, ) {} async execute(command: DeleteAuthenticationCommand) { @@ -21,8 +21,8 @@ export class DeleteAuthenticationUseCase { command.deleteAuthenticationRequest.uuid, ); } catch (error) { - this._loggingMessager.publish( - 'auth.delete.crit', + this._messager.publish( + 'logging.auth.delete.crit', JSON.stringify({ command, error, diff --git a/src/modules/authentication/domain/usecases/delete-username.usecase.ts b/src/modules/authentication/domain/usecases/delete-username.usecase.ts index 9000d3a..5dbb3fb 100644 --- a/src/modules/authentication/domain/usecases/delete-username.usecase.ts +++ b/src/modules/authentication/domain/usecases/delete-username.usecase.ts @@ -1,6 +1,6 @@ import { UnauthorizedException } from '@nestjs/common'; import { CommandHandler } from '@nestjs/cqrs'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { DeleteUsernameCommand } from '../../commands/delete-username.command'; @@ -8,7 +8,7 @@ import { DeleteUsernameCommand } from '../../commands/delete-username.command'; export class DeleteUsernameUseCase { constructor( private readonly _usernameRepository: UsernameRepository, - private readonly _loggingMessager: LoggingMessager, + private readonly _messager: Messager, ) {} async execute(command: DeleteUsernameCommand) { @@ -25,8 +25,8 @@ export class DeleteUsernameUseCase { } throw new UnauthorizedException(); } catch (error) { - this._loggingMessager.publish( - 'auth.username.delete.warning', + this._messager.publish( + 'logging.auth.username.delete.warning', JSON.stringify({ command, error, diff --git a/src/modules/authentication/domain/usecases/update-password.usecase.ts b/src/modules/authentication/domain/usecases/update-password.usecase.ts index 0f6f8eb..f850ac5 100644 --- a/src/modules/authentication/domain/usecases/update-password.usecase.ts +++ b/src/modules/authentication/domain/usecases/update-password.usecase.ts @@ -3,13 +3,13 @@ import { AuthenticationRepository } from '../../adapters/secondaries/authenticat import { Authentication } from '../entities/authentication'; import * as bcrypt from 'bcrypt'; import { UpdatePasswordCommand } from '../../commands/update-password.command'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; @CommandHandler(UpdatePasswordCommand) export class UpdatePasswordUseCase { constructor( private readonly _authenticationRepository: AuthenticationRepository, - private readonly _loggingMessager: LoggingMessager, + private readonly _messager: Messager, ) {} async execute(command: UpdatePasswordCommand): Promise { @@ -21,8 +21,8 @@ export class UpdatePasswordUseCase { password: hash, }); } catch (error) { - this._loggingMessager.publish( - 'auth.password.update.warning', + this._messager.publish( + 'logging.auth.password.update.warning', JSON.stringify({ command, error, diff --git a/src/modules/authentication/domain/usecases/update-username.usecase.ts b/src/modules/authentication/domain/usecases/update-username.usecase.ts index 35c51ac..c3d9882 100644 --- a/src/modules/authentication/domain/usecases/update-username.usecase.ts +++ b/src/modules/authentication/domain/usecases/update-username.usecase.ts @@ -2,7 +2,7 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { BadRequestException } from '@nestjs/common'; import { CommandBus, CommandHandler } from '@nestjs/cqrs'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { AddUsernameCommand } from '../../commands/add-username.command'; import { UpdateUsernameCommand } from '../../commands/update-username.command'; @@ -16,7 +16,7 @@ export class UpdateUsernameUseCase { private readonly _usernameRepository: UsernameRepository, private readonly _commandBus: CommandBus, @InjectMapper() private readonly _mapper: Mapper, - private readonly _loggingMessager: LoggingMessager, + private readonly _messager: Messager, ) {} async execute(command: UpdateUsernameCommand): Promise { @@ -41,8 +41,8 @@ export class UpdateUsernameUseCase { }, ); } catch (error) { - this._loggingMessager.publish( - 'auth.username.update.warning', + this._messager.publish( + 'logging.auth.username.update.warning', JSON.stringify({ command, error, diff --git a/src/modules/authentication/tests/unit/add-username.usecase.spec.ts b/src/modules/authentication/tests/unit/add-username.usecase.spec.ts index a46f35e..4c5ddde 100644 --- a/src/modules/authentication/tests/unit/add-username.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/add-username.usecase.spec.ts @@ -8,7 +8,7 @@ import { Type } from '../../domain/dtos/type.enum'; import { AddUsernameRequest } from '../../domain/dtos/add-username.request'; import { AddUsernameCommand } from '../../commands/add-username.command'; import { AddUsernameUseCase } from '../../domain/usecases/add-username.usecase'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; const addUsernameRequest: AddUsernameRequest = { uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', @@ -46,7 +46,7 @@ describe('AddUsernameUseCase', () => { useValue: mockUsernameRepository, }, { - provide: LoggingMessager, + provide: Messager, useValue: mockMessager, }, AddUsernameUseCase, diff --git a/src/modules/authentication/tests/unit/create-authentication.usecase.spec.ts b/src/modules/authentication/tests/unit/create-authentication.usecase.spec.ts index a223f69..2ee6e9c 100644 --- a/src/modules/authentication/tests/unit/create-authentication.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/create-authentication.usecase.spec.ts @@ -9,7 +9,7 @@ import { CreateAuthenticationUseCase } from '../../domain/usecases/create-authen import * as bcrypt from 'bcrypt'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { Type } from '../../domain/dtos/type.enum'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; const newAuthenticationRequest: CreateAuthenticationRequest = new CreateAuthenticationRequest(); @@ -62,7 +62,7 @@ describe('CreateAuthenticationUseCase', () => { useValue: mockUsernameRepository, }, { - provide: LoggingMessager, + provide: Messager, useValue: mockMessager, }, CreateAuthenticationUseCase, diff --git a/src/modules/authentication/tests/unit/delete-authentication.usecase.spec.ts b/src/modules/authentication/tests/unit/delete-authentication.usecase.spec.ts index dd81688..f3bda36 100644 --- a/src/modules/authentication/tests/unit/delete-authentication.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/delete-authentication.usecase.spec.ts @@ -2,7 +2,7 @@ import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; import { AuthenticationRepository } from '../../adapters/secondaries/authentication.repository'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { DeleteAuthenticationCommand } from '../../commands/delete-authentication.command'; import { DeleteAuthenticationRequest } from '../../domain/dtos/delete-authentication.request'; @@ -69,7 +69,7 @@ describe('DeleteAuthenticationUseCase', () => { useValue: mockUsernameRepository, }, { - provide: LoggingMessager, + provide: Messager, useValue: mockMessager, }, DeleteAuthenticationUseCase, diff --git a/src/modules/authentication/tests/unit/delete-username.usecase.spec.ts b/src/modules/authentication/tests/unit/delete-username.usecase.spec.ts index 501cabd..854479e 100644 --- a/src/modules/authentication/tests/unit/delete-username.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/delete-username.usecase.spec.ts @@ -2,7 +2,7 @@ import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { UnauthorizedException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { DeleteUsernameCommand } from '../../commands/delete-username.command'; import { DeleteUsernameRequest } from '../../domain/dtos/delete-username.request'; @@ -82,7 +82,7 @@ describe('DeleteUsernameUseCase', () => { useValue: mockUsernameRepository, }, { - provide: LoggingMessager, + provide: Messager, useValue: mockMessager, }, DeleteUsernameUseCase, diff --git a/src/modules/authentication/tests/unit/logging.messager.usecase.spec.ts b/src/modules/authentication/tests/unit/logging.messager.usecase.spec.ts deleted file mode 100644 index 8836fc7..0000000 --- a/src/modules/authentication/tests/unit/logging.messager.usecase.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { Test, TestingModule } from '@nestjs/testing'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; - -const mockAmqpConnection = { - publish: jest.fn().mockImplementation(), -}; - -describe('LoggingMessager', () => { - let loggingMessager: LoggingMessager; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - LoggingMessager, - { - provide: AmqpConnection, - useValue: mockAmqpConnection, - }, - ], - }).compile(); - - loggingMessager = module.get(LoggingMessager); - }); - - it('should be defined', () => { - expect(LoggingMessager).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockAmqpConnection, 'publish'); - await loggingMessager.publish('authentication.create.info', 'my-test'); - expect(mockAmqpConnection.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/src/modules/authentication/tests/unit/authentication.messager.usecase.spec.ts b/src/modules/authentication/tests/unit/messager.spec.ts similarity index 55% rename from src/modules/authentication/tests/unit/authentication.messager.usecase.spec.ts rename to src/modules/authentication/tests/unit/messager.spec.ts index 01f28a7..97107d1 100644 --- a/src/modules/authentication/tests/unit/authentication.messager.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/messager.spec.ts @@ -1,41 +1,47 @@ import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; +import { ConfigService } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; -import { AuthenticationMessager } from '../../adapters/secondaries/authentication.messager'; +import { Messager } from '../../adapters/secondaries/messager'; const mockAmqpConnection = { publish: jest.fn().mockImplementation(), }; -describe('AuthenticationMessager', () => { - let authenticationMessager: AuthenticationMessager; +const mockConfigService = { + get: jest.fn().mockResolvedValue({ + RMQ_EXCHANGE: 'mobicoop', + }), +}; + +describe('Messager', () => { + let messager: Messager; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [], providers: [ - AuthenticationMessager, + Messager, { provide: AmqpConnection, useValue: mockAmqpConnection, }, + { + provide: ConfigService, + useValue: mockConfigService, + }, ], }).compile(); - authenticationMessager = module.get( - AuthenticationMessager, - ); + messager = module.get(Messager); }); it('should be defined', () => { - expect(authenticationMessager).toBeDefined(); + expect(messager).toBeDefined(); }); it('should publish a message', async () => { jest.spyOn(mockAmqpConnection, 'publish'); - await authenticationMessager.publish( - 'authentication.create.info', - 'my-test', - ); + messager.publish('authentication.create.info', 'my-test'); expect(mockAmqpConnection.publish).toHaveBeenCalledTimes(1); }); }); diff --git a/src/modules/authentication/tests/unit/update-password.usecase.spec.ts b/src/modules/authentication/tests/unit/update-password.usecase.spec.ts index 38ed6ac..982ea1e 100644 --- a/src/modules/authentication/tests/unit/update-password.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/update-password.usecase.spec.ts @@ -7,7 +7,7 @@ import * as bcrypt from 'bcrypt'; import { UpdatePasswordRequest } from '../../domain/dtos/update-password.request'; import { UpdatePasswordCommand } from '../../commands/update-password.command'; import { UpdatePasswordUseCase } from '../../domain/usecases/update-password.usecase'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; const updatePasswordRequest: UpdatePasswordRequest = new UpdatePasswordRequest(); @@ -46,7 +46,7 @@ describe('UpdatePasswordUseCase', () => { useValue: mockAuthenticationRepository, }, { - provide: LoggingMessager, + provide: Messager, useValue: mockMessager, }, UpdatePasswordUseCase, diff --git a/src/modules/authentication/tests/unit/update-username.usecase.spec.ts b/src/modules/authentication/tests/unit/update-username.usecase.spec.ts index 084a6b6..ca3f8b3 100644 --- a/src/modules/authentication/tests/unit/update-username.usecase.spec.ts +++ b/src/modules/authentication/tests/unit/update-username.usecase.spec.ts @@ -10,7 +10,7 @@ import { UpdateUsernameUseCase } from '../../domain/usecases/update-username.use import { CommandBus } from '@nestjs/cqrs'; import { UsernameProfile } from '../../mappers/username.profile'; import { BadRequestException } from '@nestjs/common'; -import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; +import { Messager } from '../../adapters/secondaries/messager'; const existingUsername = { uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', @@ -100,7 +100,7 @@ describe('UpdateUsernameUseCase', () => { useValue: mockAddUsernameCommand, }, { - provide: LoggingMessager, + provide: Messager, useValue: mockMessager, }, UpdateUsernameUseCase,