# HG changeset patch # User Alain Mazy # Date 1730753484 -3600 # Node ID d1dea8ad74a67b5ce155cfd9feec5691a05f27e3 # Parent aeb9f63923b162f66a22db71eef5b8760f68a987 implement StorageAccessOnFind for answers diff -r aeb9f63923b1 -r d1dea8ad74a6 NEWS --- a/NEWS Mon Nov 04 20:00:42 2024 +0100 +++ b/NEWS Mon Nov 04 21:51:24 2024 +0100 @@ -74,6 +74,7 @@ - W004_NoMainDicomTagsSignature - W005_RequestingTagFromLowerResourceLevel - W006_RequestingTagFromMetaHeader + - W007_MissingRequestedTagsNotReadFromDisk * New default MainDicomTags are now stored in DB. Note that, in order to store these values for resources that were ingested in Orthanc before this release, you would have to run the Housekeeper plugin or call /reconstruct on every resources diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Resources/Configuration.json --- a/OrthancServer/Resources/Configuration.json Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Resources/Configuration.json Mon Nov 04 21:51:24 2024 +0100 @@ -1009,7 +1009,12 @@ // Display a warning when a user performs a find request and requests a tag // from the DICOM Meta Header. // (new in Orthanc 1.12.5) - "W006_RequestingTagFromMetaHeader": true + "W006_RequestingTagFromMetaHeader": true, + + // Display a warning when a user requests a tag that can not be read from disk + // because "StorageAccessOnFind" is set to "Never". + // (new in Orthanc 1.12.5) + "W007_MissingRequestedTagsNotReadFromDisk": true }, // Configure Orthanc in read only mode. diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/OrthancConfiguration.cpp --- a/OrthancServer/Sources/OrthancConfiguration.cpp Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/OrthancConfiguration.cpp Mon Nov 04 21:51:24 2024 +0100 @@ -1173,6 +1173,10 @@ { warning = Warnings_006_RequestingTagFromMetaHeader; } + else if (name == "W007_MissingRequestedTagsNotReadFromDisk") + { + warning = Warnings_007_MissingRequestedTagsNotReadFromDisk; + } else { throw OrthancException(ErrorCode_BadFileFormat, name + " is not recognized as a valid warning name"); diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/OrthancFindRequestHandler.cpp --- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp Mon Nov 04 21:51:24 2024 +0100 @@ -444,7 +444,7 @@ * Run the query. **/ - ResourceFinder finder(level, ResponseContentFlags_ID); + ResourceFinder finder(level, ResponseContentFlags_ID, context_.GetFindStorageAccessMode()); finder.SetDatabaseLookup(lookup); finder.AddRequestedTags(requestedTags); diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Mon Nov 04 21:51:24 2024 +0100 @@ -152,7 +152,7 @@ responseContent = static_cast(static_cast(responseContent) | ResponseContentFlags_Metadata); } - ResourceFinder finder(level, responseContent); + ResourceFinder finder(level, responseContent, context.GetFindStorageAccessMode()); finder.SetOrthancId(level, identifier); finder.SetRetrieveMetadata(retrieveMetadata); @@ -193,7 +193,7 @@ std::set requestedTags; OrthancRestApi::GetRequestedTags(requestedTags, call); - ResourceFinder finder(resourceType, (expand ? ResponseContentFlags_ExpandTrue : ResponseContentFlags_ID)); + ResourceFinder finder(resourceType, (expand ? ResponseContentFlags_ExpandTrue : ResponseContentFlags_ID), OrthancRestApi::GetContext(call).GetFindStorageAccessMode()); finder.AddRequestedTags(requestedTags); if (call.HasArgument("limit") || @@ -251,7 +251,7 @@ const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); - ResourceFinder finder(resourceType, ResponseContentFlags_ExpandTrue); + ResourceFinder finder(resourceType, ResponseContentFlags_ExpandTrue, OrthancRestApi::GetContext(call).GetFindStorageAccessMode()); finder.AddRequestedTags(requestedTags); finder.SetOrthancId(resourceType, call.GetUriComponent("id", "")); @@ -3250,7 +3250,7 @@ const ResourceType level = StringToResourceType(request[KEY_LEVEL].asCString()); - ResourceFinder finder(level, responseContent); + ResourceFinder finder(level, responseContent, context.GetFindStorageAccessMode()); DatabaseLookup dicomTagLookup; @@ -3542,7 +3542,7 @@ std::set requestedTags; OrthancRestApi::GetRequestedTags(requestedTags, call); - ResourceFinder finder(end, (expand ? ResponseContentFlags_ExpandTrue : ResponseContentFlags_ID)); + ResourceFinder finder(end, (expand ? ResponseContentFlags_ExpandTrue : ResponseContentFlags_ID), OrthancRestApi::GetContext(call).GetFindStorageAccessMode()); finder.SetOrthancId(start, call.GetUriComponent("id", "")); finder.AddRequestedTags(requestedTags); diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/OrthancWebDav.cpp --- a/OrthancServer/Sources/OrthancWebDav.cpp Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/OrthancWebDav.cpp Mon Nov 04 21:51:24 2024 +0100 @@ -937,7 +937,7 @@ Visitor visitor(resources); - ResourceFinder finder(ResourceType_Study, ResponseContentFlags_ID); + ResourceFinder finder(ResourceType_Study, ResponseContentFlags_ID, GetContext().GetFindStorageAccessMode()); finder.SetDatabaseLookup(query); finder.Execute(visitor, GetContext()); } @@ -1015,7 +1015,7 @@ Visitor visitor; - ResourceFinder finder(ResourceType_Study, ResponseContentFlags_ID); + ResourceFinder finder(ResourceType_Study, ResponseContentFlags_ID, context_.GetFindStorageAccessMode()); finder.SetDatabaseLookup(query); finder.Execute(visitor, context_); @@ -1393,7 +1393,7 @@ return false; } - ResourceFinder finder(level, ResponseContentFlags_ID); + ResourceFinder finder(level, ResponseContentFlags_ID, context_.GetFindStorageAccessMode()); finder.SetDatabaseLookup(query); finder.SetRetrieveMetadata(true); @@ -1444,7 +1444,7 @@ ResourceType level, const DatabaseLookup& query) { - ResourceFinder finder(level, ResponseContentFlags_ExpandTrue); + ResourceFinder finder(level, ResponseContentFlags_ExpandTrue, context.GetFindStorageAccessMode()); finder.SetDatabaseLookup(query); Json::Value expanded; @@ -1514,7 +1514,7 @@ mime = MimeType_Dicom; - ResourceFinder finder(ResourceType_Instance, ResponseContentFlags_ID); + ResourceFinder finder(ResourceType_Instance, ResponseContentFlags_ID, context_.GetFindStorageAccessMode()); finder.SetDatabaseLookup(query); finder.SetRetrieveMetadata(true); finder.SetRetrieveAttachments(true); @@ -1644,7 +1644,7 @@ DicomDeleteVisitor visitor(context_, level); - ResourceFinder finder(level, ResponseContentFlags_ID); + ResourceFinder finder(level, ResponseContentFlags_ID, context_.GetFindStorageAccessMode()); finder.SetDatabaseLookup(query); finder.Execute(visitor, context_); return true; diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/ResourceFinder.cpp --- a/OrthancServer/Sources/ResourceFinder.cpp Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/ResourceFinder.cpp Mon Nov 04 21:51:24 2024 +0100 @@ -544,7 +544,8 @@ ResourceFinder::ResourceFinder(ResourceType level, - ResponseContentFlags responseContent) : + ResponseContentFlags responseContent, + FindStorageAccessMode storageAccessMode) : request_(level), databaseLimits_(0), isSimpleLookup_(true), @@ -554,7 +555,7 @@ limitsSince_(0), limitsCount_(0), responseContent_(responseContent), - allowStorageAccess_(true), + storageAccessMode_(storageAccessMode), isWarning002Enabled_(false), isWarning004Enabled_(false), isWarning005Enabled_(false) @@ -1023,12 +1024,14 @@ bool isWarning002Enabled = false; bool isWarning004Enabled = false; bool isWarning006Enabled = false; + bool isWarning007Enabled = false; { OrthancConfiguration::ReaderLock lock; isWarning002Enabled = lock.GetConfiguration().IsWarningEnabled(Warnings_002_InconsistentDicomTagsInDb); isWarning004Enabled = lock.GetConfiguration().IsWarningEnabled(Warnings_004_NoMainDicomTagsSignature); isWarning006Enabled = lock.GetConfiguration().IsWarningEnabled(Warnings_006_RequestingTagFromMetaHeader); + isWarning007Enabled = lock.GetConfiguration().IsWarningEnabled(Warnings_007_MissingRequestedTagsNotReadFromDisk); } FindResponse response; @@ -1111,15 +1114,16 @@ if (!remainingRequestedTags.empty() && !DicomMap::HasOnlyComputedTags(remainingRequestedTags)) // if the only remaining tags are computed tags, it is worthless to read them from disk { - if (!allowStorageAccess_) - { - throw OrthancException(ErrorCode_BadSequenceOfCalls, - "Cannot add missing requested tags, as access to file storage is disallowed"); - } - else + if (IsStorageAccessAllowedOnAnswers()) { ReadMissingTagsFromStorageArea(outRequestedTags, context, request_, resource, remainingRequestedTags); } + else if (isWarning007Enabled) + { + std::string joinedTags; + FromDcmtkBridge::FormatListOfTags(joinedTags, remainingRequestedTags); + LOG(WARNING) << "W007: Unable to include requested tags since 'StorageAccessOnFind' does not allow accessing the storage to build answers: " << joinedTags; + } } std::string mainDicomTagsSignature; @@ -1191,6 +1195,34 @@ } } + bool ResourceFinder::IsStorageAccessAllowedOnAnswers() + { + switch (storageAccessMode_) + { + case FindStorageAccessMode_DiskOnAnswer: + case FindStorageAccessMode_DiskOnLookupAndAnswer: + return true; + case FindStorageAccessMode_DatabaseOnly: + return false; + default: + throw OrthancException(ErrorCode_InternalError); + } + } + + + bool ResourceFinder::IsStorageAccessOnLookup() + { + switch (storageAccessMode_) + { + case FindStorageAccessMode_DiskOnAnswer: + return false; + case FindStorageAccessMode_DiskOnLookupAndAnswer: + case FindStorageAccessMode_DatabaseOnly: + return true; + default: + throw OrthancException(ErrorCode_InternalError); + } + } void ResourceFinder::Execute(Json::Value& target, ServerContext& context, diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/ResourceFinder.h --- a/OrthancServer/Sources/ResourceFinder.h Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/ResourceFinder.h Mon Nov 04 21:51:24 2024 +0100 @@ -66,7 +66,7 @@ uint64_t limitsSince_; uint64_t limitsCount_; ResponseContentFlags responseContent_; - bool allowStorageAccess_; + FindStorageAccessMode storageAccessMode_; std::set requestedTags_; std::set requestedComputedTags_; @@ -101,22 +101,17 @@ return requestedTags_.size() > 0; } + bool IsStorageAccessAllowedOnAnswers(); + + bool IsStorageAccessOnLookup(); + public: ResourceFinder(ResourceType level, - ResponseContentFlags responseContent); + ResponseContentFlags responseContent, + FindStorageAccessMode storageAccessMode); void SetDatabaseLimits(uint64_t limits); - bool IsAllowStorageAccess() const - { - return allowStorageAccess_; - } - - void SetAllowStorageAccess(bool allow) - { - allowStorageAccess_ = allow; - } - void SetOrthancId(ResourceType level, const std::string& id) { diff -r aeb9f63923b1 -r d1dea8ad74a6 OrthancServer/Sources/ServerEnumerations.h --- a/OrthancServer/Sources/ServerEnumerations.h Mon Nov 04 20:00:42 2024 +0100 +++ b/OrthancServer/Sources/ServerEnumerations.h Mon Nov 04 21:51:24 2024 +0100 @@ -251,10 +251,11 @@ Warnings_None, Warnings_001_TagsBeingReadFromStorage, Warnings_002_InconsistentDicomTagsInDb, - Warnings_003_DecoderFailure, // new in Orthanc 1.12.5 - Warnings_004_NoMainDicomTagsSignature, // new in Orthanc 1.12.5 - Warnings_005_RequestingTagFromLowerResourceLevel, // new in Orthanc 1.12.5 - Warnings_006_RequestingTagFromMetaHeader // new in Orthanc 1.12.5 + Warnings_003_DecoderFailure, // new in Orthanc 1.12.5 + Warnings_004_NoMainDicomTagsSignature, // new in Orthanc 1.12.5 + Warnings_005_RequestingTagFromLowerResourceLevel, // new in Orthanc 1.12.5 + Warnings_006_RequestingTagFromMetaHeader, // new in Orthanc 1.12.5 + Warnings_007_MissingRequestedTagsNotReadFromDisk // new in Orthanc 1.12.5 };