changeset 303:eb4ac27f0768 refactoring

new URI: /dicom-web/servers/.../qido
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 17 Jun 2019 18:04:46 +0200
parents ebd8a1cd97da
children fb455aa44112
files NEWS Plugin/Configuration.cpp Plugin/Configuration.h Plugin/DicomWebClient.cpp Plugin/DicomWebClient.h Plugin/Plugin.cpp
diffstat 6 files changed, 177 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Jun 14 17:52:17 2019 +0200
+++ b/NEWS	Mon Jun 17 18:04:46 2019 +0200
@@ -4,6 +4,7 @@
 * Support "Transfer-Encoding: chunked" to reduce memory consumption in STOW-RS
   (provided the SDK version is above 1.5.7)
 * Handling of the HTTP header "Forwarded" for WADO-RS
+* New URI: /dicom-web/servers/.../qido
 
 
 Version 0.6 (2019-02-27)
--- a/Plugin/Configuration.cpp	Fri Jun 14 17:52:17 2019 +0200
+++ b/Plugin/Configuration.cpp	Mon Jun 17 18:04:46 2019 +0200
@@ -247,6 +247,39 @@
 
 
   void ParseAssociativeArray(std::map<std::string, std::string>& target,
+                             const Json::Value& value)
+  {
+    if (value.type() != Json::objectValue)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
+                                      "This is not a JSON object");
+    }
+
+    if (value.type() != Json::objectValue)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
+                                      "The JSON object is not a JSON associative array as expected");
+    }
+
+    Json::Value::Members names = value.getMemberNames();
+
+    for (size_t i = 0; i < names.size(); i++)
+    {
+      if (value[names[i]].type() != Json::stringValue)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
+                                        "Value \"" + names[i] + "\" in the associative array "
+                                        "is not a string as expected");
+      }
+      else
+      {
+        target[names[i]] = value[names[i]].asString();
+      }
+    }
+  }
+  
+
+  void ParseAssociativeArray(std::map<std::string, std::string>& target,
                              const Json::Value& value,
                              const std::string& key)
   {
@@ -256,34 +289,13 @@
                                       "This is not a JSON object");
     }
 
-    if (!value.isMember(key))
+    if (value.isMember(key))
     {
-      return;
-    }
-
-    const Json::Value& tmp = value[key];
-
-    if (tmp.type() != Json::objectValue)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
-                                      "The field \"" + key + "\" of a JSON object is "
-                                      "not a JSON associative array as expected");
+      ParseAssociativeArray(target, value[key]);
     }
-
-    Json::Value::Members names = tmp.getMemberNames();
-
-    for (size_t i = 0; i < names.size(); i++)
+    else
     {
-      if (tmp[names[i]].type() != Json::stringValue)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
-                                        "Some value in the associative array \"" + key + 
-                                        "\" is not a string as expected");
-      }
-      else
-      {
-        target[names[i]] = tmp[names[i]].asString();
-      }
+      target.clear();
     }
   }
 
--- a/Plugin/Configuration.h	Fri Jun 14 17:52:17 2019 +0200
+++ b/Plugin/Configuration.h	Mon Jun 17 18:04:46 2019 +0200
@@ -70,6 +70,9 @@
                              const Json::Value& value,
                              const std::string& key);
 
+  void ParseAssociativeArray(std::map<std::string, std::string>& target,
+                             const Json::Value& value);
+
   bool ParseTag(Orthanc::DicomTag& target,
                 const std::string& name);
 
--- a/Plugin/DicomWebClient.cpp	Fri Jun 14 17:52:17 2019 +0200
+++ b/Plugin/DicomWebClient.cpp	Mon Jun 17 18:04:46 2019 +0200
@@ -659,21 +659,16 @@
 
 
 
-
-void GetFromServer(OrthancPluginRestOutput* output,
-                   const char* /*url*/,
-                   const OrthancPluginHttpRequest* request)
+static void ConfigureGetFromServer(OrthancPlugins::HttpClient& client,
+                                   const OrthancPluginHttpRequest* request)
 {
   static const char* URI = "Uri";
   static const char* HTTP_HEADERS = "HttpHeaders";
   static const char* GET_ARGUMENTS = "Arguments";
 
-  OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
-
   if (request->method != OrthancPluginHttpMethod_Post)
   {
-    OrthancPluginSendMethodNotAllowed(context, output, "POST");
-    return;
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
   }
 
   std::string tmp;
@@ -695,12 +690,29 @@
   std::string uri;
   OrthancPlugins::DicomWebServers::UriEncode(uri, tmp, getArguments);
 
-  OrthancPlugins::HttpClient client;
   OrthancPlugins::DicomWebServers::GetInstance().ConfigureHttpClient(client, request->groups[0], uri);
 
   std::map<std::string, std::string> additionalHeaders;
   OrthancPlugins::ParseAssociativeArray(additionalHeaders, body, HTTP_HEADERS);
   client.AddHeaders(additionalHeaders);
+}
+
+
+
+void GetFromServer(OrthancPluginRestOutput* output,
+                   const char* /*url*/,
+                   const OrthancPluginHttpRequest* request)
+{
+  OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
+
+  if (request->method != OrthancPluginHttpMethod_Post)
+  {
+    OrthancPluginSendMethodNotAllowed(context, output, "POST");
+    return;
+  }
+
+  OrthancPlugins::HttpClient client;
+  ConfigureGetFromServer(client, request);
   
   std::map<std::string, std::string> answerHeaders;
   std::string answer;
@@ -733,6 +745,18 @@
 }
 
 
+void GetFromServer(Json::Value& result,
+                   const OrthancPluginHttpRequest* request)
+{
+  OrthancPlugins::HttpClient client;
+  ConfigureGetFromServer(client, request);
+
+  std::map<std::string, std::string> answerHeaders;
+  client.Execute(answerHeaders, result);
+}
+
+
+
 
 static void RetrieveFromServerInternal(std::set<std::string>& instances,
                                        const Orthanc::WebServiceParameters& server,
--- a/Plugin/DicomWebClient.h	Fri Jun 14 17:52:17 2019 +0200
+++ b/Plugin/DicomWebClient.h	Mon Jun 17 18:04:46 2019 +0200
@@ -32,6 +32,9 @@
                    const char* /*url*/,
                    const OrthancPluginHttpRequest* request);
 
+void GetFromServer(Json::Value& result,
+                   const OrthancPluginHttpRequest* request);
+
 void RetrieveFromServer(OrthancPluginRestOutput* output,
                         const char* /*url*/,
                         const OrthancPluginHttpRequest* request);
--- a/Plugin/Plugin.cpp	Fri Jun 14 17:52:17 2019 +0200
+++ b/Plugin/Plugin.cpp	Mon Jun 17 18:04:46 2019 +0200
@@ -103,6 +103,7 @@
       json.append("get");
       json.append("retrieve");
       json.append("stow");
+      json.append("qido");
 
       std::string answer = json.toStyledString(); 
       OrthancPluginAnswerBuffer(context, output, answer.c_str(), answer.size(), "application/json");
@@ -142,6 +143,104 @@
 }
 
 
+
+void QidoClient(OrthancPluginRestOutput* output,
+                const char* /*url*/,
+                const OrthancPluginHttpRequest* request)
+{
+  OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
+
+  if (request->method != OrthancPluginHttpMethod_Post)
+  {
+    OrthancPluginSendMethodNotAllowed(context, output, "POST");
+  }
+  else
+  {
+    Json::Value answer;
+    GetFromServer(answer, request);
+    
+    if (answer.type() != Json::arrayValue)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
+    }
+
+    Json::Value result = Json::arrayValue;
+    for (Json::Value::ArrayIndex i = 0; i < answer.size(); i++)
+    {
+      if (answer[i].type() != Json::objectValue)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
+      }
+
+      Json::Value::Members tags = answer[i].getMemberNames();
+
+      Json::Value item = Json::objectValue;
+      
+      for (size_t j = 0; j < tags.size(); j++)
+      {
+        Orthanc::DicomTag tag(0, 0);
+        if (Orthanc::DicomTag::ParseHexadecimal(tag, tags[j].c_str()))
+        {
+          Json::Value value = Json::objectValue;
+          value["Group"] = tag.GetGroup();
+          value["Element"] = tag.GetElement();
+          
+          OrthancPlugins::OrthancString name;
+          name.Assign(OrthancPluginGetTagName(context, tag.GetGroup(), tag.GetElement(), NULL));
+
+          if (name.GetContent() != NULL)
+          {
+            value["Name"] = std::string(name.GetContent());
+          }
+
+          const Json::Value& source = answer[i][tags[j]];
+          if (source.type() != Json::objectValue ||
+              !source.isMember("vr") ||
+              source["vr"].type() != Json::stringValue)
+          {
+            throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
+          }
+
+          value["vr"] = source["vr"].asString();
+
+          if (source.isMember("Value") &&
+              source["Value"].type() == Json::arrayValue &&
+              source["Value"].size() >= 1)
+          {
+            const Json::Value& content = source["Value"][0];
+
+            switch (content.type())
+            {
+              case Json::stringValue:
+                value["Value"] = content.asString();
+                break;
+
+              case Json::objectValue:
+                if (content.isMember("Alphabetic") &&
+                    content["Alphabetic"].type() == Json::stringValue)
+                {
+                  value["Value"] = content["Alphabetic"].asString();
+                }
+                break;
+
+              default:
+                break;
+            }
+          }
+
+          item[tags[j]] = value;
+        }
+      }
+
+      result.append(item);
+    }
+
+    std::string tmp = result.toStyledString();
+    OrthancPluginAnswerBuffer(context, output, tmp.c_str(), tmp.size(), "application/json");
+  }
+}
+
+
 static bool DisplayPerformanceWarning(OrthancPluginContext* context)
 {
   (void) DisplayPerformanceWarning;   // Disable warning about unused function
@@ -380,6 +479,7 @@
         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);
       }
       else
       {