From 31ab4e5805bc3158105743c3736762d688f9f84d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daute=20Rodr=C3=ADguez=20Rodr=C3=ADguez?= Date: Thu, 19 May 2022 13:54:44 +0100 Subject: [PATCH 1/3] feat: added failed legacy project import db cleanup queue provider --- ...roject-import-db-cleanup-queue.provider.ts | 30 +++++++++++++++++++ ...cy-project-import-db-cleanup-queue-name.ts | 2 ++ api/libs/legacy-project-import/src/index.ts | 11 +++++-- .../legacy-project-import/src/job-input.ts | 4 +++ .../legacy-project-import/src/job-output.ts | 4 +++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 api/apps/api/src/modules/legacy-project-import/infra/failed-legacy-project-import-db-cleanup-queue.provider.ts create mode 100644 api/libs/legacy-project-import/src/failed-legacy-project-import-db-cleanup-queue-name.ts diff --git a/api/apps/api/src/modules/legacy-project-import/infra/failed-legacy-project-import-db-cleanup-queue.provider.ts b/api/apps/api/src/modules/legacy-project-import/infra/failed-legacy-project-import-db-cleanup-queue.provider.ts new file mode 100644 index 0000000000..f1f7cb2891 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/infra/failed-legacy-project-import-db-cleanup-queue.provider.ts @@ -0,0 +1,30 @@ +import { QueueBuilder } from '@marxan-api/modules/queue'; +import { + FailedLegacyProjectImportDbCleanupJobInput, + FailedLegacyProjectImportDbCleanupJobOutput, + failedLegacyProjectImportDbCleanupQueueName, +} from '@marxan/legacy-project-import'; +import { FactoryProvider } from '@nestjs/common'; +import { Queue } from 'bullmq'; + +export const failedLegacyProjectImportDbCleanupQueueToken = Symbol( + 'failed legacy project import db cleanup queue token', +); + +export const failedLegacyProjectImportDbCleanupQueueProvider: FactoryProvider< + Queue< + FailedLegacyProjectImportDbCleanupJobInput, + FailedLegacyProjectImportDbCleanupJobOutput + > +> = { + provide: failedLegacyProjectImportDbCleanupQueueToken, + useFactory: ( + queueBuilder: QueueBuilder< + FailedLegacyProjectImportDbCleanupJobInput, + FailedLegacyProjectImportDbCleanupJobOutput + >, + ) => { + return queueBuilder.buildQueue(failedLegacyProjectImportDbCleanupQueueName); + }, + inject: [QueueBuilder], +}; diff --git a/api/libs/legacy-project-import/src/failed-legacy-project-import-db-cleanup-queue-name.ts b/api/libs/legacy-project-import/src/failed-legacy-project-import-db-cleanup-queue-name.ts new file mode 100644 index 0000000000..61d09013f6 --- /dev/null +++ b/api/libs/legacy-project-import/src/failed-legacy-project-import-db-cleanup-queue-name.ts @@ -0,0 +1,2 @@ +export const failedLegacyProjectImportDbCleanupQueueName = + 'failed-legacy-project-import-db-cleanup'; diff --git a/api/libs/legacy-project-import/src/index.ts b/api/libs/legacy-project-import/src/index.ts index 15133ec435..c492e3415b 100644 --- a/api/libs/legacy-project-import/src/index.ts +++ b/api/libs/legacy-project-import/src/index.ts @@ -1,6 +1,13 @@ export * from './domain'; export * from './infra'; -export { LegacyProjectImportJobInput } from './job-input'; -export { LegacyProjectImportJobOutput } from './job-output'; +export { + LegacyProjectImportJobInput, + FailedLegacyProjectImportDbCleanupJobInput, +} from './job-input'; +export { + LegacyProjectImportJobOutput, + FailedLegacyProjectImportDbCleanupJobOutput, +} from './job-output'; export { LegacyProjectImportPieceProcessor } from './legacy-project-import-piece-processor.port'; export { legacyProjectImportQueueName } from './legacy-project-import-queue-name'; +export { failedLegacyProjectImportDbCleanupQueueName } from './failed-legacy-project-import-db-cleanup-queue-name'; diff --git a/api/libs/legacy-project-import/src/job-input.ts b/api/libs/legacy-project-import/src/job-input.ts index 7385be1638..40710b2a71 100644 --- a/api/libs/legacy-project-import/src/job-input.ts +++ b/api/libs/legacy-project-import/src/job-input.ts @@ -9,3 +9,7 @@ export interface LegacyProjectImportJobInput { readonly scenarioId: string; readonly piece: LegacyProjectImportPiece; } + +export interface FailedLegacyProjectImportDbCleanupJobInput { + readonly projectId: string; +} diff --git a/api/libs/legacy-project-import/src/job-output.ts b/api/libs/legacy-project-import/src/job-output.ts index aca7eaad7d..e1ec87ce5f 100644 --- a/api/libs/legacy-project-import/src/job-output.ts +++ b/api/libs/legacy-project-import/src/job-output.ts @@ -10,3 +10,7 @@ export interface LegacyProjectImportJobOutput { readonly piece: LegacyProjectImportPiece; readonly warnings?: string[]; } + +export interface FailedLegacyProjectImportDbCleanupJobOutput { + readonly projectId: string; +} From 61724ebbfec42d02d625e0227e260941768feecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daute=20Rodr=C3=ADguez=20Rodr=C3=ADguez?= Date: Thu, 19 May 2022 13:55:01 +0100 Subject: [PATCH 2/3] feat: legacy project import batch failed saga --- ...legacy-project-import-batch-failed.saga.ts | 25 +++++++++++++++++++ .../legacy-project-import.infra.module.ts | 6 +++-- ...or-failed-legacy-project-import.command.ts | 8 ++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import-batch-failed.saga.ts create mode 100644 api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.command.ts diff --git a/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import-batch-failed.saga.ts b/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import-batch-failed.saga.ts new file mode 100644 index 0000000000..dbe201f174 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import-batch-failed.saga.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@nestjs/common'; +import { ICommand, ofType, Saga } from '@nestjs/cqrs'; +import { Observable, of } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; +import { MarkLegacyProjectImportAsFailed } from '../application/mark-legacy-project-import-as-failed.command'; +import { LegacyProjectImportBatchFailed } from '../domain/events/legacy-project-import-batch-failed.event'; +import { ScheduleDbCleanupForFailedLegacyProjectImport } from './schedule-db-cleanup-for-failed-legacy-project-import.command'; + +@Injectable() +export class LegacyProjectImportBatchFailedSaga { + @Saga() + saga = (events$: Observable): Observable => + events$.pipe( + ofType(LegacyProjectImportBatchFailed), + mergeMap((event) => + of( + new MarkLegacyProjectImportAsFailed( + event.projectId, + `${event.batchNumber} batch contains failed pieces`, + ), + new ScheduleDbCleanupForFailedLegacyProjectImport(event.projectId), + ), + ), + ); +} diff --git a/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts b/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts index 81ce39f7ec..1f8f1d2880 100644 --- a/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts +++ b/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts @@ -2,10 +2,11 @@ import { ApiEventsModule } from '@marxan-api/modules/api-events'; import { QueueApiEventsModule } from '@marxan-api/modules/queue-api-events'; import { Logger, Module, Scope } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; +import { LegacyProjectImportBatchFailedSaga } from './legacy-project-import-batch-failed.saga'; import { - importLegacyProjectPieceQueueProvider, - importLegacyProjectPiecenQueueEventsProvider, importLegacyProjectPieceEventsFactoryProvider, + importLegacyProjectPiecenQueueEventsProvider, + importLegacyProjectPieceQueueProvider, } from './legacy-project-import-queue.provider'; @Module({ @@ -14,6 +15,7 @@ import { importLegacyProjectPieceQueueProvider, importLegacyProjectPiecenQueueEventsProvider, importLegacyProjectPieceEventsFactoryProvider, + LegacyProjectImportBatchFailedSaga, { provide: Logger, useClass: Logger, diff --git a/api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.command.ts b/api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.command.ts new file mode 100644 index 0000000000..8aec5ca038 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.command.ts @@ -0,0 +1,8 @@ +import { ResourceId } from '@marxan/cloning/domain'; +import { Command } from '@nestjs-architects/typed-cqrs'; + +export class ScheduleDbCleanupForFailedLegacyProjectImport extends Command { + constructor(public readonly projectId: ResourceId) { + super(); + } +} From d429ff8d8177b4cf9d3e94f05f97b77237103045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daute=20Rodr=C3=ADguez=20Rodr=C3=ADguez?= Date: Thu, 19 May 2022 14:12:02 +0100 Subject: [PATCH 3/3] feat: schedule db cleanup for failed legacy project import handler --- .../legacy-project-import.infra.module.ts | 4 ++ ...or-failed-legacy-project-import.handler.ts | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.handler.ts diff --git a/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts b/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts index 1f8f1d2880..f698cfbb3f 100644 --- a/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts +++ b/api/apps/api/src/modules/legacy-project-import/infra/legacy-project-import.infra.module.ts @@ -2,12 +2,14 @@ import { ApiEventsModule } from '@marxan-api/modules/api-events'; import { QueueApiEventsModule } from '@marxan-api/modules/queue-api-events'; import { Logger, Module, Scope } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; +import { failedLegacyProjectImportDbCleanupQueueProvider } from './failed-legacy-project-import-db-cleanup-queue.provider'; import { LegacyProjectImportBatchFailedSaga } from './legacy-project-import-batch-failed.saga'; import { importLegacyProjectPieceEventsFactoryProvider, importLegacyProjectPiecenQueueEventsProvider, importLegacyProjectPieceQueueProvider, } from './legacy-project-import-queue.provider'; +import { ScheduleDbCleanupForFailedLegacyProjectImportHandler } from './schedule-db-cleanup-for-failed-legacy-project-import.handler'; @Module({ imports: [ApiEventsModule, QueueApiEventsModule, CqrsModule], @@ -15,7 +17,9 @@ import { importLegacyProjectPieceQueueProvider, importLegacyProjectPiecenQueueEventsProvider, importLegacyProjectPieceEventsFactoryProvider, + failedLegacyProjectImportDbCleanupQueueProvider, LegacyProjectImportBatchFailedSaga, + ScheduleDbCleanupForFailedLegacyProjectImportHandler, { provide: Logger, useClass: Logger, diff --git a/api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.handler.ts b/api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.handler.ts new file mode 100644 index 0000000000..35dabd0d2f --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/infra/schedule-db-cleanup-for-failed-legacy-project-import.handler.ts @@ -0,0 +1,39 @@ +import { FailedLegacyProjectImportDbCleanupJobInput } from '@marxan/legacy-project-import'; +import { Inject, Logger } from '@nestjs/common'; +import { CommandHandler, IInferredCommandHandler } from '@nestjs/cqrs'; +import { Queue } from 'bullmq'; +import { failedLegacyProjectImportDbCleanupQueueToken } from './failed-legacy-project-import-db-cleanup-queue.provider'; +import { ScheduleDbCleanupForFailedLegacyProjectImport } from './schedule-db-cleanup-for-failed-legacy-project-import.command'; + +@CommandHandler(ScheduleDbCleanupForFailedLegacyProjectImport) +export class ScheduleDbCleanupForFailedLegacyProjectImportHandler + implements + IInferredCommandHandler { + constructor( + @Inject(failedLegacyProjectImportDbCleanupQueueToken) + private readonly queue: Queue, + private readonly logger: Logger, + ) { + this.logger.setContext( + ScheduleDbCleanupForFailedLegacyProjectImportHandler.name, + ); + } + + async execute({ + projectId, + }: ScheduleDbCleanupForFailedLegacyProjectImport): Promise { + const job = await this.queue.add( + `failed-legacy-project-import-db-cleanup`, + { + projectId: projectId.value, + }, + ); + + if (!job) { + this.logger.error( + `failed-legacy-project-import-db-cleanup job couldn't be added to queue`, + ); + return; + } + } +}