Implement distributed event handler to propagate ad deletion
This commit is contained in:
parent
1701fbbeb1
commit
d48d01f051
|
@ -15,6 +15,9 @@ export const MATCHER_AD_CREATION_FAILED_ROUTING_KEY =
|
|||
export const AD_CREATED_MESSAGE_HANDLER = 'adCreated';
|
||||
export const AD_CREATED_ROUTING_KEY = 'ad.created';
|
||||
export const AD_CREATED_QUEUE = 'matcher.ad.created';
|
||||
export const AD_DELETED_MESSAGE_HANDLER = 'adDeleted';
|
||||
export const AD_DELETED_ROUTING_KEY = 'ad.deleted';
|
||||
export const AD_DELETED_QUEUE = 'matcher.ad.deleted';
|
||||
|
||||
// health
|
||||
export const GRPC_HEALTH_PACKAGE_NAME = 'health';
|
||||
|
|
|
@ -43,6 +43,7 @@ import { TimeConverter } from './infrastructure/time-converter';
|
|||
import { TimezoneFinder } from './infrastructure/timezone-finder';
|
||||
import { MatchGrpcController } from './interface/grpc-controllers/match.grpc-controller';
|
||||
import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler';
|
||||
import { AdDeletedMessageHandler } from './interface/message-handlers/ad-deleted.message-handler';
|
||||
import { MatchMapper } from './match.mapper';
|
||||
import { MatchingMapper } from './matching.mapper';
|
||||
|
||||
|
@ -97,7 +98,7 @@ const imports = [
|
|||
|
||||
const grpcControllers = [MatchGrpcController];
|
||||
|
||||
const messageHandlers = [AdCreatedMessageHandler];
|
||||
const messageHandlers = [AdCreatedMessageHandler, AdDeletedMessageHandler];
|
||||
|
||||
const eventHandlers: Provider[] = [
|
||||
PublishMessageWhenMatcherAdIsCreatedDomainEventHandler,
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import { RabbitSubscribe } from '@mobicoop/message-broker-module';
|
||||
import { DeleteAdCommand } from '@modules/ad/core/application/commands/delete-ad/delete-ad.command';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CommandBus } from '@nestjs/cqrs';
|
||||
import {
|
||||
AD_DELETED_MESSAGE_HANDLER,
|
||||
AD_DELETED_ROUTING_KEY,
|
||||
} from '@src/app.constants';
|
||||
import { AdReference } from './ad.types';
|
||||
|
||||
@Injectable()
|
||||
export class AdDeletedMessageHandler {
|
||||
constructor(private readonly commandBus: CommandBus) {}
|
||||
|
||||
@RabbitSubscribe({
|
||||
name: AD_DELETED_MESSAGE_HANDLER,
|
||||
routingKey: AD_DELETED_ROUTING_KEY,
|
||||
})
|
||||
public async adDeleted(message: string): Promise<void> {
|
||||
try {
|
||||
const deletedAd: AdReference = JSON.parse(message);
|
||||
await this.commandBus.execute(
|
||||
new DeleteAdCommand({
|
||||
id: deletedAd.aggregateId,
|
||||
}),
|
||||
);
|
||||
} catch (error: any) {
|
||||
// do not throw error to acknowledge incoming message
|
||||
// error handling should be done in the command handler, if relevant
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||
|
||||
export type Ad = {
|
||||
export type AdReference = {
|
||||
aggregateId: string;
|
||||
};
|
||||
|
||||
export type Ad = AdReference & {
|
||||
driver: boolean;
|
||||
passenger: boolean;
|
||||
frequency: Frequency;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import { AdDeletedMessageHandler } from '@modules/ad/interface/message-handlers/ad-deleted.message-handler';
|
||||
import { CommandBus } from '@nestjs/cqrs';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
const adDeletedMessage =
|
||||
'{"aggregateId":"4eb6a6af-ecfd-41c3-9118-473a507014d4"}';
|
||||
|
||||
const mockCommandBus = {
|
||||
execute: jest.fn(),
|
||||
};
|
||||
|
||||
describe('Ad Deleted Message Handler', () => {
|
||||
let adDeletedMessageHandler: AdDeletedMessageHandler;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: CommandBus,
|
||||
useValue: mockCommandBus,
|
||||
},
|
||||
AdDeletedMessageHandler,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
adDeletedMessageHandler = module.get<AdDeletedMessageHandler>(
|
||||
AdDeletedMessageHandler,
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(adDeletedMessageHandler).toBeDefined();
|
||||
});
|
||||
|
||||
it('should call the delete command', async () => {
|
||||
jest.spyOn(mockCommandBus, 'execute');
|
||||
await adDeletedMessageHandler.adDeleted(adDeletedMessage);
|
||||
expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
|
@ -1,17 +1,20 @@
|
|||
import { Module, Provider } from '@nestjs/common';
|
||||
import { MESSAGE_PUBLISHER } from './messager.di-tokens';
|
||||
import {
|
||||
MessageBrokerModule,
|
||||
MessageBrokerModuleOptions,
|
||||
MessageBrokerPublisher,
|
||||
} from '@mobicoop/message-broker-module';
|
||||
import { Module, Provider } from '@nestjs/common';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import {
|
||||
AD_CREATED_MESSAGE_HANDLER,
|
||||
AD_CREATED_QUEUE,
|
||||
AD_CREATED_ROUTING_KEY,
|
||||
AD_DELETED_MESSAGE_HANDLER,
|
||||
AD_DELETED_QUEUE,
|
||||
AD_DELETED_ROUTING_KEY,
|
||||
SERVICE_NAME,
|
||||
} from '@src/app.constants';
|
||||
import { MESSAGE_PUBLISHER } from './messager.di-tokens';
|
||||
|
||||
const imports = [
|
||||
MessageBrokerModule.forRootAsync({
|
||||
|
@ -33,6 +36,10 @@ const imports = [
|
|||
routingKey: AD_CREATED_ROUTING_KEY,
|
||||
queue: AD_CREATED_QUEUE,
|
||||
},
|
||||
[AD_DELETED_MESSAGE_HANDLER]: {
|
||||
routingKey: AD_DELETED_ROUTING_KEY,
|
||||
queue: AD_DELETED_QUEUE,
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
|
|
Loading…
Reference in New Issue