@radicalimaging/static-wado-webserver
v1.5.0
Published
Webserver to serve a static-wado repo
Downloads
188
Readme
@radicalimaging/static-wado-webserver
The static wado webserver demonstrates how to serve up the files generated by static-wado-creator to provide a DICOMweb set of services, while allowing certain services to be modified by adding a custom extension.
Pre-requisites
View root pre-requisites section pre-requisites
Development
View root development section development. Additionally, this component is developed using ecmascript modules, so be aware that most of the code uses the .mjs module extension for javascript.
Installation
The component can be installed as a global module via:
npm install -g
Usage
There is a command line tool, installed as above, that provides an extendible web service. That is run installed, or uninstalled as:
dicomwebserver
or
node bin/dicomwebserver.mjs
This will serve up the files in ~/ohif
and ~/dicomweb
in the following way:
- Files in ohif are served according to their extension, using a .gz extension version of it when present, served to
http://localhost:5000
by default. - For the OHIF files, if the URL doesn't match a dicomweb url, and is otherwise not found, serve up
~/ohif/index.html
- For the DICOMweb files, serve it up as follows:
- For studies, series and instances queries, serve up the index.json.gz file by default
- For metadata, serve up the metadata.gz file as 'application/json'
- For frames retrieval, serve up the raw file name directly, but if not found, fallback to the frame number.gz, as a GZIP file
- Provide a studyQuery result that reads the studies/index.json.gz file and filters it according to the search criteria
Default Configuration Files
The tool looks for a JSON5 configuration file (which is JSON + comments basically), located either in ./static-wado.json5
or else in ~/static-wado.json5
. This configuration file can override settings such as the directory that stores the client, or the port number on the web service etc. These configuration values are then further modified by command-line settings.
Alternatively, the settings file to use can be specified with the -c or --configuration
setting, passing it a file name to read as a JSON5 file (it will add the extension if not present). The format of the file looks like this:
{
// Defaults that apply to static wado generally
staticWadoConfig {
rootDir: '/data/dicomweb',
},
// Defaults that apply to the DICOMweb server
dicomWebServerConfig: {
studyQuery: "exampleCustomPlugin",
clientDir: "~/ohif",
port: 8080,
},
// plugin locations, used to load custom plugins
plugins: {
// Where to load the custom plugin from.
// This is COMPLETELY code injection, so require access control both to the static-wado.json5 file and the specified file
exampleCustomPlugin: "/src/exampleCustomPlugin/dist/dist.js",
},
}
Configuration Values
- The
rootDir
parameter sets the default root directory for storing the DICOMweb data, or for serving it from. clientDir
specifies the location of the client filesport
specifies the default port for the web server to run on (do NOT specify this in staticcWadoConfig, as the SCP uses the same name)studyQuery
specifies the name of a plugin to use that provides study level query capabilitiesaccessCheck
specifies the name of a plugin that checks to see if the study is available in the dicomweb dirstowCommands
is an array of command lines that will be passed a set of filenames to store.corsOptions
specifies an object with options to set up cors. CORS is not applied when this property is not present or if there is no origin (inner property) defined.
stowCommands to store to DICOM
Assuming you have dcm4che installed, then you can configure stowCommands like this:
stowComands: ["mkdicomweb", "dcmsnd -L SCUNAME SCPName@hostname:104"],
to configure to store to the local mkdicomweb plugin, plus SCPName on host hostname on port 104.
Configure external viewer
Webserver can also be integrated with external viewer server. In order to achieve that configuration file must contain:
{
...
corsOptions: {
enabled: true,
origin: ['http://viewer-origin:port]
...other configs
}
}
This will ensure webserver accepts cross origins requests. @see {@link https://www.npmjs.com/package/cors#configuration-options} for more options properties.
Plugins
There are several plugins currently defined:
studyQueryReadIndex
reads thestudies/index.json.gz
file and sub-selects it to generate the query response.studiesQueryToScp
queries a remote DIMSE service to find the response for the study level data.The following plugins are planned:
retrieveCMove
will check if the study is locally available, and if not, will perform a c-move to the specified scp destinationstudyQueryDb
does a query for studies against a database. Also, it stores to the given destination.
Additional external plugins can be defined to extend the base router by defining a webserverPlugins
array in the configuration file - ex:
clientGroup { plugins: [
{
pluginModule: 'my-plugins',
pluginName: 'aPlugin',
pluginRoute: '/endpoint1/:myParam',
},
{
pluginModule: 'my-plugins',
pluginName: 'bPlugin',
pluginRoute: '/endpoint2',
},
]}
The plugin is imported dynamically using the pluginModule and pluginModuleName, and must define a setRoute method that registers the pluginRoute with the express router - ex:
aPlugin: {
setRoute: (routerExpress, pluginItem) => {
routerExpress.get(pluginItem.pluginRoute, async (req, res) => {
res.status(200).send(`Invoked with ${req.params.myParam}`);
});
},
},
Design
The basic design of the dicomwebserver is just a configuration script that uses expressjs
to configure the default handling of the responses, plus add the plugin handling for the responses on top of that. All of the interesting logic is actually within the various plugins, and those are intentionally kept fairly small. The intent of this is to allow the same plugins to eventually be re-used for serving data from other sources such as an AWS s3 bucket via cloudfront.