Mercurial > hg > orthanc-dicomweb
changeset 345:b005ab8a64bb
test to avoid access to the filesystem in WADO-RS metadata
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 19 Aug 2019 17:36:48 +0200 |
parents | 270a58adbac2 |
children | 442c6e3083ed |
files | Plugin/WadoRs.cpp |
diffstat | 1 files changed, 79 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugin/WadoRs.cpp Mon Aug 19 16:39:29 2019 +0200 +++ b/Plugin/WadoRs.cpp Mon Aug 19 17:36:48 2019 +0200 @@ -245,11 +245,39 @@ } -static bool GetDicomIdentifiers(std::string& studyInstanceUid, - std::string& seriesInstanceUid, - std::string& sopInstanceUid, - const std::string& orthancId) + +static void CopyDictionary(Json::Value& target, + const Json::Value& source) { + if (target.type() != Json::objectValue || + source.type() != Json::objectValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + Json::Value::Members members = source.getMemberNames(); + + for (size_t i = 0; i < members.size(); i++) + { + if (source[members[i]].type() != Json::stringValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + else + { + target[members[i]] = source[members[i]].asString(); + } + } +} + + +static void WriteInstanceMetadata(OrthancPlugins::DicomWebFormatter::HttpWriter& writer, + const std::string& orthancId, + const std::string& wadoBase) +{ + std::string studyInstanceUid, seriesInstanceUid, sopInstanceUid; + bool found; + #if 0 // This version is slow, as one access is done to the filesystem // (cf. "/instances/.../tags"). It was in use in versions <= 1.0 of @@ -271,30 +299,33 @@ studyInstanceUid = dicom[STUDY_INSTANCE_UID].asString(); seriesInstanceUid = dicom[SERIES_INSTANCE_UID].asString(); sopInstanceUid = dicom[SOP_INSTANCE_UID].asString(); - return true; + found = true; } else { - return false; + found = false; } #else // This version is faster, as it only queries the database (no file // is opened on the filesystem, besides the SQLite database). - Json::Value study, series, instance; + Json::Value patient, study, series, instance; static const char* const MAIN_DICOM_TAGS = "MainDicomTags"; static const char* const STUDY_INSTANCE_UID = "StudyInstanceUID"; static const char* const SERIES_INSTANCE_UID = "SeriesInstanceUID"; static const char* const SOP_INSTANCE_UID = "SOPInstanceUID"; - if (OrthancPlugins::RestApiGet(study, "/instances/" + orthancId + "/study", false) && + if (OrthancPlugins::RestApiGet(patient, "/instances/" + orthancId + "/patient", false) && + OrthancPlugins::RestApiGet(study, "/instances/" + orthancId + "/study", false) && OrthancPlugins::RestApiGet(series, "/instances/" + orthancId + "/series", false) && OrthancPlugins::RestApiGet(instance, "/instances/" + orthancId, false) && + patient.isMember(MAIN_DICOM_TAGS) && study.isMember(MAIN_DICOM_TAGS) && series.isMember(MAIN_DICOM_TAGS) && instance.isMember(MAIN_DICOM_TAGS) && + patient[MAIN_DICOM_TAGS].type() == Json::objectValue && study[MAIN_DICOM_TAGS].type() == Json::objectValue && series[MAIN_DICOM_TAGS].type() == Json::objectValue && instance[MAIN_DICOM_TAGS].type() == Json::objectValue && @@ -308,13 +339,50 @@ studyInstanceUid = study[MAIN_DICOM_TAGS][STUDY_INSTANCE_UID].asString(); seriesInstanceUid = series[MAIN_DICOM_TAGS][SERIES_INSTANCE_UID].asString(); sopInstanceUid = instance[MAIN_DICOM_TAGS][SOP_INSTANCE_UID].asString(); - return true; + found = true; + +#if 0 + // This is a FAST version, that does not access the filesystem. It + // only uses the main DICOM tags as stored in the database, so + // less common tags will be missing. This is important if the + // DICOM/JSON files are stored on low-speed filesystem (e.g. AWS + // S3). TODO - Add a configuration option in the plugin + const std::string bulkRoot = (wadoBase + + "studies/" + studyInstanceUid + + "/series/" + seriesInstanceUid + + "/instances/" + sopInstanceUid + "/bulk"); + + Json::Value combined = Json::objectValue; + CopyDictionary(combined, patient[MAIN_DICOM_TAGS]); + CopyDictionary(combined, study[MAIN_DICOM_TAGS]); + CopyDictionary(combined, series[MAIN_DICOM_TAGS]); + CopyDictionary(combined, instance[MAIN_DICOM_TAGS]); + + OrthancPlugins::MemoryBuffer dicom; + dicom.CreateDicom(combined, OrthancPluginCreateDicomFlags_None); + writer.AddDicom(dicom.GetData(), dicom.GetSize(), bulkRoot); + return; +#endif } else { - return false; + found = false; } #endif + + if (found) + { + const std::string bulkRoot = (wadoBase + + "studies/" + studyInstanceUid + + "/series/" + seriesInstanceUid + + "/instances/" + sopInstanceUid + "/bulk"); + + OrthancPlugins::MemoryBuffer dicom; + if (dicom.RestApiGet("/instances/" + orthancId + "/file", false)) + { + writer.AddDicom(dicom.GetData(), dicom.GetSize(), bulkRoot); + } + } } @@ -356,20 +424,7 @@ for (std::list<std::string>::const_iterator it = instances.begin(); it != instances.end(); ++it) { - std::string studyInstanceUid, seriesInstanceUid, sopInstanceUid; - if (GetDicomIdentifiers(studyInstanceUid, seriesInstanceUid, sopInstanceUid, *it)) - { - const std::string bulkRoot = (wadoBase + - "studies/" + studyInstanceUid + - "/series/" + seriesInstanceUid + - "/instances/" + sopInstanceUid + "/bulk"); - - OrthancPlugins::MemoryBuffer dicom; - if (dicom.RestApiGet("/instances/" + *it + "/file", false)) - { - writer.AddDicom(dicom.GetData(), dicom.GetSize(), bulkRoot); - } - } + WriteInstanceMetadata(writer, *it, wadoBase); } writer.Send();