diff --git a/extensions/default/src/DicomWebProxyDataSource/index.js b/extensions/default/src/DicomWebProxyDataSource/index.js new file mode 100644 index 0000000000..e873237dde --- /dev/null +++ b/extensions/default/src/DicomWebProxyDataSource/index.js @@ -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 }; diff --git a/extensions/default/src/getDataSourcesModule.js b/extensions/default/src/getDataSourcesModule.js index dfccc6a18e..6eab56a2fa 100644 --- a/extensions/default/src/getDataSourcesModule.js +++ b/extensions/default/src/getDataSourcesModule.js @@ -5,6 +5,7 @@ import { createDicomWebApi } from './DicomWebDataSource/index.js'; import { createDicomJSONApi } from './DicomJSONDataSource/index.js'; import { createDicomLocalApi } from './DicomLocalDataSource/index.js'; +import { createDicomWebProxyApi } from './DicomWebProxyDataSource/index.js'; /** * @@ -16,6 +17,11 @@ function getDataSourcesModule() { type: 'webApi', createDataSource: createDicomWebApi, }, + { + name: 'dicomwebproxy', + type: 'webApi', + createDataSource: createDicomWebProxyApi, + }, { name: 'dicomjson', type: 'jsonApi', diff --git a/platform/docs/docs/configuration/dataSources/dicom-web-proxy.md b/platform/docs/docs/configuration/dataSources/dicom-web-proxy.md new file mode 100644 index 0000000000..6f98b36a45 --- /dev/null +++ b/platform/docs/docs/configuration/dataSources/dicom-web-proxy.md @@ -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. diff --git a/platform/viewer/public/config/default.js b/platform/viewer/public/config/default.js index 558f473c27..05a4089692 100644 --- a/platform/viewer/public/config/default.js +++ b/platform/viewer/public/config/default.js @@ -53,6 +53,14 @@ window.config = { useBulkDataURI: false, }, }, + { + friendlyName: 'dicomweb delegating proxy', + namespace: '@ohif/extension-default.dataSourcesModule.dicomwebproxy', + sourceName: 'dicomwebproxy', + configuration: { + name: 'dicomwebproxy', + }, + }, { friendlyName: 'dicom json', namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',