dicomweb-proxy
Version:
A proxy to translate between dicomweb and dimse
406 lines (336 loc) • 12.5 kB
text/typescript
import { fetchMeta } from '../dimse/fetchMeta';
import { FastifyPluginCallback } from 'fastify';
import { doFind } from '../dimse/findData';
import { QUERY_LEVEL } from '../dimse/querLevel';
import { doWadoRs } from '../dimse/wadoRs';
import { doWadoUri } from '../dimse/wadoUri';
import { LoggerSingleton } from '../utils/logger';
import deepmerge from 'deepmerge';
import combineMerge from '../utils/combineMerge';
const options = { arrayMerge: combineMerge };
const logger = LoggerSingleton.Instance;
interface IParamsStudy {
studyInstanceUid: string;
}
interface IParamsSeries extends IParamsStudy {
seriesInstanceUid: string;
}
interface IParamsImage extends IParamsSeries {
sopInstanceUid: string;
}
interface IQueryImage {
studyUID: string;
seriesUID: string;
objectUID: string;
}
interface QueryParams {
[key: string]: string;
}
const routes: FastifyPluginCallback = function (server, opts, done) {
server.get<{
Querystring: QueryParams;
}>('/rs/studies', async (req, reply) => {
try {
const { query } = req;
const json = deepmerge.all(await doFind(QUERY_LEVEL.STUDY, query), options);
return reply.send(json);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsStudy;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid', async (req, reply) => {
const { params } = req;
const { studyInstanceUid } = params;
try {
const rsp = await doWadoRs({ studyInstanceUid });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsStudy;
}>('/rs/studies/:studyInstanceUid/pixeldata', async (req, reply) => {
const { studyInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, dataFormat: 'pixeldata' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsStudy;
}>('/rs/studies/:studyInstanceUid/rendered', async (req, reply) => {
const { studyInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, dataFormat: 'rendered' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsStudy;
}>('/rs/studies/:studyInstanceUid/thumbnail', async (req, reply) => {
const { studyInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, dataFormat: 'thumbnail' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsStudy;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/metadata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
try {
const json = deepmerge.all(await doFind(QUERY_LEVEL.SERIES, query), options);
return reply.send(json);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsImage;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/bulkdata/:sopInstanceUid', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, sopInstanceUid, dataFormat: 'bulkdata' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsStudy;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/series', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
try {
const json = deepmerge.all(await doFind(QUERY_LEVEL.SERIES, query), options);
return reply.send(json);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsSeries;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid', async (req, reply) => {
const { params } = req;
const { studyInstanceUid, seriesInstanceUid } = params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsSeries;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/pixeldata', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, dataFormat: 'pixeldata' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsSeries;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/rendered', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, dataFormat: 'rendered' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsSeries;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/thumbnail', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, dataFormat: 'thumbnail' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsSeries;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances', async (req, reply) => {
const { query, params } = req;
query.StudyInstanceUID = params.studyInstanceUid;
query.SeriesInstanceUID = params.seriesInstanceUid;
try {
const json = deepmerge.all(await doFind(QUERY_LEVEL.IMAGE, query), options);
return reply.send(json);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsSeries;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/metadata', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid } = req.params;
const { query } = req;
query.StudyInstanceUID = studyInstanceUid;
query.SeriesInstanceUID = seriesInstanceUid;
try {
const rsp = await fetchMeta(query, studyInstanceUid, seriesInstanceUid);
return reply.send(rsp);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsImage;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/pixeldata', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, sopInstanceUid, dataFormat: 'pixeldata' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsImage;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/rendered', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, sopInstanceUid, dataFormat: 'rendered' });
console.log(rsp);
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsImage;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/thumbnail', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, sopInstanceUid, dataFormat: 'thumbnail' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
}
catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsImage;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/frames/:frame', async (req, reply) => {
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = req.params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, sopInstanceUid, dataFormat: 'pixeldata' });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Params: IParamsImage;
Querystring: QueryParams;
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid', async (req, reply) => {
const { params } = req;
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = params;
try {
const rsp = await doWadoRs({ studyInstanceUid, seriesInstanceUid, sopInstanceUid });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
//------------------------------------------------------------------
server.get<{
Querystring: IQueryImage;
}>('/wadouri', async (req, reply) => {
const { studyUID, seriesUID, objectUID } = req.query;
try {
const rsp = await doWadoUri({ studyInstanceUid: studyUID, seriesInstanceUid: seriesUID, sopInstanceUid: objectUID });
reply.header('Content-Type', rsp.contentType);
return reply.send(rsp.buffer);
} catch (error) {
logger.error(error);
return reply.code(500).send();
}
});
done();
};
module.exports = routes;
//------------------------------------------------------------------