From f20158a44e345c8e0c85c8fd45500b8a66136573 Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Fri, 23 May 2025 14:42:29 +0200 Subject: [PATCH] Fix job_v3 handlebar helper Refactors this to reuse the mapJobClassV4toV3 function from the job controller --- src/common/handlebars-helpers.ts | 49 +-------------- .../update-job-v3-mapping.interceptor.ts | 20 +------ src/jobs/job-v3-mappings.ts | 60 +++++++++++++++++++ src/jobs/jobs.controller.ts | 40 ++----------- 4 files changed, 70 insertions(+), 99 deletions(-) create mode 100644 src/jobs/job-v3-mappings.ts diff --git a/src/common/handlebars-helpers.ts b/src/common/handlebars-helpers.ts index 57a5c49b5..73d151eeb 100644 --- a/src/common/handlebars-helpers.ts +++ b/src/common/handlebars-helpers.ts @@ -3,8 +3,7 @@ * * Helpers should be registered in app.module.ts */ -import { JobClass } from "src/jobs/schemas/job.schema"; -import { JobParams } from "src/jobs/types/job-types.enum"; +import { mapJobClassV4toV3 } from "src/jobs/job-v3-mappings"; /** * Convert json objects to HTML @@ -70,50 +69,6 @@ export const jsonify = (context: unknown): string => { return JSON.stringify(context, null, 3); }; -type DatasetIdV3 = { - pid: string; - files: string[]; -}; -interface JobV3 { - id: string; - emailJobInitiator?: string; - type: string; - creationTime: Date; - executionTime?: Date; - jobParams: Record; - jobStatusMessage?: string; - datasetList: DatasetIdV3[]; - jobResultObject?: unknown; -} - -/** - * Convert a current job to follow the old v3 schema. - * - * Useful as a shim for backwards compatibility with old archive systems. - * - * Example: '{{{ jsonify (job_v3 this) }}}' - * @param context - */ -export const job_v3 = (job: JobClass): JobV3 => { - let datasetList: DatasetIdV3[] = []; - if (JobParams.DatasetList in job.jobParams) { - datasetList = job.jobParams[JobParams.DatasetList] as DatasetIdV3[]; - } - return { - id: job.id || job._id, - emailJobInitiator: job.contactEmail, - type: job.type, - creationTime: job.createdAt, - jobParams: { - ...job.jobParams, - username: job.createdBy, - }, - // v3 statusMessages were generally concise, so use the statusCode - jobStatusMessage: job.statusCode, - datasetList: datasetList, - }; -}; - /** * URL encode input * @param context Handlebars variable @@ -137,7 +92,7 @@ export const handlebarsHelpers = { keyToWord: formatCamelCase, eq: (a: unknown, b: unknown) => a === b, jsonify: jsonify, - job_v3: job_v3, + job_v3: mapJobClassV4toV3, urlencode: urlencode, base64enc: base64enc, }; diff --git a/src/jobs/interceptors/update-job-v3-mapping.interceptor.ts b/src/jobs/interceptors/update-job-v3-mapping.interceptor.ts index 9bd5e6731..7e6cd9ac6 100644 --- a/src/jobs/interceptors/update-job-v3-mapping.interceptor.ts +++ b/src/jobs/interceptors/update-job-v3-mapping.interceptor.ts @@ -7,6 +7,7 @@ import { import { Observable } from "rxjs"; import { UpdateJobDtoV3 } from "../dto/update-job.v3.dto"; import { UpdateJobDto } from "../dto/update-job.dto"; +import { mapUpdateJobDtoV3ToV4 } from "../job-v3-mappings"; /** * PATCH/api/v3/jobs requires an UpdateJobDtoV3 object as request body. @@ -19,24 +20,7 @@ export class UpdateJobV3MappingInterceptor implements NestInterceptor { const request = context.switchToHttp().getRequest(); const dtoV3 = request.body as UpdateJobDtoV3; - let newBody: UpdateJobDto = { - statusCode: dtoV3.jobStatusMessage, - statusMessage: dtoV3.jobStatusMessage, - }; - - let newjobResultObject = dtoV3.jobResultObject; - // if executionTime is provided, add it to jobResultObject, to maintain compatibility - // after the job update is completed, it will be then moved to jobParams - if (dtoV3.executionTime) { - newjobResultObject = { - ...newjobResultObject, - executionTime: dtoV3.executionTime, - }; - } - newBody = { - ...newBody, - jobResultObject: newjobResultObject, - }; + const newBody: UpdateJobDto = mapUpdateJobDtoV3ToV4(dtoV3); request.body = newBody; return next.handle(); } diff --git a/src/jobs/job-v3-mappings.ts b/src/jobs/job-v3-mappings.ts new file mode 100644 index 000000000..441540eee --- /dev/null +++ b/src/jobs/job-v3-mappings.ts @@ -0,0 +1,60 @@ +/** + * Functions for mapping between v3 and v4 job models + */ + +import { DatasetListDto } from "./dto/dataset-list.dto"; +import { OutputJobV3Dto } from "./dto/output-job-v3.dto"; +import { UpdateJobDto } from "./dto/update-job.dto"; +import { UpdateJobDtoV3 } from "./dto/update-job.v3.dto"; +import { JobClass } from "./schemas/job.schema"; + +/** + * Transform a v4 job instance so that is compatible with v3 + * @param job: a JobClass instance (v4) + * @returns a OutputJobV3Dto instance + */ +export function mapJobClassV4toV3(job: JobClass): OutputJobV3Dto { + const jobV3 = new OutputJobV3Dto(); + // Map fields from v4 to v3 + jobV3._id = job._id; + jobV3.id = job.id; + jobV3.emailJobInitiator = job.contactEmail; + jobV3.type = job.type; + jobV3.creationTime = job.createdAt; + jobV3.jobStatusMessage = job.statusCode; + jobV3.jobResultObject = job.jobResultObject; + // Extract datasetList from jobParams + const { datasetList, ...jobParams } = job.jobParams; + jobV3.datasetList = datasetList as DatasetListDto[]; + jobV3.jobParams = jobParams; + // Extract executionTime from jobParams + if (job.jobParams.executionTime) { + const { datasetList, executionTime, ...jobParams } = job.jobParams; + jobV3.datasetList = datasetList as DatasetListDto[]; + jobV3.executionTime = executionTime as Date; + jobV3.jobParams = jobParams; + } + return jobV3; +} + +export function mapUpdateJobDtoV3ToV4(dtoV3: UpdateJobDtoV3) { + let newBody: UpdateJobDto = { + statusCode: dtoV3.jobStatusMessage, + statusMessage: dtoV3.jobStatusMessage, + }; + + let newjobResultObject = dtoV3.jobResultObject; + // if executionTime is provided, add it to jobResultObject, to maintain compatibility + // after the job update is completed, it will be then moved to jobParams + if (dtoV3.executionTime) { + newjobResultObject = { + ...newjobResultObject, + executionTime: dtoV3.executionTime, + }; + } + newBody = { + ...newBody, + jobResultObject: newjobResultObject, + }; + return newBody; +} diff --git a/src/jobs/jobs.controller.ts b/src/jobs/jobs.controller.ts index a78cae0b4..425946259 100644 --- a/src/jobs/jobs.controller.ts +++ b/src/jobs/jobs.controller.ts @@ -70,6 +70,7 @@ import { ConfigService } from "@nestjs/config"; import { JobConfigService } from "../config/job-config/jobconfig.service"; import { CreateJobV3MappingInterceptor } from "./interceptors/create-job-v3-mapping.interceptor"; import { UpdateJobV3MappingInterceptor } from "./interceptors/update-job-v3-mapping.interceptor"; +import { mapJobClassV4toV3 } from "./job-v3-mappings"; @ApiBearerAuth() @ApiTags("jobs") @@ -646,35 +647,6 @@ export class JobsController { } } - /** - * Transform a v4 job instance so that is compatible with v3 - * @param job: a JobClass instance (v4) - * @returns a OutputJobV3Dto instance - */ - private mapJobClassV4toV3(job: JobClass): OutputJobV3Dto { - const jobV3 = new OutputJobV3Dto(); - // Map fields from v4 to v3 - jobV3._id = job._id; - jobV3.id = job.id; - jobV3.emailJobInitiator = job.contactEmail; - jobV3.type = job.type; - jobV3.creationTime = job.createdAt; - jobV3.jobStatusMessage = job.statusCode; - jobV3.jobResultObject = job.jobResultObject; - // Extract datasetList from jobParams - const { datasetList, ...jobParams } = job.jobParams; - jobV3.datasetList = datasetList as DatasetListDto[]; - jobV3.jobParams = jobParams; - // Extract executionTime from jobParams - if (job.jobParams.executionTime) { - const { datasetList, executionTime, ...jobParams } = job.jobParams; - jobV3.datasetList = datasetList as DatasetListDto[]; - jobV3.executionTime = executionTime as Date; - jobV3.jobParams = jobParams; - } - return jobV3; - } - /** * Create job implementation */ @@ -730,7 +702,7 @@ export class JobsController { @Body() createJobDto: CreateJobDto, ): Promise { const job = await this.createJob(request, createJobDto); - return job ? this.mapJobClassV4toV3(job) : null; + return job ? mapJobClassV4toV3(job) : null; } /** @@ -859,7 +831,7 @@ export class JobsController { ): Promise { Logger.log("Updating job v3 ", id); const updatedJob = await this.updateJob(request, id, updateJobDto); - return updatedJob ? this.mapJobClassV4toV3(updatedJob) : null; + return updatedJob ? mapJobClassV4toV3(updatedJob) : null; } /** @@ -995,7 +967,7 @@ export class JobsController { @Query() filters: { fields?: string; limits?: string }, ): Promise { const jobs = await this.fullQueryJobs(request, filters); - return jobs?.map(this.mapJobClassV4toV3) ?? null; + return jobs?.map(mapJobClassV4toV3) ?? null; } /** @@ -1224,7 +1196,7 @@ export class JobsController { @Param("id") id: string, ): Promise { const job = await this.getJobById(request, id); - return job ? this.mapJobClassV4toV3(job) : null; + return job ? mapJobClassV4toV3(job) : null; } /** @@ -1348,7 +1320,7 @@ export class JobsController { @Query("filter") filter?: string, ): Promise { const jobs = await this.getJobs(request, filter); - return jobs?.map(this.mapJobClassV4toV3) ?? ([] as OutputJobV3Dto[]); + return jobs?.map(mapJobClassV4toV3) ?? ([] as OutputJobV3Dto[]); } /**