changeset 4340:6fa8bb987be2

"DicomEchoChecksFind" config option + "CheckFind" field in /modalities/.../echo
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 03 Dec 2020 15:58:52 +0100
parents fc5caed6f940
children 977c2759eb0a
files NEWS OrthancServer/Resources/Configuration.json OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp
diffstat 3 files changed, 50 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Dec 03 11:47:03 2020 +0100
+++ b/NEWS	Thu Dec 03 15:58:52 2020 +0100
@@ -7,6 +7,7 @@
 * New sample tool "OrthancImport.py" to easily import compressed archives (ZIP) into Orthanc
 * Logging categories (cf. command-line options starting with "--verbose-" and "--trace=")
 * New command-line option "--trace-dicom" to access full debug information from DCMTK
+* New config option "DicomEchoChecksFind" to automatically complement C-GET SCU with C-FIND SCU
 
 REST API
 --------
@@ -16,6 +17,8 @@
 * "/tools/log-level-*": Dynamically access and/or change the verbosity of logging categories
 * "/peers/{id}/configuration": Get the configuration of one peer (cf. "/peers?expand")
 * "/modalities/{id}/configuration": Get the configuration of one modality (cf. "/modalities?expand")
+* "/tools/dicom-echo" and "/modalities/{id}/echo" now accept the field "CheckFind" in their JSON
+  body to complement C-GET SCU with C-FIND SCU ("DicomEchoChecksFind" on a per-connection basis)
 
 Maintenance
 -----------
--- a/OrthancServer/Resources/Configuration.json	Thu Dec 03 11:47:03 2020 +0100
+++ b/OrthancServer/Resources/Configuration.json	Thu Dec 03 15:58:52 2020 +0100
@@ -287,6 +287,12 @@
   // "false", Orthanc only checks the AET of the remote modality.
   "DicomCheckModalityHost" : false,
 
+  // Whether the C-GET SCU is automatically followed by a C-FIND SCU,
+  // while testing the connectivity from Orthanc to a remote DICOM
+  // modality. This allows to check that the remote modality does
+  // accept C-FIND requests from Orthanc (new in Orthanc 1.8.1).
+  "DicomEchoChecksFind" : false,
+
   // The timeout (in seconds) after which the DICOM associations are
   // considered as closed by the Orthanc SCU (client) if the remote
   // DICOM SCP (server) does not answer.
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp	Thu Dec 03 11:47:03 2020 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp	Thu Dec 03 15:58:52 2020 +0100
@@ -60,6 +60,7 @@
   static const char* const KEY_RESOURCES = "Resources";
   static const char* const KEY_TARGET_AET = "TargetAet";
   static const char* const KEY_TIMEOUT = "Timeout";
+  static const char* const KEY_CHECK_FIND = "CheckFind";
   static const char* const SOP_CLASS_UID = "SOPClassUID";
   static const char* const SOP_INSTANCE_UID = "SOPInstanceUID";
   
@@ -114,15 +115,42 @@
    ***************************************************************************/
 
   static void ExecuteEcho(RestApiOutput& output,
-                          const DicomAssociationParameters& parameters)
+                          const DicomAssociationParameters& parameters,
+                          const Json::Value& body)
   {
     DicomControlUserConnection connection(parameters);
 
     if (connection.Echo())
     {
+      bool find = false;
+      
+      if (body.type() == Json::objectValue &&
+          body.isMember(KEY_CHECK_FIND))
+      {
+        find = SerializationToolbox::ReadBoolean(body, KEY_CHECK_FIND);
+      }
+      else
+      {
+        OrthancConfiguration::ReaderLock lock;
+        find = lock.GetConfiguration().GetBooleanParameter("DicomEchoChecksFind", false);
+      }
+
+      if (find)
+      {
+        // Issue a C-FIND request at the study level about a random Study Instance UID
+        const std::string studyInstanceUid = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study);
+        
+        DicomMap query;
+        query.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyInstanceUid, false);
+
+        DicomFindAnswers answers(false /* not a worklist */);
+
+        // The following line throws an exception if the remote modality doesn't support C-FIND
+        connection.Find(answers, ResourceType_Study, query, false /* normalize */);
+      }
+
       // Echo has succeeded
       output.AnswerBuffer("{}", MimeType_Json);
-      return;
     }
     else
     {
@@ -134,7 +162,16 @@
   
   static void DicomEcho(RestApiPostCall& call)
   {
-    ExecuteEcho(call.GetOutput(), GetAssociationParameters(call));
+    Json::Value body;
+    if (call.ParseJsonRequest(body))
+    {
+      const DicomAssociationParameters parameters = GetAssociationParameters(call, body);
+      ExecuteEcho(call.GetOutput(), parameters, body);
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_BadFileFormat, "Cannot parse the JSON body");
+    }
   }
   
 
@@ -152,7 +189,7 @@
       DicomAssociationParameters params(localAet, modality);
       InjectAssociationTimeout(params, body);
 
-      ExecuteEcho(call.GetOutput(), params);
+      ExecuteEcho(call.GetOutput(), params, body);
     }
     else
     {