Skip to content

Commit

Permalink
refactor: duplicate codes in retrieve controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
Chinlinlee committed Nov 4, 2023
1 parent d13c5a0 commit a9676d8
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 219 deletions.
152 changes: 152 additions & 0 deletions api/dicom-web/controller/WADO-RS/base.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
const { Controller } = require("@root/api/controller.class");
const { RetrieveAuditService } = require("./service/retrieveAudit.service");
const { EventOutcomeIndicator } = require("@models/DICOM/audit/auditUtils");
const { WADOZip } = require("./service/WADOZip");
const { ApiLogger } = require("@root/utils/logs/api-logger");
const { sendNotSupportedMediaType, getAcceptType, supportInstanceMultipartType, ImageMultipartWriter, InstanceImagePathFactory, multipartContentTypeWriter, StudyImagePathFactory, SeriesImagePathFactory } = require("./service/WADO-RS.service");
const { ControllerErrorHandler } = require("@error/controller.handler");

class BaseRetrieveController extends Controller {
constructor(req, res) {
super(req, res);
this.apiLogger = new ApiLogger(this.request, "WADO-RS");
this.apiLogger.addTokenValue();
this.zipResponseHandlerType = BaseZipResponseHandler;
this.multipartResponseHandlerType = BaseMultipartRelatedResponseHandler;
}

logAction() {
throw new Error("Not implemented.");
}

async mainProcess() {
try {
if (this.request.headers.accept.toLowerCase() === "application/zip") {
return await this.responseZip();
} else if (this.request.headers.accept.includes("multipart/related")) {
return await this.responseMultipartRelated();
} else if (this.request.headers.accept.includes("*")) {
this.request.headers.accept = "multipart/related; type=\"application/dicom\"";
return await this.responseMultipartRelated();
}

return sendNotSupportedMediaType(this.response, this.request.headers.accept);
} catch (e) {
return ControllerErrorHandler.raiseInternalServerError(e, this.apiLogger, this.response);
}
}

async responseZip() {
let zipResponseHandler = new this.zipResponseHandlerType(this.request, this.response);
await zipResponseHandler.doResponse();
}

async responseMultipartRelated() {
let multipartResponseHandler = new this.multipartResponseHandlerType(this.request, this.response);
await multipartResponseHandler.doResponse();
}
}


class BaseZipResponseHandler {
constructor(req, res) {
this.request = req;
this.response = res;
this.wadoZip = new WADOZip(this.request, this.response);
this.zipGetter = this.wadoZip.getZipOfInstanceDICOMFile.bind(this.wadoZip);
}

async doResponse() {
let retrieveAuditService = new RetrieveAuditService(this.request, this.request.params.studyUID, EventOutcomeIndicator.Success);

await retrieveAuditService.onBeginRetrieve();

let zipResult = await this.zipGetter();
if (zipResult.status) {
await retrieveAuditService.completedRetrieve();
return this.response.end();
} else {
retrieveAuditService.eventResult = EventOutcomeIndicator.MajorFailure;
await retrieveAuditService.completedRetrieve();
this.response.writeHead(zipResult.code, {
"Content-Type": "application/dicom+json"
});
return this.response.end(JSON.stringify(zipResult));
}
}
}

class StudyZipResponseHandler extends BaseZipResponseHandler {
constructor(req, res) {
super(req, res);
this.zipGetter = this.wadoZip.getZipOfStudyDICOMFiles.bind(this.wadoZip);
}
}

class SeriesZipResponseHandler extends BaseZipResponseHandler {
constructor(req, res) {
super(req, res);
this.zipGetter = this.wadoZip.getZipOfSeriesDICOMFiles.bind(this.wadoZip);
}
}

class InstanceZipResponseHandler extends BaseZipResponseHandler {
constructor(req, res) {
super(req, res);
this.zipGetter = this.wadoZip.getZipOfInstanceDICOMFile.bind(this.wadoZip);
}
}

class BaseMultipartRelatedResponseHandler {
constructor(req, res) {
this.request = req;
this.response = res;
this.imagePathFactoryType = StudyImagePathFactory;
}

async doResponse() {
let type = getAcceptType(this.request);
let isSupported = supportInstanceMultipartType.indexOf(type) > -1;
if (!isSupported) {
return sendNotSupportedMediaType(this.response, type);
}

let imageMultipartWriter = new ImageMultipartWriter(
this.request,
this.response,
this.imagePathFactoryType ,
multipartContentTypeWriter[type]
);

return await imageMultipartWriter.write();
}
}

class StudyMultipartRelatedResponseHandler extends BaseMultipartRelatedResponseHandler {
constructor(req, res) {
super(req, res);
this.imagePathFactoryType = StudyImagePathFactory;
}
}

class SeriesMultipartRelatedResponseHandler extends BaseMultipartRelatedResponseHandler {
constructor(req, res) {
super(req, res);
this.imagePathFactoryType = SeriesImagePathFactory;
}
}

class InstanceMultipartRelatedResponseHandler extends BaseMultipartRelatedResponseHandler {
constructor(req, res) {
super(req, res);
this.imagePathFactoryType = InstanceImagePathFactory;
}
}

module.exports.BaseRetrieveController = BaseRetrieveController;
module.exports.StudyZipResponseHandler = StudyZipResponseHandler;
module.exports.SeriesZipResponseHandler = SeriesZipResponseHandler;
module.exports.InstanceZipResponseHandler = InstanceZipResponseHandler;
module.exports.StudyMultipartRelatedResponseHandler = StudyMultipartRelatedResponseHandler;
module.exports.SeriesMultipartRelatedResponseHandler = SeriesMultipartRelatedResponseHandler;
module.exports.InstanceMultipartRelatedResponseHandler = InstanceMultipartRelatedResponseHandler;
82 changes: 7 additions & 75 deletions api/dicom-web/controller/WADO-RS/retrieveInstance.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,14 @@
const wadoService = require("./service/WADO-RS.service");
const { WADOZip } = require("./service/WADOZip");
const { ApiLogger } = require("../../../../utils/logs/api-logger");
const { Controller } = require("../../../controller.class");
const { RetrieveAuditService } = require("./service/retrieveAudit.service");
const { EventOutcomeIndicator } = require("@models/DICOM/audit/auditUtils");
class RetrieveInstanceOfSeriesOfStudiesController extends Controller {
const { BaseRetrieveController, InstanceZipResponseHandler, InstanceMultipartRelatedResponseHandler } = require("./base.controller");
class RetrieveInstanceOfSeriesOfStudiesController extends BaseRetrieveController {
constructor(req, res) {
super(req, res);
this.zipResponseHandlerType = InstanceZipResponseHandler;
this.multipartResponseHandlerType = InstanceMultipartRelatedResponseHandler;
}

async mainProcess() {
let apiLogger = new ApiLogger(this.request, "WADO-RS");
apiLogger.addTokenValue();

apiLogger.logger.info(`Get study's series' instances, study UID: ${this.request.params.studyUID}, series UID: ${this.request.params.seriesUID}`);
apiLogger.logger.info(`Request Accept: ${this.request.headers.accept}`);

try {

if (this.request.headers.accept.toLowerCase() === "application/zip") {
return await this.responseZip();
} else if (this.request.headers.accept.includes("multipart/related")) {
return await this.responseMultipartRelated();
} else if (this.request.headers.accept.includes("*")){
this.request.headers.accept = "multipart/related; type=\"application/dicom\"";
return await this.responseMultipartRelated();
}

return wadoService.sendNotSupportedMediaType(this.response, this.request.headers.accept);
} catch(e) {
let errorStr = JSON.stringify(e, Object.getOwnPropertyNames(e));
apiLogger.logger.error(errorStr);

this.response.writeHead(500, {
"Content-Type": "application/dicom+json"
});
this.response.end(JSON.stringify({
code: 500,
message: errorStr
}));
}
}

async responseZip() {
let retrieveAuditService = new RetrieveAuditService(this.request, this.request.params.studyUID, EventOutcomeIndicator.Success);

let wadoZip = new WADOZip(this.request, this.response);
await retrieveAuditService.onBeginRetrieve();

let zipResult = await wadoZip.getZipOfInstanceDICOMFile();
if (zipResult.status) {
await retrieveAuditService.completedRetrieve();
return this.response.end();
} else {
retrieveAuditService.eventResult = EventOutcomeIndicator.MajorFailure;
await retrieveAuditService.completedRetrieve();
this.response.writeHead(zipResult.code, {
"Content-Type": "application/dicom+json"
});
return this.response.end(JSON.stringify(zipResult));
}
}

async responseMultipartRelated() {
let type = wadoService.getAcceptType(this.request);
let isSupported = wadoService.supportInstanceMultipartType.indexOf(type) > -1;
if (!isSupported) {
return wadoService.sendNotSupportedMediaType(this.response, type);
}

let imageMultipartWriter = new wadoService.ImageMultipartWriter(
this.request,
this.response,
wadoService.InstanceImagePathFactory,
wadoService.multipartContentTypeWriter[type]
);

return await imageMultipartWriter.write();
logAction() {
this.apiLogger.logger.info(`Get study's series' instances, study UID: ${this.request.params.studyUID}, series UID: ${this.request.params.seriesUID}`);
this.apiLogger.logger.info(`Request Accept: ${this.request.headers.accept}`);
}
}

Expand Down
78 changes: 6 additions & 72 deletions api/dicom-web/controller/WADO-RS/retrieveStudy-Series-Instances.js
Original file line number Diff line number Diff line change
@@ -1,80 +1,14 @@
const { logger } = require("../../../../utils/logs/log");
const wadoService = require("./service/WADO-RS.service");
const { WADOZip } = require("./service/WADOZip");
const errorResponse = require("../../../../utils/errorResponse/errorResponseMessage");
const { Controller } = require("../../../controller.class");
const { RetrieveAuditService } = require("./service/retrieveAudit.service");
const { EventOutcomeIndicator } = require("@models/DICOM/audit/auditUtils");
const { BaseRetrieveController, SeriesZipResponseHandler, SeriesMultipartRelatedResponseHandler } = require("./base.controller");

class RetrieveInstancesOfSeries extends Controller {
class RetrieveInstancesOfSeries extends BaseRetrieveController {
constructor(req, res) {
super(req, res);
this.zipResponseHandlerType = SeriesZipResponseHandler;
this.multipartResponseHandlerType = SeriesMultipartRelatedResponseHandler;
}

async mainProcess() {
try {
logger.info(`[WADO-RS] [Get study's series' instances, study UID: ${this.request.params.studyUID}, series UID: ${this.request.params.seriesUID}] [Request Accept: ${this.request.headers.accept}]`);

if (this.request.headers.accept.toLowerCase() === "application/zip") {
return await this.responseZip();
} else if (this.request.headers.accept.includes("multipart/related")) {
return await this.responseMultipartRelated();
} else if (this.request.headers.accept.includes("*")){
this.request.headers.accept = "multipart/related; type=\"application/dicom\"";
return await this.responseMultipartRelated();
}

return wadoService.sendNotSupportedMediaType(this.response, this.request.headers.accept);
} catch (e) {
let errorStr = JSON.stringify(e, Object.getOwnPropertyNames(e));
logger.error(`[WADO-RS] [Error: ${errorStr}]`);

this.response.writeHead(500, {
"Content-Type": "application/dicom+json"
});
this.response.end(JSON.stringify({
code: 500,
message: errorStr
}));
}
}

async responseZip() {
let retrieveAuditService = new RetrieveAuditService(this.request, this.request.params.studyUID, EventOutcomeIndicator.Success);

let wadoZip = new WADOZip(this.request, this.response);
await retrieveAuditService.onBeginRetrieve();

let zipResult = await wadoZip.getZipOfSeriesDICOMFiles();
if (zipResult.status) {
await retrieveAuditService.completedRetrieve();
return this.response.end();
} else {
retrieveAuditService.eventResult = EventOutcomeIndicator.MajorFailure;
await retrieveAuditService.completedRetrieve();

this.response.writeHead(zipResult.code, {
"Content-Type": "application/dicom+json"
});
return this.response.end(JSON.stringify(zipResult));
}
}

async responseMultipartRelated() {
let type = wadoService.getAcceptType(this.request);
let isSupported = wadoService.supportInstanceMultipartType.indexOf(type) > -1;
if (!isSupported) {
return wadoService.sendNotSupportedMediaType(this.response, type);
}

let imageMultipartWriter = new wadoService.ImageMultipartWriter(
this.request,
this.response,
wadoService.SeriesImagePathFactory,
wadoService.multipartContentTypeWriter[type]
);

return await imageMultipartWriter.write();
logAction() {
this.apiLogger.logger.info(`[WADO-RS] [Get study's series' instances, study UID: ${this.request.params.studyUID}, series UID: ${this.request.params.seriesUID}] [Request Accept: ${this.request.headers.accept}]`);
}
}

Expand Down
Loading

0 comments on commit a9676d8

Please sign in to comment.