changeset 360:c9cc22e56952

trying to cache DICOMweb metadata
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 11 Sep 2019 15:08:13 +0200
parents 105598b74e1a
children 1dc8e5753d3f
files Plugin/DicomWebFormatter.cpp Plugin/DicomWebFormatter.h Plugin/QidoRs.cpp Plugin/WadoRs.cpp
diffstat 4 files changed, 94 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/Plugin/DicomWebFormatter.cpp	Fri Aug 30 18:49:50 2019 +0200
+++ b/Plugin/DicomWebFormatter.cpp	Wed Sep 11 15:08:13 2019 +0200
@@ -23,6 +23,10 @@
 
 #include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>
 
+#if !defined(NDEBUG)
+#  include <json/reader.h>
+#endif
+
 
 namespace OrthancPlugins
 {
@@ -179,7 +183,7 @@
   }
 
                   
-  void DicomWebFormatter::HttpWriter::AddJson(const Json::Value& value)
+  void DicomWebFormatter::HttpWriter::AddOrthancJson(const Json::Value& value)
   {
     MemoryBuffer dicom;
     dicom.CreateDicom(value, OrthancPluginCreateDicomFlags_None);
@@ -188,6 +192,38 @@
   }
 
 
+  void DicomWebFormatter::HttpWriter::AddDicomWebSerializedJson(const void* data,
+                                                                size_t size)
+  {
+    if (isXml_)
+    {
+      // This function can only be used in the JSON case
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+    }
+
+#if !defined(NDEBUG)  // In debug mode, check that the value is actually a JSON string
+    Json::Reader reader;
+    Json::Value json;
+    if (!reader.parse(reinterpret_cast<const char*>(data),
+                      reinterpret_cast<const char*>(data) + size, json))
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+    }
+#endif
+    
+    if (first_)
+    {
+      first_ = false;
+    }
+    else
+    {
+      jsonBuffer_.AddChunk(",");
+    }
+    
+    jsonBuffer_.AddChunk(data, size);
+  }
+
+
   void DicomWebFormatter::HttpWriter::Send()
   {
     if (!isXml_)
--- a/Plugin/DicomWebFormatter.h	Fri Aug 30 18:49:50 2019 +0200
+++ b/Plugin/DicomWebFormatter.h	Wed Sep 11 15:08:13 2019 +0200
@@ -97,6 +97,11 @@
       HttpWriter(OrthancPluginRestOutput* output,
                  bool isXml);
 
+      bool IsXml() const
+      {
+        return isXml_;
+      }
+
       void AddDicom(const void* dicom,
                     size_t size,
                     const std::string& bulkRoot)
@@ -104,7 +109,10 @@
         AddInternal(dicom, size, OrthancPluginDicomWebBinaryMode_BulkDataUri, bulkRoot);
       }
 
-      void AddJson(const Json::Value& value);
+      void AddOrthancJson(const Json::Value& value);
+
+      void AddDicomWebSerializedJson(const void* data,
+                                     size_t size);
 
       void Send();
     };
--- a/Plugin/QidoRs.cpp	Fri Aug 30 18:49:50 2019 +0200
+++ b/Plugin/QidoRs.cpp	Wed Sep 11 15:08:13 2019 +0200
@@ -522,7 +522,7 @@
         result[tag->first.Format()] = tag->second;
       }
 
-      writer.AddJson(result);
+      writer.AddOrthancJson(result);
     }
   }
 
--- a/Plugin/WadoRs.cpp	Fri Aug 30 18:49:50 2019 +0200
+++ b/Plugin/WadoRs.cpp	Wed Sep 11 15:08:13 2019 +0200
@@ -385,12 +385,58 @@
                                   "studies/" + studyInstanceUid +
                                   "/series/" + seriesInstanceUid + 
                                   "/instances/" + sopInstanceUid + "/bulk");
-      
+
+#if 1
+    // On a SSD drive, this version is twice slower than if using
+    // cache (see below)
+    
     OrthancPlugins::MemoryBuffer dicom;
     if (dicom.RestApiGet("/instances/" + orthancId + "/file", false))
     {
       writer.AddDicom(dicom.GetData(), dicom.GetSize(), bulkRoot);
     }
+#else
+
+    // TODO - Have a global setting to enable/disable caching of DICOMweb
+
+    // TODO - Have a way to clear the "4444" attachments if Orthanc
+    // version changes => Store Orthanc core version in a prefix or in
+    // another attachments?
+    
+    OrthancPlugins::MemoryBuffer buffer;
+
+    if (writer.IsXml())
+    {
+      // DICOMweb XML is not cached
+      if (buffer.RestApiGet("/instances/" + orthancId + "/file", false))
+      {
+        writer.AddDicom(buffer.GetData(), buffer.GetSize(), bulkRoot);
+      }
+    }
+    else
+    {
+      if (buffer.RestApiGet("/instances/" + orthancId + "/attachments/4444/data", false))
+      {
+        writer.AddDicomWebSerializedJson(buffer.GetData(), buffer.GetSize());
+      }
+      else if (buffer.RestApiGet("/instances/" + orthancId + "/file", false))
+      {
+        // "Ignore binary mode" in DICOMweb conversion if caching is
+        // enabled, as the bulk root can change across executions
+
+        std::string dicomweb;
+        {
+          // TODO - Avoid a global mutex => Need to change Orthanc SDK
+          OrthancPlugins::DicomWebFormatter::Locker locker(OrthancPluginDicomWebBinaryMode_Ignore, "");
+          locker.Apply(dicomweb, OrthancPlugins::GetGlobalContext(),
+                       buffer.GetData(), buffer.GetSize(), false /* JSON */);
+        }
+
+        buffer.RestApiPut("/instances/" + orthancId + "/attachments/4444", dicomweb, false);
+        writer.AddDicomWebSerializedJson(dicomweb.c_str(), dicomweb.size());
+      }
+    }
+#endif
   }
 }