# `@ohif/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](../../README.md#pre-requisites)

## Development
View root development section [development](../../README.md#development).  Additionally, this component
is developped 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:
```shell
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:
```shell
dicomwebserver
or
node bin/dicomwebserver.mjs
```

This will serve up the files in `~/ohif` and `~/dicomweb` in the following way:
1. 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.
2. For the OHIF files, if the URL doesn't match a dicomweb url, and is otherwise not found, serve up `~/ohif/index.html`
3. 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
4. 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:
```js
{
  // 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 files
* `port` 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 capabilities
* `accessCheck` specifies the name of a plugin that checks to see if the study is available in the dicomweb dir
* `stowCommands` 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:
```js
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 the `studies/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 destination
* `studyQueryDb` does a query for studies against a database. Also, it stores to the given destination.

## 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.

