plug to broker

This commit is contained in:
Gsk54
2023-01-26 10:41:57 +01:00
parent 85a03f23d8
commit 9d462a71cb
14 changed files with 519 additions and 3 deletions

View File

@@ -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 ConfigurationMessager extends IMessageBroker {
constructor(private readonly _amqpConnection: AmqpConnection) {
super('configuration');
}
publish(routingKey: string, message: string): void {
this._amqpConnection.publish(this.exchange, routingKey, message);
}
}

View File

@@ -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);
}
}

View File

@@ -1,8 +1,12 @@
import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CqrsModule } from '@nestjs/cqrs';
import { DatabaseModule } from '../database/database.module';
import { ConfigurationController } from './adapters/primaries/configuration.controller';
import { ConfigurationMessager } from './adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from './adapters/secondaries/configuration.repository';
import { LoggingMessager } from './adapters/secondaries/logging.messager';
import { CreateConfigurationUseCase } from './domain/usecases/create-configuration.usecase';
import { DeleteConfigurationUseCase } from './domain/usecases/delete-configuration.usecase';
import { FindAllConfigurationsUseCase } from './domain/usecases/find-all-configurations.usecase';
@@ -11,12 +15,35 @@ import { UpdateConfigurationUseCase } from './domain/usecases/update-configurati
import { ConfigurationProfile } from './mappers/configuration.profile';
@Module({
imports: [DatabaseModule, CqrsModule],
imports: [
DatabaseModule,
CqrsModule,
RabbitMQModule.forRootAsync(RabbitMQModule, {
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
exchanges: [
{
name: 'configuration',
type: 'topic',
},
{
name: 'logging',
type: 'topic',
},
],
uri: configService.get<string>('RMQ_URI'),
connectionInitOptions: { wait: false },
}),
inject: [ConfigService],
}),
],
exports: [],
controllers: [ConfigurationController],
providers: [
ConfigurationProfile,
ConfigurationRepository,
ConfigurationMessager,
LoggingMessager,
FindAllConfigurationsUseCase,
FindConfigurationByUuidUseCase,
CreateConfigurationUseCase,

View File

@@ -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;
}

View File

@@ -1,7 +1,9 @@
import { Mapper } from '@automapper/core';
import { InjectMapper } from '@automapper/nestjs';
import { CommandHandler } from '@nestjs/cqrs';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { CreateConfigurationCommand } from '../../commands/create-configuration.command';
import { CreateConfigurationRequest } from '../dtos/create-configuration.request';
import { Configuration } from '../entities/configuration';
@@ -10,6 +12,8 @@ import { Configuration } from '../entities/configuration';
export class CreateConfigurationUseCase {
constructor(
private readonly _repository: ConfigurationRepository,
private readonly _configurationMessager: ConfigurationMessager,
private readonly _loggingMessager: LoggingMessager,
@InjectMapper() private readonly _mapper: Mapper,
) {}
@@ -22,8 +26,27 @@ export class CreateConfigurationUseCase {
try {
const configuration = await this._repository.create(entity);
this._configurationMessager.publish(
'create',
JSON.stringify(configuration),
);
this._loggingMessager.publish(
'configuration.create.info',
JSON.stringify(configuration),
);
return configuration;
} catch (error) {
let key = 'configuration.create.crit';
if (error.message.includes('Already exists')) {
key = 'configuration.create.warning';
}
this._loggingMessager.publish(
key,
JSON.stringify({
command,
error,
}),
);
throw error;
}
}

View File

@@ -1,17 +1,38 @@
import { CommandHandler } from '@nestjs/cqrs';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { DeleteConfigurationCommand } from '../../commands/delete-configuration.command';
import { Configuration } from '../entities/configuration';
@CommandHandler(DeleteConfigurationCommand)
export class DeleteConfigurationUseCase {
constructor(private readonly _repository: ConfigurationRepository) {}
constructor(
private readonly _repository: ConfigurationRepository,
private readonly _configurationMessager: ConfigurationMessager,
private readonly _loggingMessager: LoggingMessager,
) {}
async execute(command: DeleteConfigurationCommand): Promise<Configuration> {
try {
const configuration = await this._repository.delete(command.uuid);
this._configurationMessager.publish(
'delete',
JSON.stringify({ uuid: configuration.uuid }),
);
this._loggingMessager.publish(
'configuration.delete.info',
JSON.stringify({ uuid: configuration.uuid }),
);
return configuration;
} catch (error) {
this._loggingMessager.publish(
'configuration.delete.crit',
JSON.stringify({
command,
error,
}),
);
throw error;
}
}

View File

@@ -1,12 +1,16 @@
import { NotFoundException } from '@nestjs/common';
import { QueryHandler } from '@nestjs/cqrs';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { FindConfigurationByUuidQuery } from '../../queries/find-configuration-by-uuid.query';
import { Configuration } from '../entities/configuration';
@QueryHandler(FindConfigurationByUuidQuery)
export class FindConfigurationByUuidUseCase {
constructor(private readonly _repository: ConfigurationRepository) {}
constructor(
private readonly _repository: ConfigurationRepository,
private readonly _loggingMessager: LoggingMessager,
) {}
async execute(
findConfigurationByUuid: FindConfigurationByUuidQuery,
@@ -18,6 +22,13 @@ export class FindConfigurationByUuidUseCase {
if (!configuration) throw new NotFoundException();
return configuration;
} catch (error) {
this._loggingMessager.publish(
'configuration.read.warning',
JSON.stringify({
query: findConfigurationByUuid,
error,
}),
);
throw error;
}
}

View File

@@ -1,7 +1,9 @@
import { Mapper } from '@automapper/core';
import { InjectMapper } from '@automapper/nestjs';
import { CommandHandler } from '@nestjs/cqrs';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { UpdateConfigurationCommand } from '../../commands/update-configuration.command';
import { UpdateConfigurationRequest } from '../dtos/update-configuration.request';
import { Configuration } from '../entities/configuration';
@@ -10,6 +12,8 @@ import { Configuration } from '../entities/configuration';
export class UpdateConfigurationUseCase {
constructor(
private readonly _repository: ConfigurationRepository,
private readonly _configurationMessager: ConfigurationMessager,
private readonly _loggingMessager: LoggingMessager,
@InjectMapper() private readonly _mapper: Mapper,
) {}
@@ -25,8 +29,23 @@ export class UpdateConfigurationUseCase {
command.updateConfigurationRequest.uuid,
entity,
);
this._configurationMessager.publish(
'update',
JSON.stringify(command.updateConfigurationRequest),
);
this._loggingMessager.publish(
'configuration.update.info',
JSON.stringify(command.updateConfigurationRequest),
);
return configuration;
} catch (error) {
this._loggingMessager.publish(
'configuration.update.crit',
JSON.stringify({
command,
error,
}),
);
throw error;
}
}

View File

@@ -1,7 +1,9 @@
import { classes } from '@automapper/classes';
import { AutomapperModule } from '@automapper/nestjs';
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { CreateConfigurationCommand } from '../../commands/create-configuration.command';
import { CreateConfigurationRequest } from '../../domain/dtos/create-configuration.request';
import { Domain } from '../../domain/dtos/domain.enum';
@@ -31,6 +33,10 @@ const mockConfigurationRepository = {
}),
};
const mockMessager = {
publish: jest.fn().mockImplementation(),
};
describe('CreateConfigurationUseCase', () => {
let createConfigurationUseCase: CreateConfigurationUseCase;
@@ -44,6 +50,14 @@ describe('CreateConfigurationUseCase', () => {
},
CreateConfigurationUseCase,
ConfigurationProfile,
{
provide: ConfigurationMessager,
useValue: mockMessager,
},
{
provide: LoggingMessager,
useValue: mockMessager,
},
],
}).compile();

View File

@@ -1,5 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { DeleteConfigurationCommand } from '../../commands/delete-configuration.command';
import { Domain } from '../../domain/dtos/domain.enum';
import { DeleteConfigurationUseCase } from '../../domain/usecases/delete-configuration.usecase';
@@ -43,6 +45,10 @@ const mockConfigurationRepository = {
}),
};
const mockMessager = {
publish: jest.fn().mockImplementation(),
};
describe('DeleteConfigurationUseCase', () => {
let deleteConfigurationUseCase: DeleteConfigurationUseCase;
@@ -54,6 +60,14 @@ describe('DeleteConfigurationUseCase', () => {
useValue: mockConfigurationRepository,
},
DeleteConfigurationUseCase,
{
provide: ConfigurationMessager,
useValue: mockMessager,
},
{
provide: LoggingMessager,
useValue: mockMessager,
},
],
}).compile();

View File

@@ -1,6 +1,8 @@
import { NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { Domain } from '../../domain/dtos/domain.enum';
import { FindConfigurationByUuidRequest } from '../../domain/dtos/find-configuration-by-uuid.request';
import { FindConfigurationByUuidUseCase } from '../../domain/usecases/find-configuration-by-uuid.usecase';
@@ -25,6 +27,10 @@ const mockConfigurationRepository = {
}),
};
const mockMessager = {
publish: jest.fn().mockImplementation(),
};
describe('FindConfigurationByUuidUseCase', () => {
let findConfigurationByUuidUseCase: FindConfigurationByUuidUseCase;
@@ -37,6 +43,14 @@ describe('FindConfigurationByUuidUseCase', () => {
useValue: mockConfigurationRepository,
},
FindConfigurationByUuidUseCase,
{
provide: ConfigurationMessager,
useValue: mockMessager,
},
{
provide: LoggingMessager,
useValue: mockMessager,
},
],
}).compile();

View File

@@ -1,7 +1,9 @@
import { classes } from '@automapper/classes';
import { AutomapperModule } from '@automapper/nestjs';
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager';
import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { UpdateConfigurationCommand } from '../../commands/update-configuration.command';
import { UpdateConfigurationRequest } from '../../domain/dtos/update-configuration.request';
import { Configuration } from '../../domain/entities/configuration';
@@ -33,6 +35,10 @@ const mockConfigurationRepository = {
}),
};
const mockMessager = {
publish: jest.fn().mockImplementation(),
};
describe('UpdateConfigurationUseCase', () => {
let updateConfigurationUseCase: UpdateConfigurationUseCase;
@@ -47,6 +53,14 @@ describe('UpdateConfigurationUseCase', () => {
},
UpdateConfigurationUseCase,
ConfigurationProfile,
{
provide: ConfigurationMessager,
useValue: mockMessager,
},
{
provide: LoggingMessager,
useValue: mockMessager,
},
],
}).compile();