changeset 595:f9d029c56ba4

added a route to populate the series metadata cache
author Alain Mazy <am@osimis.io>
date Tue, 22 Aug 2023 10:31:34 +0200
parents 68aa83ffa290
children e1f219c7c302
files NEWS Plugin/Configuration.cpp Plugin/Configuration.h Plugin/Plugin.cpp Plugin/WadoRs.cpp Plugin/WadoRs.h
diffstat 6 files changed, 59 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Aug 21 16:33:27 2023 +0200
+++ b/NEWS	Tue Aug 22 10:31:34 2023 +0200
@@ -2,9 +2,12 @@
 ===============================
 
 * speed improvement:
-  - Now storing the output of studies/../series/../metadata route in an attachment when in "Full" mode.
+  - Now storing the output of /dicom-web/studies/../series/../metadata route in an attachment that can be used
+    by the "Full" mode.
     The json file is gzipped and stored in attachment 4301 everytime a series is stable or the first time
-    its studies/../series/../metadata route is called if the attachment does not exist yet.
+    its /dicom-web/studies/../series/../metadata route is called in "Full" mode if the attachment does not exist yet.
+    A new route /studies/{orthancId}/update-dicomweb-cache has also been added to allow e.g. the Housekeeper plugin
+    to generate these attachment for old studies.
 
 Version 1.14 (2023-07-05)
 =========================
--- a/Plugin/Configuration.cpp	Mon Aug 21 16:33:27 2023 +0200
+++ b/Plugin/Configuration.cpp	Tue Aug 22 10:31:34 2023 +0200
@@ -680,7 +680,6 @@
     MetadataMode GetMetadataMode(Orthanc::ResourceType level)
     {
       static const std::string FULL = "Full";
-      static const std::string FULL_NO_CACHE = "FullNoCache";
       static const std::string MAIN_DICOM_TAGS = "MainDicomTags";
       static const std::string EXTRAPOLATE = "Extrapolate";
       
@@ -703,10 +702,6 @@
 
       if (value == FULL)
       {
-        return MetadataMode_FullWithCache;
-      }
-      else if (value == FULL_NO_CACHE)
-      {
         return MetadataMode_Full;
       }
       else if (value == MAIN_DICOM_TAGS)
--- a/Plugin/Configuration.h	Mon Aug 21 16:33:27 2023 +0200
+++ b/Plugin/Configuration.h	Tue Aug 22 10:31:34 2023 +0200
@@ -48,8 +48,7 @@
 
   enum MetadataMode
   {
-    MetadataMode_Full,           // Read all the DICOM instances from the storage area
-    MetadataMode_FullWithCache,  // Read all the DICOM instances from the storage area and store them in an attachment on StableSeries event
+    MetadataMode_Full,           // Read all the DICOM instances from the storage area and store them in an attachment on StableSeries event
     MetadataMode_MainDicomTags,  // Only use the Orthanc database (main DICOM tags only)
     MetadataMode_Extrapolate     // Extrapolate user-specified tags from a few DICOM instances
   };
--- a/Plugin/Plugin.cpp	Mon Aug 21 16:33:27 2023 +0200
+++ b/Plugin/Plugin.cpp	Tue Aug 22 10:31:34 2023 +0200
@@ -603,6 +603,8 @@
         OrthancPlugins::RegisterRestCallback<RetrieveInstanceRendered>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/rendered", true);
         OrthancPlugins::RegisterRestCallback<RetrieveFrameRendered>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/frames/([^/]*)/rendered", true);
 
+        OrthancPlugins::RegisterRestCallback<UpdateSeriesMetadataCache>("/studies/([^/]*)/update-dicomweb-cache", true);
+
         OrthancPluginRegisterOnChangeCallback(context, OnChangeCallback);
 
 
--- a/Plugin/WadoRs.cpp	Mon Aug 21 16:33:27 2023 +0200
+++ b/Plugin/WadoRs.cpp	Tue Aug 22 10:31:34 2023 +0200
@@ -817,7 +817,6 @@
     }
 
     case OrthancPlugins::MetadataMode_Full:
-    case OrthancPlugins::MetadataMode_FullWithCache:
     {
       const std::string bulkRoot = (wadoBase +
                                     "studies/" + studyInstanceUid +
@@ -1401,33 +1400,61 @@
 
 void CacheSeriesMetadata(const std::string& seriesOrthancId)
 {
-  const OrthancPlugins::MetadataMode mode =
-    OrthancPlugins::Configuration::GetMetadataMode(Orthanc::ResourceType_Series);
+  LOG(INFO) << "DicomWEB: pre-computing the WADO-RS series metadata for series " << seriesOrthancId;
 
-  if (mode == OrthancPlugins::MetadataMode_FullWithCache)
+  std::string studyInstanceUid, seriesInstanceUid;
+  
+  Json::Value result;
+  if (OrthancPlugins::RestApiGet(result, "/series/" + seriesOrthancId, false))
   {
-    LOG(INFO) << "DicomWEB: pre-computing the WADO-RS series metadata";
-
-    std::string studyInstanceUid, seriesInstanceUid;
-    
-    Json::Value result;
-    if (OrthancPlugins::RestApiGet(result, "/series/" + seriesOrthancId, false))
+    seriesInstanceUid = result[MAIN_DICOM_TAGS]["SeriesInstanceUID"].asString();
+    if (OrthancPlugins::RestApiGet(result, "/studies/" + result["ParentStudy"].asString(), false))
     {
-      seriesInstanceUid = result[MAIN_DICOM_TAGS]["SeriesInstanceUID"].asString();
-      if (OrthancPlugins::RestApiGet(result, "/studies/" + result["ParentStudy"].asString(), false))
-      {
-        studyInstanceUid = result[MAIN_DICOM_TAGS]["StudyInstanceUID"].asString();
+      studyInstanceUid = result[MAIN_DICOM_TAGS]["StudyInstanceUID"].asString();
 
-        MainDicomTagsCache cache;
-        OrthancPlugins::DicomWebFormatter::HttpWriter writer(NULL /* output */, false /* isXml */);  // we cache only the JSON format -> no need for an HttpOutput
+      MainDicomTagsCache cache;
+      OrthancPlugins::DicomWebFormatter::HttpWriter writer(NULL /* output */, false /* isXml */);  // we cache only the JSON format -> no need for an HttpOutput
 
-        std::string serializedSeriesMetadataNotUsed;
-        CacheSeriesMetadataInternal(serializedSeriesMetadataNotUsed, writer, cache, studyInstanceUid, seriesInstanceUid, seriesOrthancId);
-      }
+      std::string serializedSeriesMetadataNotUsed;
+      CacheSeriesMetadataInternal(serializedSeriesMetadataNotUsed, writer, cache, studyInstanceUid, seriesInstanceUid, seriesOrthancId);
     }
   }
 }
 
+void UpdateSeriesMetadataCache(OrthancPluginRestOutput* output,
+                               const char* /*url*/,
+                               const OrthancPluginHttpRequest* request)
+{
+  if (request->method != OrthancPluginHttpMethod_Post)
+  {
+    OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "POST");
+    return;
+  }
+
+  if (request->groupsCount != 1)
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest);
+  }
+
+  std::string studyId(request->groups[0]);
+
+  LOG(INFO) << "DicomWEB: updating the series metadata cache for study " << studyId;
+
+  Json::Value study;
+
+  if (OrthancPlugins::RestApiGet(study, "/studies/" + studyId, false) && study.type() == Json::objectValue)
+  {
+    for (Json::ArrayIndex i = 0; i < study["Series"].size(); ++i)
+    {
+      CacheSeriesMetadata(study["Series"][i].asString());
+    }
+  }
+
+  std::string answer = "{}"; 
+  OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, answer.c_str(), answer.size(), "application/json");
+}
+
+
 
 void RetrieveSeriesMetadataInternalWithCache(OrthancPlugins::DicomWebFormatter::HttpWriter& writer,
                                              MainDicomTagsCache& cache,
@@ -1438,7 +1465,7 @@
                                              const std::string& seriesInstanceUid,
                                              const std::string& wadoBase)
 {
-  if (mode == OrthancPlugins::MetadataMode_FullWithCache && !isXml)
+  if (mode == OrthancPlugins::MetadataMode_Full && !isXml)
   {
     // check if we already have computed the series metadata and saved them in an attachment
     std::string serializedSeriesMetadata;
--- a/Plugin/WadoRs.h	Mon Aug 21 16:33:27 2023 +0200
+++ b/Plugin/WadoRs.h	Tue Aug 22 10:31:34 2023 +0200
@@ -63,6 +63,10 @@
                             const char* url,
                             const OrthancPluginHttpRequest* request);
 
+void UpdateSeriesMetadataCache(OrthancPluginRestOutput* output,
+                               const char* url,
+                               const OrthancPluginHttpRequest* request);
+
 void CacheSeriesMetadata(const std::string& seriesOrthancId);
 
 void RetrieveInstanceMetadata(OrthancPluginRestOutput* output,