send logging messages
This commit is contained in:
parent
a34d51a524
commit
60855dec99
|
@ -1,6 +1,6 @@
|
|||
import { Mapper } from '@automapper/core';
|
||||
import { InjectMapper } from '@automapper/nestjs';
|
||||
import { Controller } from '@nestjs/common';
|
||||
import { Controller, UsePipes } from '@nestjs/common';
|
||||
import { CommandBus, QueryBus } from '@nestjs/cqrs';
|
||||
import { GrpcMethod, RpcException } from '@nestjs/microservices';
|
||||
import { DatabaseException } from 'src/modules/database/src/exceptions/DatabaseException';
|
||||
|
@ -21,8 +21,15 @@ import { Auth } from '../../domain/entities/auth';
|
|||
import { Username } from '../../domain/entities/username';
|
||||
import { ValidateAuthQuery } from '../../queries/validate-auth.query';
|
||||
import { AuthPresenter } from './auth.presenter';
|
||||
import { RpcValidationPipe } from './rpc.validation-pipe';
|
||||
import { UsernamePresenter } from './username.presenter';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
whitelist: true,
|
||||
forbidUnknownValues: false,
|
||||
}),
|
||||
)
|
||||
@Controller()
|
||||
export class AuthController {
|
||||
constructor(
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import { AmqpConnection } from '@golevelup/nestjs-rabbitmq';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { IMessageBroker } from '../../domain/interfaces/message-broker';
|
||||
|
||||
@Injectable()
|
||||
export class AuthMessager extends IMessageBroker {
|
||||
constructor(private readonly _amqpConnection: AmqpConnection) {
|
||||
super('auth');
|
||||
}
|
||||
|
||||
publish(routingKey: string, message: string): void {
|
||||
this._amqpConnection.publish(this.exchange, routingKey, message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -28,6 +28,10 @@ import { AuthMessagerController } from './adapters/primaries/auth-messager.contr
|
|||
name: 'user',
|
||||
type: 'topic',
|
||||
},
|
||||
{
|
||||
name: 'logging',
|
||||
type: 'topic',
|
||||
},
|
||||
],
|
||||
uri: configService.get<string>('RMQ_URI'),
|
||||
enableControllerDiscovery: true,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export abstract class IMessageBroker {
|
||||
exchange: string;
|
||||
|
||||
constructor(exchange: string) {
|
||||
this.exchange = exchange;
|
||||
}
|
||||
|
||||
abstract publish(routingKey: string, message: string): void;
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { AddUsernameCommand } from '../../commands/add-username.command';
|
||||
import { Username } from '../entities/username';
|
||||
|
||||
@CommandHandler(AddUsernameCommand)
|
||||
export class AddUsernameUseCase {
|
||||
constructor(private readonly _usernameRepository: UsernameRepository) {}
|
||||
constructor(
|
||||
private readonly _usernameRepository: UsernameRepository,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: AddUsernameCommand): Promise<Username> {
|
||||
const { uuid, username, type } = command.addUsernameRequest;
|
||||
|
@ -15,8 +19,15 @@ export class AddUsernameUseCase {
|
|||
type,
|
||||
username,
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'auth.username.add.warning',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,14 @@ import { CreateAuthCommand } from '../../commands/create-auth.command';
|
|||
import { Auth } from '../entities/auth';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
|
||||
@CommandHandler(CreateAuthCommand)
|
||||
export class CreateAuthUseCase {
|
||||
constructor(
|
||||
private readonly _authRepository: AuthRepository,
|
||||
private readonly _usernameRepository: UsernameRepository,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: CreateAuthCommand): Promise<Auth> {
|
||||
|
@ -28,8 +30,15 @@ export class CreateAuthUseCase {
|
|||
});
|
||||
|
||||
return auth;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'auth.create.critical',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { AuthRepository } from '../../adapters/secondaries/auth.repository';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { DeleteAuthCommand } from '../../commands/delete-auth.command';
|
||||
|
||||
|
@ -8,6 +9,7 @@ export class DeleteAuthUseCase {
|
|||
constructor(
|
||||
private readonly _authRepository: AuthRepository,
|
||||
private readonly _usernameRepository: UsernameRepository,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: DeleteAuthCommand) {
|
||||
|
@ -18,8 +20,15 @@ export class DeleteAuthUseCase {
|
|||
return await this._authRepository.delete({
|
||||
uuid: command.deleteAuthRequest.uuid,
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'auth.delete.critical',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { UnauthorizedException } from '@nestjs/common';
|
||||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { DeleteUsernameCommand } from '../../commands/delete-username.command';
|
||||
|
||||
@CommandHandler(DeleteUsernameCommand)
|
||||
export class DeleteUsernameUseCase {
|
||||
constructor(private readonly _usernameRepository: UsernameRepository) {}
|
||||
constructor(
|
||||
private readonly _usernameRepository: UsernameRepository,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: DeleteUsernameCommand) {
|
||||
try {
|
||||
|
@ -20,8 +24,15 @@ export class DeleteUsernameUseCase {
|
|||
return await this._usernameRepository.delete({ username });
|
||||
}
|
||||
throw new UnauthorizedException();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'auth.username.delete.warning',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@ import { AuthRepository } from '../../adapters/secondaries/auth.repository';
|
|||
import { Auth } from '../entities/auth';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { UpdatePasswordCommand } from '../../commands/update-password.command';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
|
||||
@CommandHandler(UpdatePasswordCommand)
|
||||
export class UpdatePasswordUseCase {
|
||||
constructor(private readonly _authRepository: AuthRepository) {}
|
||||
constructor(
|
||||
private readonly _authRepository: AuthRepository,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: UpdatePasswordCommand): Promise<Auth> {
|
||||
const { uuid, password } = command.updatePasswordRequest;
|
||||
|
@ -16,8 +20,15 @@ export class UpdatePasswordUseCase {
|
|||
return await this._authRepository.update(uuid, {
|
||||
password: hash,
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'auth.password.update.warning',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +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 { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { AddUsernameCommand } from '../../commands/add-username.command';
|
||||
import { UpdateUsernameCommand } from '../../commands/update-username.command';
|
||||
|
@ -15,6 +16,7 @@ export class UpdateUsernameUseCase {
|
|||
private readonly _usernameRepository: UsernameRepository,
|
||||
private readonly _commandBus: CommandBus,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: UpdateUsernameCommand): Promise<Username> {
|
||||
|
@ -38,8 +40,15 @@ export class UpdateUsernameUseCase {
|
|||
username,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'auth.username.update.warning',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const addUsernameRequest = this._mapper.map(
|
||||
|
|
|
@ -8,6 +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';
|
||||
|
||||
const addUsernameRequest: AddUsernameRequest = {
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
|
@ -22,6 +23,10 @@ const mockUsernameRepository = {
|
|||
create: jest.fn().mockResolvedValue(addUsernameRequest),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('AddUsernameUseCase', () => {
|
||||
let addUsernameUseCase: AddUsernameUseCase;
|
||||
|
||||
|
@ -33,6 +38,10 @@ describe('AddUsernameUseCase', () => {
|
|||
provide: UsernameRepository,
|
||||
useValue: mockUsernameRepository,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
AddUsernameUseCase,
|
||||
AuthProfile,
|
||||
],
|
||||
|
|
|
@ -9,6 +9,7 @@ import { CreateAuthUseCase } from '../../domain/usecases/create-auth.usecase';
|
|||
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';
|
||||
|
||||
const newAuthRequest: CreateAuthRequest = {
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
|
@ -33,6 +34,10 @@ const mockUsernameRepository = {
|
|||
}),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('CreateAuthUseCase', () => {
|
||||
let createAuthUseCase: CreateAuthUseCase;
|
||||
|
||||
|
@ -48,6 +53,10 @@ describe('CreateAuthUseCase', () => {
|
|||
provide: UsernameRepository,
|
||||
useValue: mockUsernameRepository,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
CreateAuthUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
|
|
@ -2,6 +2,7 @@ import { classes } from '@automapper/classes';
|
|||
import { AutomapperModule } from '@automapper/nestjs';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AuthRepository } from '../../adapters/secondaries/auth.repository';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { DeleteAuthCommand } from '../../commands/delete-auth.command';
|
||||
import { DeleteAuthRequest } from '../../domain/dtos/delete-auth.request';
|
||||
|
@ -44,6 +45,10 @@ const mockUsernameRepository = {
|
|||
deleteMany: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('DeleteAuthUseCase', () => {
|
||||
let deleteAuthUseCase: DeleteAuthUseCase;
|
||||
|
||||
|
@ -59,6 +64,10 @@ describe('DeleteAuthUseCase', () => {
|
|||
provide: UsernameRepository,
|
||||
useValue: mockUsernameRepository,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
DeleteAuthUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
|
|
@ -2,6 +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 { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||
import { DeleteUsernameCommand } from '../../commands/delete-username.command';
|
||||
import { DeleteUsernameRequest } from '../../domain/dtos/delete-username.request';
|
||||
|
@ -65,6 +66,10 @@ const mockUsernameRepository = {
|
|||
delete: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('DeleteUsernameUseCase', () => {
|
||||
let deleteUsernameUseCase: DeleteUsernameUseCase;
|
||||
|
||||
|
@ -76,6 +81,10 @@ describe('DeleteUsernameUseCase', () => {
|
|||
provide: UsernameRepository,
|
||||
useValue: mockUsernameRepository,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
DeleteUsernameUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
|
|
@ -7,6 +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';
|
||||
|
||||
const updatePasswordRequest: UpdatePasswordRequest = {
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
|
@ -23,6 +24,10 @@ const mockAuthRepository = {
|
|||
}),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('UpdatePasswordUseCase', () => {
|
||||
let updatePasswordUseCase: UpdatePasswordUseCase;
|
||||
|
||||
|
@ -34,6 +39,10 @@ describe('UpdatePasswordUseCase', () => {
|
|||
provide: AuthRepository,
|
||||
useValue: mockAuthRepository,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
UpdatePasswordUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
|
|
@ -10,6 +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';
|
||||
|
||||
const existingUsername = {
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
|
@ -59,6 +60,10 @@ const mockAddUsernameCommand = {
|
|||
execute: jest.fn().mockResolvedValue(newUsernameRequest),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('UpdateUsernameUseCase', () => {
|
||||
let updateUsernameUseCase: UpdateUsernameUseCase;
|
||||
|
||||
|
@ -74,6 +79,10 @@ describe('UpdateUsernameUseCase', () => {
|
|||
provide: CommandBus,
|
||||
useValue: mockAddUsernameCommand,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
UpdateUsernameUseCase,
|
||||
UsernameProfile,
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue