feat(proxy datasource): JSON server configuration launch (#2791)
* feat: delegating dicom web proxy datasource * fix: configurably allow WADO image loader to issue preflight OPTIONS request * Added documentation and fixed up some error handling from PR review * review comments changes * another small code review fix
This commit is contained in:
parent
b5b936b53e
commit
0e3491d6bb
84
extensions/default/src/DicomWebProxyDataSource/index.js
Normal file
84
extensions/default/src/DicomWebProxyDataSource/index.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { IWebApiDataSource } from '@ohif/core';
|
||||||
|
import { createDicomWebApi } from '../DicomWebDataSource/index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This datasource is initialized with a url that returns a JSON object with a
|
||||||
|
* dicomWeb datasource configuration array present in a "servers" object.
|
||||||
|
*
|
||||||
|
* Only the first array item is parsed, if there are multiple items in the
|
||||||
|
* dicomWeb configuration array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function createDicomWebProxyApi(
|
||||||
|
dicomWebProxyConfig,
|
||||||
|
UserAuthenticationService
|
||||||
|
) {
|
||||||
|
const { name } = dicomWebProxyConfig;
|
||||||
|
let dicomWebDelegate = undefined;
|
||||||
|
|
||||||
|
const implementation = {
|
||||||
|
initialize: async ({ params, query }) => {
|
||||||
|
let studyInstanceUIDs = [];
|
||||||
|
|
||||||
|
// there seem to be a couple of variations of the case for this parameter
|
||||||
|
const queryStudyInstanceUIDs =
|
||||||
|
query.get('studyInstanceUIDs') || query.get('studyInstanceUids');
|
||||||
|
if (!queryStudyInstanceUIDs) {
|
||||||
|
throw new Error(`No studyInstanceUids in request for '${name}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = query.get('url');
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
throw new Error(`No url for '${name}'`);
|
||||||
|
} else {
|
||||||
|
const response = await fetch(url);
|
||||||
|
let data = await response.json();
|
||||||
|
if (!data.servers?.dicomWeb?.[0]) {
|
||||||
|
throw new Error('Invalid configuration returned by url');
|
||||||
|
}
|
||||||
|
|
||||||
|
dicomWebDelegate = createDicomWebApi(
|
||||||
|
data.servers.dicomWeb[0],
|
||||||
|
UserAuthenticationService
|
||||||
|
);
|
||||||
|
studyInstanceUIDs = queryStudyInstanceUIDs.split(';');
|
||||||
|
}
|
||||||
|
return studyInstanceUIDs;
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
studies: {
|
||||||
|
search: params => dicomWebDelegate.query.studies.search(params),
|
||||||
|
},
|
||||||
|
series: {
|
||||||
|
search: (...args) => dicomWebDelegate.query.series.search(...args),
|
||||||
|
},
|
||||||
|
instances: {
|
||||||
|
search: (studyInstanceUid, queryParameters) =>
|
||||||
|
dicomWebDelegate.query.instances.search(
|
||||||
|
studyInstanceUid,
|
||||||
|
queryParameters
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
retrieve: {
|
||||||
|
directURL: (...args) => dicomWebDelegate.retrieve.directURL(...args),
|
||||||
|
series: {
|
||||||
|
metadata: (...args) =>
|
||||||
|
dicomWebDelegate.retrieve.series.metadata(...args),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
store: {
|
||||||
|
dicom: (...args) => dicomWebDelegate.store(...args),
|
||||||
|
},
|
||||||
|
deleteStudyMetadataPromise: (...args) =>
|
||||||
|
dicomWebDelegate.deleteStudyMetadataPromise(...args),
|
||||||
|
getImageIdsForDisplaySet: (...args) =>
|
||||||
|
dicomWebDelegate.getImageIdsForDisplaySet(...args),
|
||||||
|
getImageIdsForInstance: (...args) =>
|
||||||
|
dicomWebDelegate.getImageIdsForInstance(...args),
|
||||||
|
};
|
||||||
|
return IWebApiDataSource.create(implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { createDicomWebProxyApi };
|
||||||
@ -5,6 +5,7 @@
|
|||||||
import { createDicomWebApi } from './DicomWebDataSource/index.js';
|
import { createDicomWebApi } from './DicomWebDataSource/index.js';
|
||||||
import { createDicomJSONApi } from './DicomJSONDataSource/index.js';
|
import { createDicomJSONApi } from './DicomJSONDataSource/index.js';
|
||||||
import { createDicomLocalApi } from './DicomLocalDataSource/index.js';
|
import { createDicomLocalApi } from './DicomLocalDataSource/index.js';
|
||||||
|
import { createDicomWebProxyApi } from './DicomWebProxyDataSource/index.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -16,6 +17,11 @@ function getDataSourcesModule() {
|
|||||||
type: 'webApi',
|
type: 'webApi',
|
||||||
createDataSource: createDicomWebApi,
|
createDataSource: createDicomWebApi,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'dicomwebproxy',
|
||||||
|
type: 'webApi',
|
||||||
|
createDataSource: createDicomWebProxyApi,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'dicomjson',
|
name: 'dicomjson',
|
||||||
type: 'jsonApi',
|
type: 'jsonApi',
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 4
|
||||||
|
sidebar_label: DICOMweb Proxy
|
||||||
|
---
|
||||||
|
|
||||||
|
# DICOMweb Proxy
|
||||||
|
|
||||||
|
You can launch the OHIF Viewer with a url that returns a JSON file which
|
||||||
|
contains a DICOMWeb configuration. The DICOMweb Proxy constructs a DICOMweb
|
||||||
|
datasource and delegates subsequent requests for metadata and images to that.
|
||||||
|
|
||||||
|
Usage is similar to that of the [DICOM JSON](./dicom-json.md) datasource and
|
||||||
|
might look like
|
||||||
|
|
||||||
|
`https://v3-demo.ohif.org/viewer/dicomwebproxy?url=https://ohif-dicom-json-example.s3.amazonaws.com/dicomweb.json`
|
||||||
|
|
||||||
|
The url to the location of the JSON file is passed in the query
|
||||||
|
after the `dicomwebproxy` string, which is
|
||||||
|
`https://ohif-dicom-json-example.s3.amazonaws.com/dicomweb.json` (this json file
|
||||||
|
does not exist at the moment of this writing).
|
||||||
|
|
||||||
|
## DICOMweb JSON configuration sample
|
||||||
|
|
||||||
|
The json returned by the url in this example contains a dicomweb configuration
|
||||||
|
(see [DICOMweb](dicom-web.md)), in a "servers" object, which is then used to
|
||||||
|
construct a dynamic DICOMweb datasource to delegate requests to. Here is an
|
||||||
|
example configuration that might be returned using the url parameter.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"servers": {
|
||||||
|
"dicomWeb": [
|
||||||
|
{
|
||||||
|
"name": "DCM4CHEE",
|
||||||
|
"wadoUriRoot": "https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado",
|
||||||
|
"qidoRoot": "https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
|
"wadoRoot": "https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
|
"qidoSupportsIncludeField": true,
|
||||||
|
"supportsReject": true,
|
||||||
|
"imageRendering": "wadors",
|
||||||
|
"thumbnailRendering": "wadors",
|
||||||
|
"enableStudyLazyLoad": true,
|
||||||
|
"supportsFuzzyMatching": true,
|
||||||
|
"supportsWildcard": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The DICOMweb Proxy expects the json returned by the url parameter it is invoked
|
||||||
|
with to include a servers object which contains a "dicomWeb" configuration array
|
||||||
|
as above. It will only consider the first array item in the dicomWeb
|
||||||
|
configuration.
|
||||||
@ -53,6 +53,14 @@ window.config = {
|
|||||||
useBulkDataURI: false,
|
useBulkDataURI: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
friendlyName: 'dicomweb delegating proxy',
|
||||||
|
namespace: '@ohif/extension-default.dataSourcesModule.dicomwebproxy',
|
||||||
|
sourceName: 'dicomwebproxy',
|
||||||
|
configuration: {
|
||||||
|
name: 'dicomwebproxy',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
friendlyName: 'dicom json',
|
friendlyName: 'dicom json',
|
||||||
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
|
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user