changeset 5696:0f8b6214308a find-refactoring

preparing to use ResourceFinder in OrthancFindRequestHandler
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 12 Jul 2024 10:56:33 +0200
parents 380a71e0d7e7
children f375e9983943
files OrthancServer/Sources/OrthancFindRequestHandler.cpp OrthancServer/Sources/ResourceFinder.cpp OrthancServer/Sources/ResourceFinder.h
diffstat 3 files changed, 123 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp	Fri Jul 12 10:16:20 2024 +0200
+++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp	Fri Jul 12 10:56:33 2024 +0200
@@ -30,6 +30,7 @@
 #include "../../OrthancFramework/Sources/Lua/LuaFunctionCall.h"
 #include "../../OrthancFramework/Sources/MetricsRegistry.h"
 #include "OrthancConfiguration.h"
+#include "ResourceFinder.cpp"
 #include "Search/DatabaseLookup.h"
 #include "ServerContext.h"
 #include "ServerToolbox.h"
@@ -319,6 +320,92 @@
   };
 
 
+  namespace
+  {
+    class LookupVisitorV2 : public ResourceFinder::IVisitor
+    {
+    private:
+      DicomFindAnswers&           answers_;
+      ServerContext&              context_;
+      ResourceType                level_;
+      const DicomMap&             query_;
+      DicomArray                  queryAsArray_;
+      const std::list<DicomTag>&  sequencesToReturn_;
+      std::string                 defaultPrivateCreator_;       // the private creator to use if the group is not defined in the query itself
+      const std::map<uint16_t, std::string>& privateCreators_;  // the private creators defined in the query itself
+      std::string                 retrieveAet_;
+      FindStorageAccessMode       findStorageAccessMode_;
+
+    public:
+      LookupVisitorV2(DicomFindAnswers&  answers,
+                      ServerContext& context,
+                      ResourceType level,
+                      const DicomMap& query,
+                      const std::list<DicomTag>& sequencesToReturn,
+                      const std::map<uint16_t, std::string>& privateCreators,
+                      FindStorageAccessMode findStorageAccessMode) :
+        answers_(answers),
+        context_(context),
+        level_(level),
+        query_(query),
+        queryAsArray_(query),
+        sequencesToReturn_(sequencesToReturn),
+        privateCreators_(privateCreators),
+        findStorageAccessMode_(findStorageAccessMode)
+      {
+        answers_.SetComplete(false);
+
+        {
+          OrthancConfiguration::ReaderLock lock;
+          defaultPrivateCreator_ = lock.GetConfiguration().GetDefaultPrivateCreator();
+          retrieveAet_ = lock.GetConfiguration().GetOrthancAET();
+        }
+      }
+
+      virtual void Apply(const FindResponse::Resource& resource,
+                         const DicomMap& requestedTags) ORTHANC_OVERRIDE
+      {
+        DicomMap answer;
+        resource.GetAllMainDicomTags(answer);
+        answer.Merge(requestedTags);
+
+        /**
+         * Add the mandatory "Retrieve AE Title (0008,0054)" tag, which was missing in Orthanc <= 1.7.2.
+         * http://dicom.nema.org/medical/dicom/current/output/html/part04.html#sect_C.4.1.1.3.2
+         * https://groups.google.com/g/orthanc-users/c/-7zNTKR_PMU/m/kfjwzEVNAgAJ
+         **/
+        answer.SetValue(DICOM_TAG_RETRIEVE_AE_TITLE, retrieveAet_, false /* not binary */);
+
+        for (size_t i = 0; i < queryAsArray_.GetSize(); i++)
+        {
+          const DicomTag tag = queryAsArray_.GetElement(i).GetTag();
+
+          if (tag == DICOM_TAG_QUERY_RETRIEVE_LEVEL)
+          {
+            // Fix issue 30 on Google Code (QR response missing "Query/Retrieve Level" (008,0052))
+            answer.SetValue(tag, queryAsArray_.GetElement(i).GetValue());
+          }
+          else if (tag == DICOM_TAG_SPECIFIC_CHARACTER_SET)
+          {
+            // Do not include the encoding, this is handled by class ParsedDicomFile
+          }
+          else if (!answer.HasTag(tag))
+          {
+            answer.SetValue(tag, "", false);
+          }
+        }
+
+        answers_.Add(answer);
+      }
+
+      virtual void MarkAsComplete() ORTHANC_OVERRIDE
+      {
+        answers_.SetComplete(true);
+      }
+    };
+  }
+
+
   void OrthancFindRequestHandler::Handle(DicomFindAnswers& answers,
                                          const DicomMap& input,
                                          const std::list<DicomTag>& sequencesToReturn,
@@ -410,9 +497,12 @@
       }
     }
 
+    std::set<DicomTag> requestedTags;
+
     for (std::list<DicomTag>::const_iterator it = sequencesToReturn.begin();
          it != sequencesToReturn.end(); ++it)
     {
+      requestedTags.insert(*it);
       CLOG(INFO, DICOM) << "  (" << it->Format()
                         << ")  " << FromDcmtkBridge::GetTagName(*it, "")
                         << " : sequence tag whose content will be copied";
@@ -453,6 +543,7 @@
       if (value.size() == 0)
       {
         // An empty string corresponds to an universal constraint, so we ignore it
+        requestedTags.insert(tag);
         continue;
       }
 
@@ -472,6 +563,7 @@
       }
       else
       {
+        requestedTags.insert(tag);
         CLOG(INFO, DICOM) << "Because of a patch for the manufacturer of the remote modality, " 
                           << "ignoring constraint on tag (" << tag.Format() << ") "
                           << FromDcmtkBridge::GetTagName(element);
@@ -486,8 +578,28 @@
     size_t limit = (level == ResourceType_Instance) ? maxInstances_ : maxResults_;
 
 
-    LookupVisitor visitor(answers, context_, level, *filteredInput, sequencesToReturn, privateCreators, context_.GetFindStorageAccessMode());
-    context_.Apply(visitor, lookup, level, 0 /* "since" is not relevant to C-FIND */, limit);
+    if (false)
+    {
+      /**
+       * EXPERIMENTAL VERSION
+       **/
+
+      ResourceFinder finder(level, false /* don't expand */);
+      finder.SetDatabaseLookup(lookup);
+      finder.AddRequestedTags(requestedTags);
+
+      LookupVisitorV2 visitor(answers, context_, level, *filteredInput, sequencesToReturn, privateCreators, context_.GetFindStorageAccessMode());
+      finder.Execute(visitor, context_);
+    }
+    else
+    {
+      /**
+       * VERSION IN ORTHANC <= 1.12.4
+       **/
+
+      LookupVisitor visitor(answers, context_, level, *filteredInput, sequencesToReturn, privateCreators, context_.GetFindStorageAccessMode());
+      context_.Apply(visitor, lookup, level, 0 /* "since" is not relevant to C-FIND */, limit);
+    }
   }
 
 
--- a/OrthancServer/Sources/ResourceFinder.cpp	Fri Jul 12 10:16:20 2024 +0200
+++ b/OrthancServer/Sources/ResourceFinder.cpp	Fri Jul 12 10:56:33 2024 +0200
@@ -949,7 +949,7 @@
       {
         if (pagingMode_ == PagingMode_FullDatabase)
         {
-          visitor.Apply(resource, hasRequestedTags_, requestedTags);
+          visitor.Apply(resource, requestedTags);
         }
         else
         {
@@ -967,7 +967,7 @@
           }
           else
           {
-            visitor.Apply(resource, hasRequestedTags_, requestedTags);
+            visitor.Apply(resource, requestedTags);
             countResults++;
           }
         }
@@ -990,19 +990,21 @@
       const ResourceFinder&  that_;
       ServerIndex& index_;
       Json::Value& target_;
+      bool         hasRequestedTags_;
 
     public:
       Visitor(const ResourceFinder& that,
               ServerIndex& index,
-              Json::Value& target) :
+              Json::Value& target,
+              bool hasRequestedTags) :
         that_(that),
         index_(index),
-        target_(target)
+        target_(target),
+        hasRequestedTags_(hasRequestedTags)
       {
       }
 
       virtual void Apply(const FindResponse::Resource& resource,
-                         bool hasRequestedTags,
                          const DicomMap& requestedTags) ORTHANC_OVERRIDE
       {
         if (that_.expand_)
@@ -1010,7 +1012,7 @@
           Json::Value item;
           that_.Expand(item, resource, index_);
 
-          if (hasRequestedTags)
+          if (hasRequestedTags_)
           {
             static const char* const REQUESTED_TAGS = "RequestedTags";
             item[REQUESTED_TAGS] = Json::objectValue;
@@ -1032,7 +1034,7 @@
 
     target = Json::arrayValue;
 
-    Visitor visitor(*this, context.GetIndex(), target);
+    Visitor visitor(*this, context.GetIndex(), target, hasRequestedTags_);
     Execute(visitor, context);
   }
 
--- a/OrthancServer/Sources/ResourceFinder.h	Fri Jul 12 10:16:20 2024 +0200
+++ b/OrthancServer/Sources/ResourceFinder.h	Fri Jul 12 10:56:33 2024 +0200
@@ -43,7 +43,6 @@
       }
 
       virtual void Apply(const FindResponse::Resource& resource,
-                         bool hasRequestedTags,
                          const DicomMap& requestedTags) = 0;
 
       virtual void MarkAsComplete() = 0;