changeset 584:47b14499455e find-refactoring

fix initialization in ReadOnly mode
author Alain Mazy <am@orthanc.team>
date Mon, 04 Nov 2024 17:51:22 +0100
parents ae7375d38607
children 65e39e76c2b6
files Framework/Plugins/IndexBackend.cpp Framework/Plugins/IndexBackend.h PostgreSQL/Plugins/IndexPlugin.cpp PostgreSQL/Plugins/PostgreSQLIndex.cpp PostgreSQL/Plugins/PostgreSQLIndex.h
diffstat 5 files changed, 51 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Plugins/IndexBackend.cpp	Mon Oct 21 18:19:51 2024 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Mon Nov 04 17:51:22 2024 +0100
@@ -305,8 +305,10 @@
   }
 
 
-  IndexBackend::IndexBackend(OrthancPluginContext* context) :
-    context_(context)
+  IndexBackend::IndexBackend(OrthancPluginContext* context,
+                             bool readOnly) :
+    context_(context),
+    readOnly_(readOnly)
   {
   }
 
--- a/Framework/Plugins/IndexBackend.h	Mon Oct 21 18:19:51 2024 +0200
+++ b/Framework/Plugins/IndexBackend.h	Mon Nov 04 17:51:22 2024 +0100
@@ -42,6 +42,7 @@
     class LookupFormatter;
 
     OrthancPluginContext*  context_;
+    bool                   readOnly_;
 
     boost::shared_mutex                                outputFactoryMutex_;
     std::unique_ptr<IDatabaseBackendOutput::IFactory>  outputFactory_;
@@ -59,6 +60,11 @@
     void SignalDeletedResources(IDatabaseBackendOutput& output,
                                 DatabaseManager& manager);
 
+    bool IsReadOnly()
+    {
+      return readOnly_;
+    }
+
   private:
     void ReadChangesInternal(IDatabaseBackendOutput& output,
                              bool& done,
@@ -75,7 +81,7 @@
                                        uint32_t limit);
 
   public:
-    explicit IndexBackend(OrthancPluginContext* context);
+    explicit IndexBackend(OrthancPluginContext* context, bool readOnly);
 
     virtual OrthancPluginContext* GetContext() ORTHANC_OVERRIDE
     {
--- a/PostgreSQL/Plugins/IndexPlugin.cpp	Mon Oct 21 18:19:51 2024 +0200
+++ b/PostgreSQL/Plugins/IndexPlugin.cpp	Mon Nov 04 17:51:22 2024 +0100
@@ -65,13 +65,20 @@
       return 0;
     }
 
+    bool readOnly = configuration.GetBooleanValue("ReadOnly", false);
+
+    if (readOnly)
+    {
+      LOG(WARNING) << "READ-ONLY SYSTEM: the Database plugin is working in read-only mode";
+    }
+    
     try
     {
       const size_t countConnections = postgresql.GetUnsignedIntegerValue("IndexConnectionsCount", 1);
 
       OrthancDatabases::PostgreSQLParameters parameters(postgresql);
       OrthancDatabases::IndexBackend::Register(
-        new OrthancDatabases::PostgreSQLIndex(context, parameters), countConnections,
+        new OrthancDatabases::PostgreSQLIndex(context, parameters, readOnly), countConnections,
         parameters.GetMaxConnectionRetries());
     }
     catch (Orthanc::OrthancException& e)
--- a/PostgreSQL/Plugins/PostgreSQLIndex.cpp	Mon Oct 21 18:19:51 2024 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLIndex.cpp	Mon Nov 04 17:51:22 2024 +0100
@@ -50,8 +50,9 @@
 namespace OrthancDatabases
 {
   PostgreSQLIndex::PostgreSQLIndex(OrthancPluginContext* context,
-                                   const PostgreSQLParameters& parameters) :
-    IndexBackend(context),
+                                   const PostgreSQLParameters& parameters,
+                                   bool readOnly) :
+    IndexBackend(context, readOnly),
     parameters_(parameters),
     clearAll_(false)
   {
@@ -94,11 +95,18 @@
 
     PostgreSQLDatabase& db = dynamic_cast<PostgreSQLDatabase&>(manager.GetDatabase());
 
-    if (parameters_.HasLock())
+    if (parameters_.HasLock()) 
     {
+      if (IsReadOnly())
+      {
+        LOG(ERROR) << "READ-ONLY SYSTEM: Unable to lock the database when working in ReadOnly mode."; 
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin);
+      }
+
       db.AdvisoryLock(POSTGRESQL_LOCK_INDEX);
     }
 
+    if (!IsReadOnly())
     {
       // lock the full DB while checking if it needs to be create/ugraded
       PostgreSQLDatabase::TransientAdvisoryLock lock(db, POSTGRESQL_LOCK_DATABASE_SETUP);
@@ -217,11 +225,30 @@
             // ComputeStatisticsReadOnly() that does not need to be uninstalled in case of downgrade.
             ApplyPrepareIndex(t, manager);
           }
+
+          // If you add new tests here, update the test in the "ReadOnly" code below
         }
 
         t.Commit();
       }
     }
+    else
+    {
+      LOG(WARNING) << "READ-ONLY SYSTEM: checking if the DB already exists and has the right schema"; 
+
+      DatabaseManager::Transaction t(manager, TransactionType_ReadOnly);
+
+      int property = 0;
+      
+      // test if the last "extension" has been installed
+      if (!LookupGlobalIntegerProperty(property, manager, MISSING_SERVER_IDENTIFIER,
+                                        Orthanc::GlobalProperty_HasComputeStatisticsReadOnly) ||
+          property != 1)
+      {
+        LOG(ERROR) << "READ-ONLY SYSTEM: the DB does not have the correct schema to run with this version of the plugin"; 
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
+      }
+    }
   }
 
 
--- a/PostgreSQL/Plugins/PostgreSQLIndex.h	Mon Oct 21 18:19:51 2024 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLIndex.h	Mon Nov 04 17:51:22 2024 +0100
@@ -45,7 +45,8 @@
 
   public:
     PostgreSQLIndex(OrthancPluginContext* context,
-                    const PostgreSQLParameters& parameters);
+                    const PostgreSQLParameters& parameters,
+                    bool readOnly = false);
 
     void SetClearAll(bool clear)
     {