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_MESSAGE_HANDLER = 'adCreated';
|
||||||
export const AD_CREATED_ROUTING_KEY = 'ad.created';
|
export const AD_CREATED_ROUTING_KEY = 'ad.created';
|
||||||
export const AD_CREATED_QUEUE = 'matcher.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
|
// health
|
||||||
export const GRPC_HEALTH_PACKAGE_NAME = '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 { TimezoneFinder } from './infrastructure/timezone-finder';
|
||||||
import { MatchGrpcController } from './interface/grpc-controllers/match.grpc-controller';
|
import { MatchGrpcController } from './interface/grpc-controllers/match.grpc-controller';
|
||||||
import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler';
|
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 { MatchMapper } from './match.mapper';
|
||||||
import { MatchingMapper } from './matching.mapper';
|
import { MatchingMapper } from './matching.mapper';
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@ const imports = [
|
||||||
|
|
||||||
const grpcControllers = [MatchGrpcController];
|
const grpcControllers = [MatchGrpcController];
|
||||||
|
|
||||||
const messageHandlers = [AdCreatedMessageHandler];
|
const messageHandlers = [AdCreatedMessageHandler, AdDeletedMessageHandler];
|
||||||
|
|
||||||
const eventHandlers: Provider[] = [
|
const eventHandlers: Provider[] = [
|
||||||
PublishMessageWhenMatcherAdIsCreatedDomainEventHandler,
|
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';
|
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||||
|
|
||||||
export type Ad = {
|
export type AdReference = {
|
||||||
aggregateId: string;
|
aggregateId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Ad = AdReference & {
|
||||||
driver: boolean;
|
driver: boolean;
|
||||||
passenger: boolean;
|
passenger: boolean;
|
||||||
frequency: Frequency;
|
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 {
|
import {
|
||||||
MessageBrokerModule,
|
MessageBrokerModule,
|
||||||
MessageBrokerModuleOptions,
|
MessageBrokerModuleOptions,
|
||||||
MessageBrokerPublisher,
|
MessageBrokerPublisher,
|
||||||
} from '@mobicoop/message-broker-module';
|
} from '@mobicoop/message-broker-module';
|
||||||
|
import { Module, Provider } from '@nestjs/common';
|
||||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import {
|
import {
|
||||||
AD_CREATED_MESSAGE_HANDLER,
|
AD_CREATED_MESSAGE_HANDLER,
|
||||||
AD_CREATED_QUEUE,
|
AD_CREATED_QUEUE,
|
||||||
AD_CREATED_ROUTING_KEY,
|
AD_CREATED_ROUTING_KEY,
|
||||||
|
AD_DELETED_MESSAGE_HANDLER,
|
||||||
|
AD_DELETED_QUEUE,
|
||||||
|
AD_DELETED_ROUTING_KEY,
|
||||||
SERVICE_NAME,
|
SERVICE_NAME,
|
||||||
} from '@src/app.constants';
|
} from '@src/app.constants';
|
||||||
|
import { MESSAGE_PUBLISHER } from './messager.di-tokens';
|
||||||
|
|
||||||
const imports = [
|
const imports = [
|
||||||
MessageBrokerModule.forRootAsync({
|
MessageBrokerModule.forRootAsync({
|
||||||
|
@ -33,6 +36,10 @@ const imports = [
|
||||||
routingKey: AD_CREATED_ROUTING_KEY,
|
routingKey: AD_CREATED_ROUTING_KEY,
|
||||||
queue: AD_CREATED_QUEUE,
|
queue: AD_CREATED_QUEUE,
|
||||||
},
|
},
|
||||||
|
[AD_DELETED_MESSAGE_HANDLER]: {
|
||||||
|
routingKey: AD_DELETED_ROUTING_KEY,
|
||||||
|
queue: AD_DELETED_QUEUE,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue