Skip to content

Commit

Permalink
refactor: move syncFhir to plugin
Browse files Browse the repository at this point in the history
- The sync fhir is part of the plugin and is not within the scope of dicom
- so we move it to plugin folder
  • Loading branch information
Chinlinlee committed Jan 20, 2024
1 parent 071ad0e commit d3c0045
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 43 deletions.
36 changes: 15 additions & 21 deletions api/dicom-web/controller/STOW-RS/service/stow-rs.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,13 @@ const {
DicomJsonBinaryDataModel
} = require("@dicom-json-model");
const { DicomFileSaver } = require("./dicom-file-saver");
const { DicomFhirService } = require("./dicom-fhir.service");
const { DicomJpegGenerator } = require("./dicom-jpeg-generator");
const { logger } = require("../../../../../utils/logs/log");

const { raccoonConfig } = require("../../../../../config-class");
const { DicomWebService } = require("../../../service/dicom-web.service");
const { AuditManager } = require("@models/DICOM/audit/auditManager");
const { EventType } = require("@models/DICOM/audit/eventType");
const { EventOutcomeIndicator } = require("@models/DICOM/audit/auditUtils");

const {
apiPath: DICOM_WEB_API_PATH
} = raccoonConfig.dicomWebConfig;

const {
isSyncToFhir
} = raccoonConfig.fhirConfig;

const StowRsFailureCode = {
"GENERAL_FAILURE": "272",
Expand All @@ -34,11 +24,19 @@ const StowRsFailureCode = {
class StowRsService {
/**
* @param {import('express').Request} req
* @param {import('express').Response} res
* @param {import('formidable').File[]} uploadFiles
*/
constructor(req, uploadFiles) {
constructor(req, res, uploadFiles) {
this.request = req;
this.response = res;

this.response.locals = {
"storeInfos": []
};

this.uploadFiles = uploadFiles;

this.responseMessage = {
"00081190": {
//Study retrieve URL
Expand Down Expand Up @@ -90,29 +88,25 @@ class StowRsService {
let storeInstanceResult = await this.storeInstance(currentFile);
dicomJsonModel = storeInstanceResult.dicomJsonModel;
dicomFileSaveInfo = storeInstanceResult.dicomFileSaveInfo;
} catch(e) {
this.response.locals.storeInfos.push({
dicomFileSaveInfo,
dicomJsonModel
});
} catch (e) {
// log transferred failure
let auditManager = new AuditManager(
EventType.STORE_CREATE, EventOutcomeIndicator.MajorFailure,
DicomWebService.getRemoteAddress(this.request), DicomWebService.getRemoteHostname(this.request),
DicomWebService.getServerAddress(), DicomWebService.getServerHostname()
);

await auditManager.onDicomInstancesTransferred(
dicomJsonModel ? [dicomJsonModel.uidObj.studyUID] : "Unknown"
);

throw e;
}


//sync DICOM to FHIR
if (isSyncToFhir) {
let dicomFhirService = new DicomFhirService(this.request, dicomJsonModel);
await dicomFhirService.initDicomFhirConverter();
await dicomFhirService.postDicomToFhirServerAndStoreLog();
}

//generate JPEG
let dicomJpegGenerator = new DicomJpegGenerator(dicomJsonModel, dicomFileSaveInfo.instancePath);
dicomJpegGenerator.generateAllFrames();
Expand Down
2 changes: 1 addition & 1 deletion api/dicom-web/controller/STOW-RS/storeInstance.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class StoreInstanceController extends Controller {
let multipartParseResult = await requestMultipartParser.parse();

if (multipartParseResult.status) {
let stowRsService = new StowRsService(this.request, multipartParseResult.multipart.files);
let stowRsService = new StowRsService(this.request, this.response, multipartParseResult.multipart.files);
let storeInstancesResult = await stowRsService.storeInstances();

retCode = storeInstancesResult.code;
Expand Down
8 changes: 0 additions & 8 deletions config-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,6 @@ class DicomWebConfig {
}
}

class FhirConfig {
constructor() {
this.isSyncToFhir = env.get("SYCN_TO_FHIR_SERVER").default("true").asBool();
this.baseUrl = env.get("FHIRSERVER_BASE_URL").default("http://127.0.0.1:8089/fhir").asString();
}
}


class RaccoonConfig {
constructor() {
Expand All @@ -72,7 +65,6 @@ class RaccoonConfig {

this.dicomWebConfig = new DicomWebConfig();
this.dicomDimseConfig = new DimseConfig();
this.fhirConfig = new FhirConfig();

/** @type {string} */
this.mediaStorageUID = generateUidFromGuid(
Expand Down
15 changes: 15 additions & 0 deletions plugins/config.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,20 @@ module.exports.pluginsConfig = {
method: "get"
}
]
},
"syncToFhirServer": {
enable: false,
before: false,
routers: [
{
path: "/dicom-web/studies",
method: "post"
}
],
fhir: {
server: {
baseUrl: "http://127.0.0.1/fhir"
}
}
}
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { URL } = require("url");
const axios = require("axios").default;
const _ = require("lodash");
const { urlJoin } = require("../../../utils/url");
const { fhirLogger } = require("../../../utils/logs/log");
const { urlJoin } = require("../../utils/url");
const { fhirLogger } = require("../../utils/logs/log");
const { getModalitiesInStudy } = require("@dbModels/instance.model");
const { DicomJsonToFhir } = require("dicomjson-to-fhir");

class DICOMFHIRConverter {
class DicomFhirConverter {
constructor() {
this.dicomFHIR = {
patient: {},
Expand Down Expand Up @@ -329,4 +329,4 @@ class DICOMFHIRConverter {
}
}

module.exports.DICOMFHIRConverter = DICOMFHIRConverter;
module.exports.DicomFhirConverter = DicomFhirConverter;
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
const path = require("path");
const fs = require("fs");

const mongoose = require("mongoose");
const {
DICOMFHIRConverter
} = require("../../../../../models/FHIR/DICOM/DICOMToFHIR");
const { fhirLogger } = require("../../../../../utils/logs/log");
DicomFhirConverter
} = require("./DICOMToFHIR");
const { fhirLogger } = require("../../utils/logs/log");

const { raccoonConfig } = require("../../../../../config-class");
const { raccoonConfig } = require("../../config-class");

const {
apiPath: DICOM_WEB_API_PATH
} = raccoonConfig.dicomWebConfig;

const {
baseUrl: FHIR_BASE_URL
} = raccoonConfig.fhirConfig;

let pluginConfigFile = path.join(__dirname, "../config.template.js");
if (fs.existsSync(path.join(__dirname, "../config.js"))) {
pluginConfigFile = path.join(__dirname, "../config.js");
}

const fhirBaseUrl = require(pluginConfigFile).pluginsConfig?.syncToFhirServer?.fhir?.server?.baseUrl;

class DicomFhirService {
constructor(req, dicomJsonModel) {
if (!fhirBaseUrl) {
throw new Error("missing fhir config in your plugin config");
}

this.request = req;
this.dicomJsonModel = dicomJsonModel;

/**
* @private
*/
this.dicomFhirConverter = new DICOMFHIRConverter();
this.dicomFhirConverter = new DicomFhirConverter();
}

async initDicomFhirConverter() {
this.dicomFhirConverter.dicomWeb.name =`raccoon-dicom-web-server`;
let protocol = this.request.secure ? "https" : "http";
this.dicomFhirConverter.dicomWeb.retrieveStudiesUrl = `${protocol}://${this.request.headers.host}/${DICOM_WEB_API_PATH}/studies`;
this.dicomFhirConverter.fhir.baseUrl = FHIR_BASE_URL;
this.dicomFhirConverter.fhir.baseUrl = fhirBaseUrl;
}

async postDicomToFhirServerAndStoreLog() {
Expand Down
30 changes: 30 additions & 0 deletions plugins/syncToFhirServer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require("./mongoose/syncFHIRLog");
const path = require("path");
const fs = require("fs");
const { DicomFhirService } = require("./dicom-fhir.service");
let pluginConfigFile = path.join(__dirname, "../config.template.js");

if (fs.existsSync(path.join(__dirname, "../config.js"))) pluginConfigFile = path.join(__dirname, "../config.js");

const { pluginsConfig } = require(pluginConfigFile);

/**
*
* @param {import("express").Request} req
* @param {import("express").Response} res
* @returns
*/
module.exports = async function (req, res) {
if (!pluginsConfig?.syncToFhirServer?.enable) return;

setImmediate(async () => {
for (let i = 0; i < res.locals.storeInfos.length; i++) {
/** @type { import("./storeInfo").StoreInfo } */
let storeInfo = res.locals.storeInfos[i];
let dicomFhirService = new DicomFhirService(req, storeInfo.dicomJsonModel);
await dicomFhirService.initDicomFhirConverter();
await dicomFhirService.postDicomToFhirServerAndStoreLog();
}
});

};
File renamed without changes.
7 changes: 7 additions & 0 deletions plugins/syncToFhirServer/storeInfo.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { DicomJsonModel } from "@models/DICOM/dicom-json-model"
import type { DicomFileSaveInfo } from "@root/utils/typeDef/STOW-RS/STOW-RS"

export type StoreInfo = {
dicomFileSaveInfo: DicomFileSaveInfo,
dicomJsonModel: DicomJsonModel
}

0 comments on commit d3c0045

Please sign in to comment.