dicomweb-websocket-bridge
Version:
Redirect dicomweb traffic over websockets to a local PACS server
374 lines (328 loc) • 12.9 kB
text/typescript
import { FastifyInstance } from 'fastify';
import { getLogger, emitToQidoWsClient, emitToWadoWsClient, emitToStowRsClient } from '../utils';
import { v4 as uuidv4 } from 'uuid';
const logger = getLogger();
interface QueryParams {
[]: string;
}
module.exports = function (server: FastifyInstance, opts: unknown, done: () => void) {
server.get<{}>('/rs/studies', async (req, reply) => {
try {
const resp = await emitToQidoWsClient('STUDY', req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/metadata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
try {
const resp = await emitToQidoWsClient('SERIES', query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
try {
const resp = await emitToQidoWsClient('SERIES', query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/metadata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
try {
const resp = await emitToQidoWsClient('IMAGE', query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
try {
const resp = await emitToQidoWsClient('IMAGE', query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string; sopInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/metadata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.SOPInstanceUID = req.params.sopInstanceUid;
try {
const resp = await emitToQidoWsClient('IMAGE', query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string };
}>('/rs/studies/:studyInstanceUid', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/rendered', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.dataFormat = 'rendered';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/pixeldata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.dataFormat = 'pixeldata';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/thumbnail', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.dataFormat = 'thumbnail';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/rendered', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.dataFormat = 'rendered';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/pixeldata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.dataFormat = 'pixeldata';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/thumbnail', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.dataFormat = 'thumbnail';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string; sopInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.SOPInstanceUID = req.params.sopInstanceUid;
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string; sopInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/rendered', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.SOPInstanceUID = req.params.sopInstanceUid;
query.dataFormat = 'rendered';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string; sopInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/pixeldata', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.SOPInstanceUID = req.params.sopInstanceUid;
query.dataFormat = 'pixeldata';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.get<{
Querystring: QueryParams;
Params: { studyInstanceUid: string; seriesInstanceUid: string; sopInstanceUid: string };
}>('/rs/studies/:studyInstanceUid/series/:seriesInstanceUid/instances/:sopInstanceUid/thumbnail', async (req, reply) => {
const { query } = req;
query.StudyInstanceUID = req.params.studyInstanceUid;
query.SeriesInstanceUID = req.params.seriesInstanceUid;
query.SOPInstanceUID = req.params.sopInstanceUid;
query.dataFormat = 'thumbnail';
try {
const resp = await emitToWadoWsClient(req.query, req.websocketToken);
reply.send(resp);
} catch (error) {
logger.error(error);
reply.send(500);
}
});
//------------------------------------------------------------------
server.put('/rs/studies', async (req, reply) => {
const { headers, multipart, websocketToken } = req;
const type = headers['content-type'];
return await emitToStowRsClient(reply, multipart, websocketToken, type);
});
//------------------------------------------------------------------
server.get(
'/viewer/wadouri',
(req, reply): Promise<void> =>
new Promise((resolve) => {
const uuid = uuidv4();
const client = global.connectedClients[req.websocketToken];
if (!client || client.handshake.auth !== req.websocketToken) {
client.once(uuid, (data) => {
reply.header('Content-Type', data.contentType);
reply.send(data.buffer);
resolve();
});
const { query } = req;
client.emit('wadouri-request', { query, uuid });
} else {
const msg = 'no ws client connected, cannot emit';
logger.error(msg);
reply.send(msg);
}
})
);
done();
};
//------------------------------------------------------------------