From 92b67c08bbda5838d7c650d6a16d9be500324235 Mon Sep 17 00:00:00 2001 From: chinlinlee Date: Tue, 16 Jan 2024 23:01:21 +0800 Subject: [PATCH] refactor: wrap methods for bulk data model - wrap methods that we can change to another repository easier --- .../WADO-RS/bulkdata/service/bulkdata.js | 85 ++++-------- .../WADO-RS/service/rendered.service.js | 13 +- models/DICOM/dicom-json-model.js | 55 ++++---- models/mongodb/models/dicomBulkData.model.js | 128 +++++++++++++++++- 4 files changed, 177 insertions(+), 104 deletions(-) diff --git a/api/dicom-web/controller/WADO-RS/bulkdata/service/bulkdata.js b/api/dicom-web/controller/WADO-RS/bulkdata/service/bulkdata.js index efbe1e81..2c8fecc8 100644 --- a/api/dicom-web/controller/WADO-RS/bulkdata/service/bulkdata.js +++ b/api/dicom-web/controller/WADO-RS/bulkdata/service/bulkdata.js @@ -1,6 +1,6 @@ const fs = require("fs"); const path = require("path"); -const dicomBulkDataModel = require("@dbModels/dicomBulkData.model"); +const { DicomBulkDataModel } = require("@dbModels/dicomBulkData.model"); const { MultipartWriter } = require("../../../../../../utils/multipartWriter"); const { streamToBuffer } = require("@jorgeferrero/stream-to-buffer"); const { raccoonConfig } = require("../../../../../../config-class"); @@ -15,7 +15,7 @@ class BulkDataService { constructor(req, res, bulkDataFactory) { this.request = req; this.response = res; - this.bulkDataFactory = new bulkDataFactory({...this.request.params}); + this.bulkDataFactory = new bulkDataFactory({ ...this.request.params }); this.multipartWriter = new MultipartWriter([], req, res); this.multipartWriter.setHeaderMultipartRelatedContentType("application/octet-stream"); } @@ -28,7 +28,7 @@ class BulkDataService { async writeBulkData(bulkData) { let absFilename; // is imagePathObj - if(bulkData.instancePath) { + if (bulkData.instancePath) { absFilename = bulkData.instancePath; } else { absFilename = path.join(raccoonConfig.dicomWebConfig.storeRootPath, bulkData.filename); @@ -39,7 +39,7 @@ class BulkDataService { this.multipartWriter.writeBoundary(); this.multipartWriter.writeContentType("application/octet-stream"); this.multipartWriter.writeContentLength(fileBuffer.length); - + let urlPath = `/dicom-web/studies/${bulkData.studyUID}/series/${bulkData.seriesUID}/instances/${bulkData.instanceUID}/bulkdata/${bulkData.binaryValuePath}`; if (bulkData.instancePath) { urlPath = `/dicom-web/studies/${bulkData.studyUID}/series/${bulkData.seriesUID}/instances/${bulkData.instanceUID}`; @@ -51,7 +51,7 @@ class BulkDataService { async getBulkData() { return await this.bulkDataFactory.getBulkData(); } - + } class BulkDataFactory { @@ -79,15 +79,7 @@ class StudyBulkDataFactory extends BulkDataFactory { studyUID } = this.uids; - let studyBulkDataArray = await dicomBulkDataModel.find({ - $and: [ - { - studyUID - } - ] - }).exec(); - - return studyBulkDataArray; + return await DicomBulkDataModel.findStudyBulkData({ studyUID }); } } @@ -102,18 +94,11 @@ class SeriesBulkDataFactory extends BulkDataFactory { seriesUID } = this.uids; - let seriesBulkDataArray = await dicomBulkDataModel.find({ - $and: [ - { - studyUID - }, - { - seriesUID - } - ] - }).exec(); - - return seriesBulkDataArray; + return await DicomBulkDataModel.findSeriesBulkData({ + studyUID, + seriesUID + }); + } } @@ -130,21 +115,11 @@ class InstanceBulkDataFactory extends BulkDataFactory { instanceUID } = this.uids; - let instanceBulkDataArray = await dicomBulkDataModel.find({ - $and: [ - { - studyUID - }, - { - seriesUID - }, - { - instanceUID - } - ] - }).exec(); - - return instanceBulkDataArray; + return await DicomBulkDataModel.findInstanceBulkData({ + studyUID, + seriesUID, + instanceUID + }); } } @@ -162,27 +137,13 @@ class SpecificBulkDataFactory extends BulkDataFactory { binaryValuePath } = this.uids; - let bulkData = await dicomBulkDataModel.findOne({ - $and: [ - { - studyUID - }, - { - seriesUID - }, - { - instanceUID - }, - { - binaryValuePath: { - $regex: `^${binaryValuePath}`, - $options: "m" - } - } - ] - }).exec(); - - return bulkData; + return await DicomBulkDataModel.findSpecificBulkData({ + studyUID, + seriesUID, + instanceUID, + binaryValuePath + }); + } } diff --git a/api/dicom-web/controller/WADO-RS/service/rendered.service.js b/api/dicom-web/controller/WADO-RS/service/rendered.service.js index ae0eae78..1c376f2e 100644 --- a/api/dicom-web/controller/WADO-RS/service/rendered.service.js +++ b/api/dicom-web/controller/WADO-RS/service/rendered.service.js @@ -13,6 +13,7 @@ const errorResponse = require("../../../../../utils/errorResponse/errorResponseM const { logger } = require("../../../../../utils/logs/log"); const { raccoonConfig } = require("../../../../../config-class"); +const { DicomBulkDataModel } = require("@dbModels/dicomBulkData.model"); class RenderedImageProcessParameterHandler { #params; @@ -40,15 +41,9 @@ class RenderedImageProcessParameterHandler { let iccProfileAction = { "no": async () => { }, "yes": async () => { - let iccProfileBinaryFile = await mongoose.model("dicomBulkData").findOne({ - $and: [ - { - binaryValuePath: "00480105.Value.0.00282000.InlineBinary" - }, - { - instanceUID: instanceID - } - ] + let iccProfileBinaryFile = await DicomBulkDataModel.findOneBulkData({ + binaryValuePath: "00480105.Value.0.00282000.InlineBinary", + instanceUID: instanceID }); if (!iccProfileBinaryFile) throw new Error("The Image dose not have icc profile tag"); let iccProfileSrc = path.join(raccoonConfig.dicomWebConfig.storeRootPath, iccProfileBinaryFile.filename); diff --git a/models/DICOM/dicom-json-model.js b/models/DICOM/dicom-json-model.js index ac773bc7..9f995435 100644 --- a/models/DICOM/dicom-json-model.js +++ b/models/DICOM/dicom-json-model.js @@ -23,7 +23,7 @@ const { dictionary } = require("./dicom-tags-dic"); * *Remove tags when processing that not use them. */ const BIG_VALUE_TAGS = [ - "52009230", + "52009230", "00480200" ]; @@ -35,7 +35,7 @@ class BaseDicomJson { */ constructor(dicomJson, ...selection) { this.dicomJson = dicomJson; - if(selection.length > 0) { + if (selection.length > 0) { this.initSelectionJson(selection); } } @@ -46,7 +46,7 @@ class BaseDicomJson { */ initSelectionJson(selection) { let selectionJson = {}; - for(let i = 0; i < selection.length; i++) { + for (let i = 0; i < selection.length; i++) { let tag = selection[i]; let item = this.getItem(tag); if (item) { @@ -86,7 +86,7 @@ class BaseDicomJson { return _.get(dictionary.tag, `${tag}`); } - static getTagOfKeyword(keyword) { + static getTagOfKeyword(keyword) { return _.get(dictionary.keyword, `${keyword}`); } @@ -158,7 +158,7 @@ class DicomJsonModel { this.storeSeriesCollection(dbJson), this.storePatientCollection(dbJson) ]); - } catch(e) { + } catch (e) { throw e; } } @@ -346,7 +346,7 @@ class DicomJsonModel { } else { startedDate = moment(startedDate, "YYYYMMDDhhmmss").toISOString(); } - + return startedDate; } @@ -360,14 +360,14 @@ class DicomJsonModel { }; } - getPatientDicomJson(dicomJson=undefined) { + getPatientDicomJson(dicomJson = undefined) { if (!dicomJson) dicomJson = this.dicomJson; let patientDicomJson = { patientID: dicomJson.patientID }; - for(let tag in tagsNeedStore.Patient) { + for (let tag in tagsNeedStore.Patient) { let value = _.get(dicomJson, tag); if (value) _.set(patientDicomJson, tag, value); @@ -376,7 +376,7 @@ class DicomJsonModel { return patientDicomJson; } - getStudyDicomJson(dicomJson=undefined) { + getStudyDicomJson(dicomJson = undefined) { if (!dicomJson) dicomJson = this.dicomJson; @@ -385,7 +385,7 @@ class DicomJsonModel { studyPath: dicomJson.studyPath }; - for(let tag in tagsNeedStore.Study) { + for (let tag in tagsNeedStore.Study) { let value = _.get(dicomJson, tag); if (value) _.set(studyDicomJson, tag, value); @@ -399,7 +399,7 @@ class DicomJsonModel { }; } - getSeriesDicomJson(dicomJson=undefined) { + getSeriesDicomJson(dicomJson = undefined) { if (!dicomJson) dicomJson = this.dicomJson; let seriesDicomJson = { @@ -408,9 +408,9 @@ class DicomJsonModel { seriesPath: dicomJson.seriesPath }; - for(let tag in tagsNeedStore.Series) { + for (let tag in tagsNeedStore.Series) { let value = _.get(dicomJson, tag); - if(value) + if (value) _.set(seriesDicomJson, tag, value); } @@ -426,7 +426,7 @@ class DicomJsonModel { class DicomJsonBinaryDataModel { - constructor(dicomJsonModel, bulkDataModelClass=BulkData) { + constructor(dicomJsonModel, bulkDataModelClass = BulkData) { /** @type {DicomJsonModel} */ this.dicomJsonModel = dicomJsonModel; @@ -455,7 +455,7 @@ class DicomJsonBinaryDataModel { getPathGroupOfBinaryProperties_() { let pathGroupOfBinaryProperties = []; - for(let binaryKey of this.binaryKeys) { + for (let binaryKey of this.binaryKeys) { if (_.get(this.dicomJsonModel.dicomJson, `${binaryKey}.Value.0`)) { pathGroupOfBinaryProperties.push(`${binaryKey}.Value.0`); @@ -476,7 +476,7 @@ class DicomJsonBinaryDataModel { sopInstanceUID } = this.dicomJsonModel.uidObj; - for(let i = 0; i < this.binaryKeys.length ; i++) { + for (let i = 0; i < this.binaryKeys.length; i++) { let binaryKey = this.binaryKeys[i]; // Reset VR to UR, because BulkDataURI is URI @@ -493,7 +493,7 @@ class DicomJsonBinaryDataModel { `${binaryKey}.BulkDataURI`, `/studies/${studyUID}/series/${seriesUID}/instances/${sopInstanceUID}/bulkdata/${pathOfBinaryProperty}` ); - + _.unset(this.dicomJsonModel.dicomJson, `${binaryKey}.InlineBinary`); } @@ -510,14 +510,14 @@ class DicomJsonBinaryDataModel { let shortInstanceUID = shortHash(sopInstanceUID); - - for(let i = 0; i < this.pathGroupOfBinaryProperties.length ; i++) { + + for (let i = 0; i < this.pathGroupOfBinaryProperties.length; i++) { let relativeFilename = `files/bulkData/${shortInstanceUID}/`; let pathOfBinaryProperty = this.pathGroupOfBinaryProperties[i]; let binaryData = _.get(this.dicomJsonModel.dicomJson, pathOfBinaryProperty); - if(binaryData) { + if (binaryData) { relativeFilename += `${pathOfBinaryProperty}.raw`; let filename = path.join( raccoonConfig.dicomWebConfig.storeRootPath, @@ -561,16 +561,10 @@ class BulkData { binaryValuePath: this.pathOfBinaryProperty }; - await dicomBulkDataModel.updateOne( + await dicomBulkDataModel.createOrUpdateBulkData( { - $and: [ - { - instanceUID: this.uidObj.sopInstanceUID - }, - { - binaryValuePath: this.pathOfBinaryProperty - } - ] + instanceUID: this.uidObj.sopInstanceUID, + binaryValuePath: this.pathOfBinaryProperty }, { studyUID: this.uidObj.studyUID, @@ -578,9 +572,6 @@ class BulkData { instanceUID: this.uidObj.sopInstanceUID, filename: this.filename, binaryValuePath: this.pathOfBinaryProperty - }, - { - upsert: true } ); logger.info(`[STOW-RS] [Store bulkdata ${JSON.stringify(item)} successful]`); diff --git a/models/mongodb/models/dicomBulkData.model.js b/models/mongodb/models/dicomBulkData.model.js index 59230537..f7efddb7 100644 --- a/models/mongodb/models/dicomBulkData.model.js +++ b/models/mongodb/models/dicomBulkData.model.js @@ -28,7 +28,131 @@ let dicomBulkDataSchema = new mongoose.Schema( }, { strict: false, - versionKey: false + versionKey: false, + statics: { + /** + * + * @param {Object} query + * @param {string} query.studyUID + * @param {string} query.seriesUID + * @param {string} query.instanceUID + * @param {string} query.binaryValuePath + * @param {any} options + * @returns + */ + findOneBulkData: async function(query, options) { + return await mongoose.model("dicomBulkData").findOne(query, options).exec(); + }, + /** + * + * @param {Object} query + * @param {string} query.studyUID + * @param {any} options + * @returns + */ + findStudyBulkData: async function(query, options) { + return await mongoose.model("dicomBulkData").find({ + $and: [ + { + studyUID: query.studyUID + } + ] + }, options?.projection, options?.options).exec(); + }, + /** + * + * @param {Object} query + * @param {string} query.studyUID + * @param {string} query.seriesUID + * @param {*} options + * @returns + */ + findSeriesBulkData: async function(query, options) { + return await mongoose.model("dicomBulkData").find({ + $and: [ + { + studyUID: query.studyUID + }, + { + seriesUID: query.seriesUID + } + ] + }, options?.projection, options?.options).exec(); + }, + /** + * + * @param {Object} query + * @param {string} query.studyUID + * @param {string} query.seriesUID + * @param {string} query.instanceUID + * @param {*} options + * @returns + */ + findInstanceBulkData: async function(query, options) { + return await mongoose.model("dicomBulkData").find({ + $and: [ + { + studyUID: query.studyUID + }, + { + seriesUID: query.seriesUID + }, + { + instanceUID: query.instanceUID + } + ] + }, options?.projection, options?.options).exec(); + }, + /** + * + * @param {Object} query + * @param {string} query.studyUID + * @param {string} query.seriesUID + * @param {string} query.instanceUID + * @param {string} query.binaryValuePath + * @param {*} options + * @returns + */ + findSpecificBulkData: async function(query, options) { + return await mongoose.model("dicomBulkData").findOne({ + $and: [ + { + studyUID: query.studyUID + }, + { + seriesUID: query.seriesUID + }, + { + instanceUID: query.instanceUID + }, + { + binaryValuePath: { + $regex: `^${query.binaryValuePath}`, + $options: "m" + } + } + ] + }, options?.projection, options?.options).exec(); + }, + createOrUpdateBulkData: async function(query, newBulkData, options) { + await mongoose.model("dicomBulkData").updateOne( + { + $and: [ + { + instanceUID: query.instanceUID + }, + { + binaryValuePath: query.binaryValuePath + } + ] + }, + newBulkData, + { + upsert: true + } + ); + } + } } ); @@ -37,4 +161,6 @@ let dicomBulkData = mongoose.model( dicomBulkDataSchema, "dicomBulkData" ); + module.exports = dicomBulkData; +module.exports.DicomBulkDataModel = dicomBulkData;