changeset 4604:2c702cfae274 db-changes

New option "DatabaseServerIdentifier" to identify the server among a pool of Orthanc servers
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Mar 2021 10:39:59 +0200
parents c125bfd31023
children d01702fb29a9
files NEWS OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/OrthancPlugins.h OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h OrthancServer/Resources/Configuration.json OrthancServer/Sources/OrthancConfiguration.cpp OrthancServer/Sources/OrthancConfiguration.h OrthancServer/Sources/main.cpp
diffstat 10 files changed, 92 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Mar 24 15:30:06 2021 +0100
+++ b/NEWS	Tue Mar 30 10:39:59 2021 +0200
@@ -5,6 +5,7 @@
 -------
 
 * Possibility to create database index plugins that don't lock a global mutex
+* New option "DatabaseServerIdentifier" to identify the server among a pool of Orthanc servers
 
 Maintenance
 -----------
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Tue Mar 30 10:39:59 2021 +0200
@@ -696,7 +696,8 @@
     virtual bool LookupGlobalProperty(std::string& target,
                                       GlobalProperty property) ORTHANC_OVERRIDE
     {
-      CheckSuccess(that_.backend_.lookupGlobalProperty(transaction_, static_cast<int32_t>(property)));
+      CheckSuccess(that_.backend_.lookupGlobalProperty(
+                     transaction_, that_.serverIdentifier_.c_str(), static_cast<int32_t>(property)));
       CheckNoEvent();
       return ReadSingleStringAnswer(target);      
     }
@@ -762,7 +763,8 @@
     virtual void SetGlobalProperty(GlobalProperty property,
                                    const std::string& value) ORTHANC_OVERRIDE
     {
-      CheckSuccess(that_.backend_.setGlobalProperty(transaction_, static_cast<int32_t>(property), value.c_str()));
+      CheckSuccess(that_.backend_.setGlobalProperty(transaction_, that_.serverIdentifier_.c_str(),
+                                                    static_cast<int32_t>(property), value.c_str()));
       CheckNoEvent();
     }
 
@@ -1048,11 +1050,16 @@
                                                    PluginsErrorDictionary&  errorDictionary,
                                                    const OrthancPluginDatabaseBackendV3* backend,
                                                    size_t backendSize,
-                                                   void* database) :
+                                                   void* database,
+                                                   const std::string& serverIdentifier) :
     library_(library),
     errorDictionary_(errorDictionary),
-    database_(database)
+    database_(database),
+    serverIdentifier_(serverIdentifier)
   {
+    CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties "
+                        << "of the custom database: \"" << serverIdentifier << "\"";
+    
     if (backendSize >= sizeof(backend_))
     {
       memcpy(&backend_, backend, sizeof(backend_));
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Tue Mar 30 10:39:59 2021 +0200
@@ -51,6 +51,7 @@
     PluginsErrorDictionary&         errorDictionary_;
     OrthancPluginDatabaseBackendV3  backend_;
     void*                           database_;
+    std::string                     serverIdentifier_;
 
     void CheckSuccess(OrthancPluginErrorCode code);
 
@@ -59,7 +60,8 @@
                             PluginsErrorDictionary&  errorDictionary,
                             const OrthancPluginDatabaseBackendV3* backend,
                             size_t backendSize,
-                            void* database);
+                            void* database,
+                            const std::string& serverIdentifier);
 
     virtual ~OrthancPluginDatabaseV3();
 
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Tue Mar 30 10:39:59 2021 +0200
@@ -1195,13 +1195,15 @@
     std::unique_ptr<OrthancPluginDatabase>  database_;
     std::unique_ptr<OrthancPluginDatabaseV3>  databaseV3_;  // New in Orthanc 1.9.2
     PluginsErrorDictionary  dictionary_;
-
-    PImpl() : 
+    std::string databaseServerIdentifier_;   // New in Orthanc 1.9.2
+
+    PImpl(const std::string& databaseServerIdentifier) : 
       context_(NULL), 
       findCallback_(NULL),
       worklistCallback_(NULL),
       argc_(1),
-      argv_(NULL)
+      argv_(NULL),
+      databaseServerIdentifier_(databaseServerIdentifier)
     {
       memset(&moveCallbacks_, 0, sizeof(moveCallbacks_));
     }
@@ -1675,7 +1677,7 @@
   };
 
 
-  OrthancPlugins::OrthancPlugins()
+  OrthancPlugins::OrthancPlugins(const std::string& databaseServerIdentifier)
   {
     /* Sanity check of the compiler */
     if (sizeof(int32_t) != sizeof(OrthancPluginErrorCode) ||
@@ -1715,7 +1717,7 @@
       throw OrthancException(ErrorCode_Plugin);
     }
 
-    pimpl_.reset(new PImpl());
+    pimpl_.reset(new PImpl(databaseServerIdentifier));
     pimpl_->manager_.RegisterServiceProvider(*this);
   }
 
@@ -4948,8 +4950,8 @@
         if (pimpl_->database_.get() == NULL &&
             pimpl_->databaseV3_.get() == NULL)
         {
-          pimpl_->databaseV3_.reset(new OrthancPluginDatabaseV3(plugin, GetErrorDictionary(),
-                                                                p.backend, p.backendSize, p.database));
+          pimpl_->databaseV3_.reset(new OrthancPluginDatabaseV3(plugin, GetErrorDictionary(), p.backend,
+                                                                p.backendSize, p.database, pimpl_->databaseServerIdentifier_));
         }
         else
         {
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h	Tue Mar 30 10:39:59 2021 +0200
@@ -245,7 +245,7 @@
                                  bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
     
   public:
-    OrthancPlugins();
+    explicit OrthancPlugins(const std::string& databaseServerIdentifier);
 
     virtual ~OrthancPlugins();
 
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h	Tue Mar 30 10:39:59 2021 +0200
@@ -1248,6 +1248,7 @@
 
     /* Answer is read using "readAnswerString()" */
     OrthancPluginErrorCode (*lookupGlobalProperty) (OrthancPluginDatabaseTransaction* transaction,
+                                                    const char* serverIdentifier,
                                                     int32_t property);
     
     /* Answer is read using "readAnswerString()" */
@@ -1288,6 +1289,7 @@
                                                        int64_t patientIdToAvoid);
 
     OrthancPluginErrorCode (*setGlobalProperty) (OrthancPluginDatabaseTransaction* transaction,
+                                                 const char* serverIdentifier,
                                                  int32_t property,
                                                  const char* value);
 
--- a/OrthancServer/Resources/Configuration.json	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Resources/Configuration.json	Tue Mar 30 10:39:59 2021 +0200
@@ -769,4 +769,15 @@
   // Orthanc SCU and Orthanc SCP. It defaults to 16KB. The allowed
   // range is [4096,131072]. (new in Orthanc 1.9.0)
   "MaximumPduLength" : 16384
+
+  // Arbitrary identifier of this Orthanc server when storing its
+  // global properties if a custom database plugin is used. This
+  // option is only useful in the case of multiple readers/writers, in
+  // order to avoid collisions between multiple Orthanc servers. If
+  // unset, this identifier is taken as a SHA-1 hash derived from the
+  // MAC adddresses of the network interfaces, and from the AET and
+  // TCP ports used by Orthanc. (new in Orthanc 1.9.2)
+  /**
+     , "DatabaseServerIdentifier" : "Orthanc1"
+  **/
 }
--- a/OrthancServer/Sources/OrthancConfiguration.cpp	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Sources/OrthancConfiguration.cpp	Tue Mar 30 10:39:59 2021 +0200
@@ -1014,6 +1014,51 @@
   }
 
 
+  std::string OrthancConfiguration::GetDatabaseServerIdentifier() const
+  {
+    std::string id;
+
+    if (LookupStringParameter(id, "DatabaseServerIdentifier"))
+    {
+      return id;
+    }
+    else
+    {
+      std::set<std::string> items;
+
+      {
+        std::set<std::string> mac;
+        SystemToolbox::GetMacAddresses(mac);
+
+        for (std::set<std::string>::const_iterator it = mac.begin(); it != mac.end(); ++it)
+        {
+          items.insert("mac=" + *it);
+        }
+      }
+
+      items.insert("aet=" + GetStringParameter("DicomAet", "ORTHANC"));
+      items.insert("dicom-port=" + boost::lexical_cast<std::string>(GetUnsignedIntegerParameter("DicomPort", 4242)));
+      items.insert("http-port=" + boost::lexical_cast<std::string>(GetUnsignedIntegerParameter("HttpPort", 8042)));
+
+      for (std::set<std::string>::const_iterator it = items.begin(); it != items.end(); ++it)
+      {
+        if (id.empty())
+        {
+          id = *it;
+        }
+        else
+        {
+          id += ("|" + *it);
+        }
+      }
+
+      std::string hash;
+      Toolbox::ComputeSHA1(hash, id);
+      return hash;
+    }
+  }
+
+  
   void OrthancConfiguration::DefaultExtractDicomSummary(DicomMap& target,
                                                         const ParsedDicomFile& dicom)
   {
--- a/OrthancServer/Sources/OrthancConfiguration.h	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Sources/OrthancConfiguration.h	Tue Mar 30 10:39:59 2021 +0200
@@ -251,6 +251,8 @@
 
     void GetAcceptedTransferSyntaxes(std::set<DicomTransferSyntax>& target) const;
 
+    std::string GetDatabaseServerIdentifier() const;
+
     static void DefaultExtractDicomSummary(DicomMap& target,
                                            const ParsedDicomFile& dicom);
 
--- a/OrthancServer/Sources/main.cpp	Wed Mar 24 15:30:06 2021 +0100
+++ b/OrthancServer/Sources/main.cpp	Tue Mar 30 10:39:59 2021 +0200
@@ -1505,7 +1505,13 @@
   std::unique_ptr<IStorageArea>  storage;
 
 #if ORTHANC_ENABLE_PLUGINS == 1
-  OrthancPlugins plugins;
+  std::string databaseServerIdentifier;
+  {
+    OrthancConfiguration::ReaderLock lock;
+    databaseServerIdentifier = lock.GetConfiguration().GetDatabaseServerIdentifier();
+  }
+  
+  OrthancPlugins plugins(databaseServerIdentifier);
   plugins.SetCommandLineArguments(argc, argv);
   LoadPlugins(plugins);