publish errors for invalid ads

This commit is contained in:
sbriat 2023-05-24 16:21:59 +02:00
parent 0dfad732c9
commit 1d6675fcf1
8 changed files with 84 additions and 44 deletions

View File

@ -6,6 +6,8 @@ import { CreateAdRequest } from '../../domain/dtos/create-ad.request';
import { validateOrReject } from 'class-validator'; import { validateOrReject } from 'class-validator';
import { Messager } from '../secondaries/messager'; import { Messager } from '../secondaries/messager';
import { plainToInstance } from 'class-transformer'; import { plainToInstance } from 'class-transformer';
import { DatabaseException } from 'src/modules/database/exceptions/database.exception';
import { ExceptionCode } from 'src/modules/utils/exception-code.enum';
@Controller() @Controller()
export class AdMessagerController { export class AdMessagerController {
@ -18,12 +20,10 @@ export class AdMessagerController {
name: 'adCreated', name: 'adCreated',
}) })
async adCreatedHandler(message: string): Promise<void> { async adCreatedHandler(message: string): Promise<void> {
let createAdRequest: CreateAdRequest;
// parse message to request instance
try { try {
// parse message to request instance createAdRequest = plainToInstance(CreateAdRequest, JSON.parse(message));
const createAdRequest: CreateAdRequest = plainToInstance(
CreateAdRequest,
JSON.parse(message),
);
// validate instance // validate instance
await validateOrReject(createAdRequest); await validateOrReject(createAdRequest);
// validate nested objects (fixes direct nested validation bug) // validate nested objects (fixes direct nested validation bug)
@ -34,8 +34,40 @@ export class AdMessagerController {
throw e; throw e;
} }
} }
} catch (e) {
this.messager.publish(
'matcher.ad.crit',
JSON.stringify({
message: `Can't validate message : ${message}`,
error: e,
}),
);
}
try {
await this.commandBus.execute(new CreateAdCommand(createAdRequest)); await this.commandBus.execute(new CreateAdCommand(createAdRequest));
} catch (e) { } catch (e) {
if (e instanceof DatabaseException) {
if (e.message.includes('already exists')) {
this.messager.publish(
'matcher.ad.crit',
JSON.stringify({
code: ExceptionCode.ALREADY_EXISTS,
message: 'Already exists',
uuid: createAdRequest.uuid,
}),
);
}
if (e.message.includes("Can't reach database server")) {
this.messager.publish(
'matcher.ad.crit',
JSON.stringify({
code: ExceptionCode.UNAVAILABLE,
message: 'Database server unavailable',
uuid: createAdRequest.uuid,
}),
);
}
}
this.messager.publish( this.messager.publish(
'logging.matcher.ad.crit', 'logging.matcher.ad.crit',
JSON.stringify({ JSON.stringify({

View File

@ -11,8 +11,8 @@ import { Configuration } from '../../domain/entities/configuration';
@Controller() @Controller()
export class ConfigurationMessagerController { export class ConfigurationMessagerController {
constructor( constructor(
private readonly _commandBus: CommandBus, private readonly commandBus: CommandBus,
private readonly _configService: ConfigService, private readonly configService: ConfigService,
) {} ) {}
@RabbitSubscribe({ @RabbitSubscribe({
@ -22,14 +22,14 @@ export class ConfigurationMessagerController {
const configuration: Configuration = JSON.parse(message); const configuration: Configuration = JSON.parse(message);
if ( if (
configuration.domain == configuration.domain ==
this._configService.get<string>('SERVICE_CONFIGURATION_DOMAIN') this.configService.get<string>('SERVICE_CONFIGURATION_DOMAIN')
) { ) {
const setConfigurationRequest: SetConfigurationRequest = const setConfigurationRequest: SetConfigurationRequest =
new SetConfigurationRequest(); new SetConfigurationRequest();
setConfigurationRequest.domain = configuration.domain; setConfigurationRequest.domain = configuration.domain;
setConfigurationRequest.key = configuration.key; setConfigurationRequest.key = configuration.key;
setConfigurationRequest.value = configuration.value; setConfigurationRequest.value = configuration.value;
await this._commandBus.execute( await this.commandBus.execute(
new SetConfigurationCommand(setConfigurationRequest), new SetConfigurationCommand(setConfigurationRequest),
); );
} }
@ -42,12 +42,12 @@ export class ConfigurationMessagerController {
const deletedConfiguration: Configuration = JSON.parse(message); const deletedConfiguration: Configuration = JSON.parse(message);
if ( if (
deletedConfiguration.domain == deletedConfiguration.domain ==
this._configService.get<string>('SERVICE_CONFIGURATION_DOMAIN') this.configService.get<string>('SERVICE_CONFIGURATION_DOMAIN')
) { ) {
const deleteConfigurationRequest = new DeleteConfigurationRequest(); const deleteConfigurationRequest = new DeleteConfigurationRequest();
deleteConfigurationRequest.domain = deletedConfiguration.domain; deleteConfigurationRequest.domain = deletedConfiguration.domain;
deleteConfigurationRequest.key = deletedConfiguration.key; deleteConfigurationRequest.key = deletedConfiguration.key;
await this._commandBus.execute( await this.commandBus.execute(
new DeleteConfigurationCommand(deleteConfigurationRequest), new DeleteConfigurationCommand(deleteConfigurationRequest),
); );
} }
@ -61,14 +61,14 @@ export class ConfigurationMessagerController {
configurations.forEach(async (configuration) => { configurations.forEach(async (configuration) => {
if ( if (
configuration.domain == configuration.domain ==
this._configService.get<string>('SERVICE_CONFIGURATION_DOMAIN') this.configService.get<string>('SERVICE_CONFIGURATION_DOMAIN')
) { ) {
const setConfigurationRequest: SetConfigurationRequest = const setConfigurationRequest: SetConfigurationRequest =
new SetConfigurationRequest(); new SetConfigurationRequest();
setConfigurationRequest.domain = configuration.domain; setConfigurationRequest.domain = configuration.domain;
setConfigurationRequest.key = configuration.key; setConfigurationRequest.key = configuration.key;
setConfigurationRequest.value = configuration.value; setConfigurationRequest.value = configuration.value;
await this._commandBus.execute( await this.commandBus.execute(
new SetConfigurationCommand(setConfigurationRequest), new SetConfigurationCommand(setConfigurationRequest),
); );
} }

View File

@ -5,19 +5,19 @@ import { IConfigurationRepository } from '../../domain/interfaces/configuration.
@Injectable() @Injectable()
export class RedisConfigurationRepository extends IConfigurationRepository { export class RedisConfigurationRepository extends IConfigurationRepository {
constructor(@InjectRedis() private readonly _redis: Redis) { constructor(@InjectRedis() private readonly redis: Redis) {
super(); super();
} }
async get(key: string): Promise<string> { get = async (key: string): Promise<string> => {
return await this._redis.get(key); return await this.redis.get(key);
} };
async set(key: string, value: string) { set = async (key: string, value: string): Promise<void> => {
await this._redis.set(key, value); await this.redis.set(key, value);
} };
async del(key: string) { del = async (key: string): Promise<void> => {
await this._redis.del(key); await this.redis.del(key);
} };
} }

View File

@ -41,14 +41,17 @@ import { SetConfigurationUseCase } from './domain/usecases/set-configuration.use
setConfiguration: { setConfiguration: {
exchange: configService.get<string>('RMQ_EXCHANGE'), exchange: configService.get<string>('RMQ_EXCHANGE'),
routingKey: ['configuration.create', 'configuration.update'], routingKey: ['configuration.create', 'configuration.update'],
queue: 'matcher-configuration-create-update',
}, },
deleteConfiguration: { deleteConfiguration: {
exchange: configService.get<string>('RMQ_EXCHANGE'), exchange: configService.get<string>('RMQ_EXCHANGE'),
routingKey: 'configuration.delete', routingKey: 'configuration.delete',
queue: 'matcher-configuration-delete',
}, },
propagateConfiguration: { propagateConfiguration: {
exchange: configService.get<string>('RMQ_EXCHANGE'), exchange: configService.get<string>('RMQ_EXCHANGE'),
routingKey: 'configuration.propagate', routingKey: 'configuration.propagate',
queue: 'matcher-configuration-propagate',
}, },
}, },
uri: configService.get<string>('RMQ_URI'), uri: configService.get<string>('RMQ_URI'),

View File

@ -3,6 +3,6 @@ import { Injectable } from '@nestjs/common';
@Injectable() @Injectable()
export abstract class IConfigurationRepository { export abstract class IConfigurationRepository {
abstract get(key: string): Promise<string>; abstract get(key: string): Promise<string>;
abstract set(key: string, value: string): void; abstract set(key: string, value: string): Promise<void>;
abstract del(key: string): void; abstract del(key: string): Promise<void>;
} }

View File

@ -4,13 +4,15 @@ import { DeleteConfigurationCommand } from '../../commands/delete-configuration.
@CommandHandler(DeleteConfigurationCommand) @CommandHandler(DeleteConfigurationCommand)
export class DeleteConfigurationUseCase { export class DeleteConfigurationUseCase {
constructor(private _configurationRepository: RedisConfigurationRepository) {} constructor(private configurationRepository: RedisConfigurationRepository) {}
async execute(deleteConfigurationCommand: DeleteConfigurationCommand) { execute = async (
await this._configurationRepository.del( deleteConfigurationCommand: DeleteConfigurationCommand,
deleteConfigurationCommand.deleteConfigurationRequest.domain + ): Promise<void> => {
':' + await this.configurationRepository.del(
deleteConfigurationCommand.deleteConfigurationRequest.key, `${deleteConfigurationCommand.deleteConfigurationRequest.domain}
:
${deleteConfigurationCommand.deleteConfigurationRequest.key}`,
); );
} };
} }

View File

@ -4,11 +4,12 @@ import { GetConfigurationQuery } from '../../queries/get-configuration.query';
@QueryHandler(GetConfigurationQuery) @QueryHandler(GetConfigurationQuery)
export class GetConfigurationUseCase { export class GetConfigurationUseCase {
constructor(private _configurationRepository: RedisConfigurationRepository) {} constructor(private configurationRepository: RedisConfigurationRepository) {}
async execute(getConfigurationQuery: GetConfigurationQuery): Promise<string> { execute = async (
return this._configurationRepository.get( getConfigurationQuery: GetConfigurationQuery,
getConfigurationQuery.domain + ':' + getConfigurationQuery.key, ): Promise<string> =>
this.configurationRepository.get(
`${getConfigurationQuery.domain}:${getConfigurationQuery.key}`,
); );
}
} }

View File

@ -4,14 +4,16 @@ import { SetConfigurationCommand } from '../../commands/set-configuration.comman
@CommandHandler(SetConfigurationCommand) @CommandHandler(SetConfigurationCommand)
export class SetConfigurationUseCase { export class SetConfigurationUseCase {
constructor(private _configurationRepository: RedisConfigurationRepository) {} constructor(private configurationRepository: RedisConfigurationRepository) {}
async execute(setConfigurationCommand: SetConfigurationCommand) { execute = async (
await this._configurationRepository.set( setConfigurationCommand: SetConfigurationCommand,
setConfigurationCommand.setConfigurationRequest.domain + ): Promise<void> => {
':' + await this.configurationRepository.set(
setConfigurationCommand.setConfigurationRequest.key, `${setConfigurationCommand.setConfigurationRequest.domain}
:
${setConfigurationCommand.setConfigurationRequest.key}`,
setConfigurationCommand.setConfigurationRequest.value, setConfigurationCommand.setConfigurationRequest.value,
); );
} };
} }