changeset 6037:ee903fefedbf pixel-anon

merge default -> pixel-anon
author Alain Mazy <am@orthanc.team>
date Tue, 11 Mar 2025 10:47:31 +0100
parents 6ad530603d23 (current diff) cba3e8ca3a87 (diff)
children 4742b4fe824b
files TODO
diffstat 11 files changed, 157 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Mar 07 17:25:34 2025 +0100
+++ b/NEWS	Tue Mar 11 10:47:31 2025 +0100
@@ -25,6 +25,9 @@
 * Recovered compatibility with Windows XP that was broken because of DCMTK 3.6.9
 * Enabled support of the 1.2.840.10008.1.2.1.99 transfer syntax
   (Deflated Explicit VR Little Endian) in static builds
+* Housekeeper plugin:
+  - When encountering an error, the housekeeper now skips the resource and continues processing.
+
 
 
 Version 1.12.6 (2025-01-22)
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Tue Mar 11 10:47:31 2025 +0100
@@ -699,7 +699,7 @@
                             const HttpToolbox::Arguments& headers,
                             const HttpToolbox::GetArguments& argumentsGET)
   {
-    std::string overriden;
+    std::string overridden;
 
     // Check whether some PUT/DELETE faking is done
 
@@ -709,7 +709,7 @@
 
     if (methodOverride != headers.end())
     {
-      overriden = methodOverride->second;
+      overridden = methodOverride->second;
     }
     else if (!strcmp(request->request_method, "GET"))
     {
@@ -719,25 +719,25 @@
       {
         if (argumentsGET[i].first == "_method")
         {
-          overriden = argumentsGET[i].second;
+          overridden = argumentsGET[i].second;
           break;
         }
       }
     }
 
-    if (overriden.size() > 0)
+    if (overridden.size() > 0)
     {
       // A faking has been done within this request
-      Toolbox::ToUpperCase(overriden);
+      Toolbox::ToUpperCase(overridden);
 
-      CLOG(INFO, HTTP) << "HTTP method faking has been detected for " << overriden;
+      CLOG(INFO, HTTP) << "HTTP method faking has been detected for " << overridden;
 
-      if (overriden == "PUT")
+      if (overridden == "PUT")
       {
         method = HttpMethod_Put;
         return true;
       }
-      else if (overriden == "DELETE")
+      else if (overridden == "DELETE")
       {
         method = HttpMethod_Delete;
         return true;
--- a/OrthancFramework/UnitTestsSources/GithubCACertificates.h	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancFramework/UnitTestsSources/GithubCACertificates.h	Tue Mar 11 10:47:31 2025 +0100
@@ -1,30 +1,37 @@
 #define GITHUB_CERTIFICATES  \
 "-----BEGIN CERTIFICATE-----\n"  \
-"MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh\n"  \
-"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"  \
-"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n"  \
-"MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT\n"  \
-"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh\n"  \
-"bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD\n"  \
-"ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV\n"  \
-"cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy\n"  \
-"FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc\n"  \
-"3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8\n"  \
-"osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT\n"  \
-"zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud\n"  \
-"EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G\n"  \
-"A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd\n"  \
-"BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG\n"  \
-"CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG\n"  \
-"NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH\n"  \
-"Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t\n"  \
-"L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC\n"  \
-"ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG\n"  \
-"9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t\n"  \
-"wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS\n"  \
-"slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R\n"  \
-"bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4\n"  \
-"chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN\n"  \
-"JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA==\n"  \
+"MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB\n"  \
+"iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n"  \
+"cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n"  \
+"BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx\n"  \
+"MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBjzELMAkGA1UEBhMCR0IxGzAZBgNV\n"  \
+"BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE\n"  \
+"ChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFJTQSBEb21haW4g\n"  \
+"VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC\n"  \
+"AQ8AMIIBCgKCAQEA1nMz1tc8INAA0hdFuNY+B6I/x0HuMjDJsGz99J/LEpgPLT+N\n"  \
+"TQEMgg8Xf2Iu6bhIefsWg06t1zIlk7cHv7lQP6lMw0Aq6Tn/2YHKHxYyQdqAJrkj\n"  \
+"eocgHuP/IJo8lURvh3UGkEC0MpMWCRAIIz7S3YcPb11RFGoKacVPAXJpz9OTTG0E\n"  \
+"oKMbgn6xmrntxZ7FN3ifmgg0+1YuWMQJDgZkW7w33PGfKGioVrCSo1yfu4iYCBsk\n"  \
+"Haswha6vsC6eep3BwEIc4gLw6uBK0u+QDrTBQBbwb4VCSmT3pDCg/r8uoydajotY\n"  \
+"uK3DGReEY+1vVv2Dy2A0xHS+5p3b4eTlygxfFQIDAQABo4IBbjCCAWowHwYDVR0j\n"  \
+"BBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFI2MXsRUrYrhd+mb\n"  \
+"+ZsF4bgBjWHhMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G\n"  \
+"A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYGBFUdIAAw\n"  \
+"CAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0\n"  \
+"LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2Bggr\n"  \
+"BgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNv\n"  \
+"bS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDov\n"  \
+"L29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAMr9hvQ5Iw0/H\n"  \
+"ukdN+Jx4GQHcEx2Ab/zDcLRSmjEzmldS+zGea6TvVKqJjUAXaPgREHzSyrHxVYbH\n"  \
+"7rM2kYb2OVG/Rr8PoLq0935JxCo2F57kaDl6r5ROVm+yezu/Coa9zcV3HAO4OLGi\n"  \
+"H19+24rcRki2aArPsrW04jTkZ6k4Zgle0rj8nSg6F0AnwnJOKf0hPHzPE/uWLMUx\n"  \
+"RP0T7dWbqWlod3zu4f+k+TY4CFM5ooQ0nBnzvg6s1SQ36yOoeNDT5++SR2RiOSLv\n"  \
+"xvcRviKFxmZEJCaOEDKNyJOuB56DPi/Z+fVGjmO+wea03KbNIaiGCpXZLoUmGv38\n"  \
+"sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL\n"  \
+"l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq\n"  \
+"6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY\n"  \
+"LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5\n"  \
+"yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K\n"  \
+"00u/I5sUKUErmgQfky3xxzlIPK1aEn8=\n"  \
 "-----END CERTIFICATE-----\n"  \
 "\n" 
--- a/OrthancFramework/UnitTestsSources/RestApiTests.cpp	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancFramework/UnitTestsSources/RestApiTests.cpp	Tue Mar 11 10:47:31 2025 +0100
@@ -99,9 +99,9 @@
 #if (UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1) && (ORTHANC_ENABLE_SSL == 1) && (ORTHANC_SANDBOXED != 1)
 
 /**
-   The HTTPS CA certificates for BitBucket were extracted as follows:
+   The HTTPS CA certificates for Github were extracted as follows:
    
-   (1) We retrieve the URI of the root CA of BitBucket:
+   (1) We retrieve the URI of the root CA of Github:
 
    # echo | openssl s_client -servername raw.githubusercontent.com -connect raw.githubusercontent.com:443 2>/dev/null | openssl x509 -text | grep "CA Issuers"
 
@@ -109,7 +109,7 @@
    macro that can be used by libcurl:
 
    # cd UnitTestsSources
-   # python2 ../Resources/RetrieveCACertificates.py GITHUB_CERTIFICATES http://cacerts.digicert.com/DigiCertGlobalG2TLSRSASHA2562020CA1-1.crt > GithubCACertificates.h
+   # python2 ../Resources/RetrieveCACertificates.py GITHUB_CERTIFICATES http://crt.sectigo.com/SectigoRSADomainValidationSecureServerCA.crt > GithubCACertificates.h
 **/
 
 #include "GithubCACertificates.h"
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Tue Mar 11 10:47:31 2025 +0100
@@ -4151,6 +4151,24 @@
     httpStatus_(0)
   {
   }
+
+  RestApiClient::RestApiClient(const char* url,
+                               const OrthancPluginHttpRequest* request) :
+    method_(request->method),
+    path_(url),
+    afterPlugins_(false),
+    httpStatus_(0)
+  {
+    OrthancPlugins::GetHttpHeaders(requestHeaders_, request);
+
+    std::string getArguments;
+    OrthancPlugins::SerializeGetArguments(getArguments, request);
+
+    if (!getArguments.empty())
+    {
+      path_ += "?" + getArguments;
+    }
+  }
 #endif
 
 
@@ -4216,6 +4234,32 @@
       }
     }
   }
+
+  void RestApiClient::Forward(OrthancPluginContext* context, OrthancPluginRestOutput* output)
+  {
+    if (Execute() && httpStatus_ == 200)
+    {
+      const char* mimeType = NULL;
+      for (HttpHeaders::const_iterator h = answerHeaders_.begin(); h != answerHeaders_.end(); ++h)
+      {
+        if (h->first == "content-type")
+        {
+          mimeType = h->second.c_str();
+        }
+      }
+      
+      AnswerString(answerBody_, mimeType, output);
+    }
+    else
+    {
+      AnswerHttpError(httpStatus_, output);
+    }
+  }
+
+  bool RestApiClient::GetAnswerJson(Json::Value& output) const
+  {
+    return ReadJson(output, answerBody_);
+  }
 #endif
 
 
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Tue Mar 11 10:47:31 2025 +0100
@@ -1531,6 +1531,10 @@
 
   public:
     RestApiClient();
+    
+    // used to forward a call from the plugin to the core
+    RestApiClient(const char* url,
+                  const OrthancPluginHttpRequest* request);
 
     void SetMethod(OrthancPluginHttpMethod method)
     {
@@ -1587,12 +1591,17 @@
 
     bool Execute();
 
+    // Execute and forward the response as is
+    void Forward(OrthancPluginContext* context, OrthancPluginRestOutput* output);
+
     uint16_t GetHttpStatus() const;
 
     bool LookupAnswerHeader(std::string& value,
                             const std::string& key) const;
 
     const std::string& GetAnswerBody() const;
+
+    bool GetAnswerJson(Json::Value& output) const;
   };
 #endif
 }
--- a/OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp	Tue Mar 11 10:47:31 2025 +0100
@@ -549,39 +549,46 @@
       const Json::Value& change = changes["Changes"][i];
       int64_t seq = change["Seq"].asInt64();
 
-      if (!limitToChange_.empty()) // if updating only maindicomtags for a single level 
+      try
       {
-        if (change["ChangeType"] == limitToChange_)
+        if (!limitToChange_.empty()) // if updating only maindicomtags for a single level 
+        {
+          if (change["ChangeType"] == limitToChange_)
+          {
+            Json::Value result;
+            Json::Value request;
+            request["ReconstructFiles"] = false;
+            request["LimitToThisLevelMainDicomTags"] = true;
+            OrthancPlugins::RestApiPost(result, "/" + limitToUrl_ + "/" + change["ID"].asString() + "/reconstruct", request, false);
+          }
+        }
+        else
         {
-          Json::Value result;
-          Json::Value request;
-          request["ReconstructFiles"] = false;
-          request["LimitToThisLevelMainDicomTags"] = true;
-          OrthancPlugins::RestApiPost(result, "/" + limitToUrl_ + "/" + change["ID"].asString() + "/reconstruct", request, false);
+          if (change["ChangeType"] == "NewStudy") // some StableStudy might be missing if orthanc was shutdown during a StableAge -> consider only the NewStudy events that can not be missed
+          {
+            Json::Value result;
+
+            if (needsReconstruct || needsReingest ||force_)
+            {
+              Json::Value request;
+              if (needsReingest)
+              {
+                request["ReconstructFiles"] = true;
+              }
+              OrthancPlugins::RestApiPost(result, "/studies/" + change["ID"].asString() + "/reconstruct", request, false);
+            }
+
+            if (needsDicomWebCaching)
+            {
+              Json::Value request;
+              OrthancPlugins::RestApiPost(result, "/studies/" + change["ID"].asString() + "/update-dicomweb-cache", request, true);
+            }
+          }
         }
       }
-      else
+      catch (...)
       {
-        if (change["ChangeType"] == "NewStudy") // some StableStudy might be missing if orthanc was shutdown during a StableAge -> consider only the NewStudy events that can not be missed
-        {
-          Json::Value result;
-
-          if (needsReconstruct || needsReingest ||force_)
-          {
-            Json::Value request;
-            if (needsReingest)
-            {
-              request["ReconstructFiles"] = true;
-            }
-            OrthancPlugins::RestApiPost(result, "/studies/" + change["ID"].asString() + "/reconstruct", request, false);
-          }
-
-          if (needsDicomWebCaching)
-          {
-            Json::Value request;
-            OrthancPlugins::RestApiPost(result, "/studies/" + change["ID"].asString() + "/update-dicomweb-cache", request, true);
-          }
-        }
+        ORTHANC_PLUGINS_LOG_ERROR("Housekeeper: unhandled error while processing change " + boost::lexical_cast<std::string>(seq) + ", skipping resource.");
       }
 
       {
@@ -703,9 +710,17 @@
   {
     if (runningPeriods_.isInPeriod())
     {
-      completed = ProcessChanges(needsReconstruct, needsReingest, needsDicomWebCaching, currentDbConfiguration);
-      SaveStatusInDb();
-      
+      try
+      {
+        completed = ProcessChanges(needsReconstruct, needsReingest, needsDicomWebCaching, currentDbConfiguration);
+        SaveStatusInDb();
+      }
+      catch (...)
+      {
+        ORTHANC_PLUGINS_LOG_ERROR("Housekeeper: unhandled error while processing change " + boost::lexical_cast<std::string>(pluginStatus_.lastProcessedChange) +
+                                 " / " + boost::lexical_cast<std::string>(pluginStatus_.lastChangeToProcess));
+      }
+
       if (!completed)
       {
         boost::recursive_mutex::scoped_lock lock(pluginStatusMutex_);
--- a/OrthancServer/Resources/Configuration.json	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancServer/Resources/Configuration.json	Tue Mar 11 10:47:31 2025 +0100
@@ -214,7 +214,7 @@
   // "?" accepts any single character at that position.
   // "*" accepts any string value at that position.
   // If you want to add a a SOP class that is not defined in
-  // DCMTK defaults, you must add it explicitely.
+  // DCMTK defaults, you must add it explicitly.
   // (new in Orthanc 1.12.6)
   // Example to add a non standard class
   // and keep the default ones:
@@ -531,9 +531,9 @@
   // accept C-FIND requests from Orthanc (new in Orthanc 1.8.1).
   "DicomEchoChecksFind" : false,
 
-  // Wheter Orthanc uses C-MOVE or C-GET to retrieve a resource after
+  // Whether Orthanc uses C-MOVE or C-GET to retrieve a resource after
   // a C-Find (when calling /queries/.../retrieve).
-  // This configuration can be overriden for each modality by providing
+  // This configuration can be overridden for each modality by providing
   // "RetrieveMethod" in the "DicomModalities" entry.
   // (new in Orthanc 1.12.6)
   "DicomDefaultRetrieveMethod" : "C-MOVE",
@@ -947,7 +947,8 @@
 
   // Deidentify/anonymize the contents of the logs (notably C-FIND,
   // C-GET, and C-MOVE queries submitted to Orthanc) according to
-  // Table E.1-1 of the DICOM standard (new in Orthanc 1.8.2)
+  // Table E.1-1 of the DICOM standard (new in Orthanc 1.8.2).
+  // Note that, the DICOM logs at TRACE level are not deidentified !
   "DeidentifyLogs" : true,
 
   // If "DeidentifyLogs" is true, this sets the DICOM standard to
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp	Tue Mar 11 10:47:31 2025 +0100
@@ -1697,7 +1697,7 @@
                          "Usage of wildcards is prohibited and the query shall only contain DICOM ID tags.  "
                          "Additionally, you may provide SOPClassesInStudy to limit the scope of the DICOM "
                          "negotiation to certain SOPClassUID or to present uncommon SOPClassUID during "
-                         "the DICOM negotation.  By default, "
+                         "the DICOM negotiation.  By default, "
                          "Orhanc will propose the most 120 common SOPClassUIDs.", true)
         .SetRequestField(KEY_QUERY, RestApiCallDocumentation::Type_JsonObject,
                          "A query object identifying all the DICOM resources to be retrieved", true)
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Fri Mar 07 17:25:34 2025 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Tue Mar 11 10:47:31 2025 +0100
@@ -946,7 +946,7 @@
           }
           else
           {
-            // if present and not explicitely set to false
+            // if present and not explicitly set to false
             if (call.HasArgument("returnUnsupportedImage") && call.GetBooleanArgument("returnUnsupportedImage", true))
             {
               std::string root = "";
--- a/TODO	Fri Mar 07 17:25:34 2025 +0100
+++ b/TODO	Tue Mar 11 10:47:31 2025 +0100
@@ -36,7 +36,7 @@
   For a DICOM Transfer, that would be nice to include the modality in the context + a study identifier or a job id.
 * (1) Accept extra DICOM tags dictionaries in the DCMTK format '.dic' (easier to use than declare
   them in the Orthanc configuration file).  Even the standard dictionaries could be 
-  overriden by these custom dictionaries.
+  overridden by these custom dictionaries.
 * Add configurations to enable/disable warnings:
   - Modifying an instance while keeping its original SOPInstanceUID: This should be avoided!
   - Modifying a study while keeping its original StudyInstanceUID: This should be avoided!
@@ -206,6 +206,9 @@
 * Log outgoing C-Find queries
 * Support other Transfer Syntaxes in the Worklist plugin:
   https://discourse.orthanc-server.org/t/could-you-please-create-an-option-to-set-the-transfer-syntax-in-the-worklist-plugin-currently-little-endian-explicit-is-fixed/4871
+* Deidentify Trace level logs: https://discourse.orthanc-server.org/t/dicom-log-deidentification-at-trace-log-level/5563
+  We should implement something like GetDeidentifiedContent(const DcmDataSet& dataset) that would 
+  reproduce DcmDataSet::print but hide individual elements that contain PHI.
 
 
 ---------