changeset 674:882743589c73 find-refactoring

ReadOnly mode
author Alain Mazy <am@orthanc.team>
date Fri, 27 Sep 2024 17:29:33 +0200 (8 months ago)
parents d3af76826278
children bef0d7030f2d
files NEWS Plugin/Configuration.cpp Plugin/Configuration.h Plugin/Plugin.cpp Plugin/WadoRs.cpp Plugin/WadoRs.h
diffstat 6 files changed, 86 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Sep 16 11:20:07 2024 +0200
+++ b/NEWS	Fri Sep 27 17:29:33 2024 +0200
@@ -6,6 +6,7 @@
   the retrieval of NumberOfStudyRelatedInstances, NumberOfStudyRelatedSeries, ...
 * Fixed non latin PatientName values that were empty in some QIDO-RS responses.
 * Optimization when running with an Orthanc that supports the ExtendedFind.
+* Added support for Orthanc running in "ReadOnly" mode.
 
 
 Version 1.17 (2024-06-05)
--- a/Plugin/Configuration.cpp	Mon Sep 16 11:20:07 2024 +0200
+++ b/Plugin/Configuration.cpp	Fri Sep 27 17:29:33 2024 +0200
@@ -682,6 +682,10 @@
       return GetBooleanValue("EnableMetadataCache", true);
     }
 
+    bool IsReadOnly()
+    {
+      return globalConfiguration_->GetBooleanValue("ReadOnly", false);
+    }
     
     MetadataMode GetMetadataMode(Orthanc::ResourceType level)
     {
--- a/Plugin/Configuration.h	Mon Sep 16 11:20:07 2024 +0200
+++ b/Plugin/Configuration.h	Fri Sep 27 17:29:33 2024 +0200
@@ -142,5 +142,7 @@
     unsigned int GetMetadataWorkerThreadsCount();
 
     bool IsMetadataCacheEnabled();
+
+    bool IsReadOnly();
   }
 }
--- a/Plugin/Plugin.cpp	Mon Sep 16 11:20:07 2024 +0200
+++ b/Plugin/Plugin.cpp	Fri Sep 27 17:29:33 2024 +0200
@@ -44,6 +44,8 @@
 static const char* const HAS_DELETE = "HasDelete";
 static const char* const SYSTEM_CAPABILITIES = "Capabilities";
 static const char* const SYSTEM_CAPABILITIES_HAS_EXTENDED_FIND = "HasExtendedFind";
+static const char* const READ_ONLY = "ReadOnly";
+bool isReadOnly_ = false;
 
 
 bool RequestHasKey(const OrthancPluginHttpRequest* request, const char* key)
@@ -483,19 +485,30 @@
                                       && system[SYSTEM_CAPABILITIES][SYSTEM_CAPABILITIES_HAS_EXTENDED_FIND].asBool();
           if (hasExtendedFind)
           {
-            LOG(WARNING) << "Orthanc supports ExtendedFind.";
+            LOG(INFO) << "Orthanc supports ExtendedFind.";
             SetPluginCanUseExtendedFile(true);
           }
           else
           {
-            LOG(WARNING) << "Orthanc does not support ExtendedFind.";
+            LOG(WARNING) << "Orthanc does not support ExtendedFind.  The DICOMWeb plugin will not benefit from some optimizations.";
+          }
+
+          bool isReadOnly = system.isMember(READ_ONLY) && system[READ_ONLY].asBool();
+
+          if (isReadOnly)
+          {
+            LOG(INFO) << "Orthanc is ReadOnly.";
+            SetSystemIsReadOnly(true);
           }
         }
 
       }; break;
 
       case OrthancPluginChangeType_StableSeries:
-        CacheSeriesMetadata(resourceId);
+        if (!OrthancPlugins::Configuration::IsReadOnly())
+        {
+          CacheSeriesMetadata(resourceId);
+        }
         break;
 
       default:
@@ -588,13 +601,27 @@
 
         LOG(WARNING) << "URI to the DICOMweb REST API: " << root;
 
-        OrthancPlugins::ChunkedRestRegistration<
-          SearchForStudies /* TODO => Rename as QIDO-RS */,
-          OrthancPlugins::StowServer::PostCallback>::Apply(root + "studies");
+
+        if (!OrthancPlugins::Configuration::IsReadOnly())
+        {
+          OrthancPlugins::ChunkedRestRegistration<
+            SearchForStudies /* TODO => Rename as QIDO-RS */,
+            OrthancPlugins::StowServer::PostCallback>::Apply(root + "studies");
 
-        OrthancPlugins::ChunkedRestRegistration<
-          RetrieveDicomStudy /* TODO => Rename as WADO-RS */,
-          OrthancPlugins::StowServer::PostCallback>::Apply(root + "studies/([^/]*)");
+          OrthancPlugins::ChunkedRestRegistration<
+            RetrieveDicomStudy /* TODO => Rename as WADO-RS */,
+            OrthancPlugins::StowServer::PostCallback>::Apply(root + "studies/([^/]*)");
+        }
+        else
+        {
+          LOG(WARNING) << "READ-ONLY SYSTEM: deactivating STOW-RS routes";
+          
+          OrthancPlugins::ChunkedRestRegistration<
+            SearchForStudies /* TODO => Rename as QIDO-RS */>::Apply(root + "studies");
+
+          OrthancPlugins::ChunkedRestRegistration<
+            RetrieveDicomStudy /* TODO => Rename as WADO-RS */>::Apply(root + "studies/([^/]*)");
+        }
 
         OrthancPlugins::RegisterRestCallback<SearchForInstances>(root + "instances", true);
         OrthancPlugins::RegisterRestCallback<SearchForSeries>(root + "series", true);    
@@ -612,10 +639,19 @@
 
         OrthancPlugins::RegisterRestCallback<ListServers>(root + "servers", true);
         OrthancPlugins::RegisterRestCallback<ListServerOperations>(root + "servers/([^/]*)", true);
-        OrthancPlugins::RegisterRestCallback<StowClient>(root + "servers/([^/]*)/stow", true);
+        
+        if (!OrthancPlugins::Configuration::IsReadOnly())
+        {
+          OrthancPlugins::RegisterRestCallback<RetrieveFromServer>(root + "servers/([^/]*)/retrieve", true);
+        }
+        else
+        {
+          LOG(WARNING) << "READ-ONLY SYSTEM: deactivating 'servers/../retrieve' route";
+        }
+
         OrthancPlugins::RegisterRestCallback<WadoRetrieveClient>(root + "servers/([^/]*)/wado", true);
+        OrthancPlugins::RegisterRestCallback<StowClient>(root + "servers/([^/]*)/stow", true);
         OrthancPlugins::RegisterRestCallback<GetFromServer>(root + "servers/([^/]*)/get", true);
-        OrthancPlugins::RegisterRestCallback<RetrieveFromServer>(root + "servers/([^/]*)/retrieve", true);
         OrthancPlugins::RegisterRestCallback<QidoClient>(root + "servers/([^/]*)/qido", true);
         OrthancPlugins::RegisterRestCallback<DeleteClient>(root + "servers/([^/]*)/delete", true);
 
@@ -630,7 +666,10 @@
         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);
+        if (!OrthancPlugins::Configuration::IsReadOnly())
+        {
+          OrthancPlugins::RegisterRestCallback<UpdateSeriesMetadataCache>("/studies/([^/]*)/update-dicomweb-cache", true);
+        }
 
         OrthancPluginRegisterOnChangeCallback(context, OnChangeCallback);
 
--- a/Plugin/WadoRs.cpp	Mon Sep 16 11:20:07 2024 +0200
+++ b/Plugin/WadoRs.cpp	Fri Sep 27 17:29:33 2024 +0200
@@ -51,6 +51,7 @@
 static boost::mutex mainDicomTagsListMutex;
 
 static bool pluginCanUseExtendedFind_ = false;
+static bool isSystemReadOnly_ = false;
 
 void SetPluginCanUseExtendedFile(bool enable)
 {
@@ -62,6 +63,16 @@
   return pluginCanUseExtendedFind_;
 }
 
+void SetSystemIsReadOnly(bool isReadOnly)
+{
+  isSystemReadOnly_ = isReadOnly;
+}
+
+bool IsSystemReadOnly()
+{
+  return isSystemReadOnly_;
+}
+
 static std::string GetResourceUri(Orthanc::ResourceType level,
                                   const std::string& publicId)
 {
@@ -1457,20 +1468,22 @@
   RetrieveSeriesMetadataInternal(instancesIds, writer, cache, OrthancPlugins::MetadataMode_Full, false /* isXml */, seriesOrthancId, studyInstanceUid, seriesInstanceUid, WADO_BASE_PLACEHOLDER);
   writer.CloseAndGetJsonOutput(serializedSeriesMetadata);
 
-  // save in attachments for future use
-  Orthanc::IBufferCompressor::Compress(compressedSeriesMetadata, compressor, serializedSeriesMetadata);
-  std::string instancesMd5;
-  Orthanc::Toolbox::ComputeMD5(instancesMd5, instancesIds);
-
-  std::string cacheContent = "2;" + instancesMd5 + ";" + compressedSeriesMetadata; 
+  if (!IsSystemReadOnly())
+  {
+    // save in attachments for future use
+    Orthanc::IBufferCompressor::Compress(compressedSeriesMetadata, compressor, serializedSeriesMetadata);
+    std::string instancesMd5;
+    Orthanc::Toolbox::ComputeMD5(instancesMd5, instancesIds);
 
-  Json::Value putResult;
-  std::string attachmentUrl = "/series/" + seriesOrthancId + "/attachments/" + SERIES_METADATA_ATTACHMENT_ID;
-  if (!OrthancPlugins::RestApiPut(putResult, attachmentUrl, cacheContent, false))
-  {
-    LOG(WARNING) << "DicomWEB: failed to write series metadata attachment";
+    std::string cacheContent = "2;" + instancesMd5 + ";" + compressedSeriesMetadata; 
+
+    Json::Value putResult;
+    std::string attachmentUrl = "/series/" + seriesOrthancId + "/attachments/" + SERIES_METADATA_ATTACHMENT_ID;
+    if (!OrthancPlugins::RestApiPut(putResult, attachmentUrl, cacheContent, false))
+    {
+      LOG(WARNING) << "DicomWEB: failed to write series metadata attachment";
+    }
   }
-
 }
 
 void CacheSeriesMetadata(const std::string& seriesOrthancId)
--- a/Plugin/WadoRs.h	Mon Sep 16 11:20:07 2024 +0200
+++ b/Plugin/WadoRs.h	Fri Sep 27 17:29:33 2024 +0200
@@ -104,4 +104,6 @@
 
 void SetPluginCanDownloadTranscodedFile(bool enable);
 
-void SetPluginCanUseExtendedFile(bool enable);
\ No newline at end of file
+void SetPluginCanUseExtendedFile(bool enable);
+
+void SetSystemIsReadOnly(bool isReadOnly);
\ No newline at end of file