changeset 305:ec6231689d89 refactoring

New URI: /dicom-web/servers/.../delete
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 18 Jun 2019 11:45:18 +0200
parents fb455aa44112
children 4a0b759019ac
files NEWS Plugin/Configuration.cpp Plugin/Configuration.h Plugin/DicomWebClient.cpp Plugin/Plugin.cpp
diffstat 5 files changed, 151 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue Jun 18 09:51:47 2019 +0200
+++ b/NEWS	Tue Jun 18 11:45:18 2019 +0200
@@ -5,6 +5,7 @@
   (provided the SDK version is above 1.5.7)
 * Handling of the HTTP header "Forwarded" for WADO-RS
 * New URI: /dicom-web/servers/.../qido
+* New URI: /dicom-web/servers/.../delete
 
 
 Version 0.6 (2019-02-27)
--- a/Plugin/Configuration.cpp	Tue Jun 18 09:51:47 2019 +0200
+++ b/Plugin/Configuration.cpp	Tue Jun 18 11:45:18 2019 +0200
@@ -317,6 +317,19 @@
   }
 
 
+  void ParseJsonBody(Json::Value& target,
+                     const OrthancPluginHttpRequest* request)
+  {
+    Json::Reader reader;
+    if (!reader.parse(reinterpret_cast<const char*>(request->body),
+                      reinterpret_cast<const char*>(request->body) + request->bodySize, target))
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
+                                      "A JSON file was expected");
+    }
+  }
+
+
   namespace Configuration
   {
     // Assume Latin-1 encoding by default (as in the Orthanc core)
--- a/Plugin/Configuration.h	Tue Jun 18 09:51:47 2019 +0200
+++ b/Plugin/Configuration.h	Tue Jun 18 11:45:18 2019 +0200
@@ -76,6 +76,9 @@
   bool ParseTag(Orthanc::DicomTag& target,
                 const std::string& name);
 
+  void ParseJsonBody(Json::Value& target,
+                     const OrthancPluginHttpRequest* request);
+
   namespace Configuration
   {
     void Initialize();
--- a/Plugin/DicomWebClient.cpp	Tue Jun 18 09:51:47 2019 +0200
+++ b/Plugin/DicomWebClient.cpp	Tue Jun 18 11:45:18 2019 +0200
@@ -159,10 +159,9 @@
   static const char* HTTP_HEADERS = "HttpHeaders";
 
   Json::Value body;
-  Json::Reader reader;
-  if (!reader.parse(reinterpret_cast<const char*>(request->body),
-                    reinterpret_cast<const char*>(request->body) + request->bodySize, body) ||
-      body.type() != Json::objectValue ||
+  OrthancPlugins::ParseJsonBody(body, request);
+
+  if (body.type() != Json::objectValue ||
       !body.isMember(RESOURCES) ||
       body[RESOURCES].type() != Json::arrayValue)
   {
@@ -671,12 +670,11 @@
     throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
   }
 
+  Json::Value body;
+  OrthancPlugins::ParseJsonBody(body, request);
+
   std::string tmp;
-  Json::Value body;
-  Json::Reader reader;
-  if (!reader.parse(reinterpret_cast<const char*>(request->body),
-                    reinterpret_cast<const char*>(request->body) + request->bodySize, body) ||
-      body.type() != Json::objectValue ||
+  if (body.type() != Json::objectValue ||
       !GetStringValue(tmp, body, URI))
   {
     throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
@@ -977,10 +975,9 @@
   Orthanc::WebServiceParameters server(OrthancPlugins::DicomWebServers::GetInstance().GetServer(request->groups[0]));
 
   Json::Value body;
-  Json::Reader reader;
-  if (!reader.parse(reinterpret_cast<const char*>(request->body),
-                    reinterpret_cast<const char*>(request->body) + request->bodySize, body) ||
-      body.type() != Json::objectValue ||
+  OrthancPlugins::ParseJsonBody(body, request);
+
+  if (body.type() != Json::objectValue ||
       !body.isMember(RESOURCES) ||
       body[RESOURCES].type() != Json::arrayValue)
   {
--- a/Plugin/Plugin.cpp	Tue Jun 18 09:51:47 2019 +0200
+++ b/Plugin/Plugin.cpp	Tue Jun 18 11:45:18 2019 +0200
@@ -97,7 +97,8 @@
     case OrthancPluginHttpMethod_Get:
     {
       // Make sure the server does exist
-      OrthancPlugins::DicomWebServers::GetInstance().GetServer(request->groups[0]);
+      const Orthanc::WebServiceParameters& server = 
+        OrthancPlugins::DicomWebServers::GetInstance().GetServer(request->groups[0]);
 
       Json::Value json = Json::arrayValue;
       json.append("get");
@@ -105,6 +106,13 @@
       json.append("stow");
       json.append("qido");
 
+      std::string value;
+      if (server.LookupUserProperty(value, "HasDelete") &&
+          value == "1")
+      {
+        json.append("delete");
+      }
+
       std::string answer = json.toStyledString(); 
       OrthancPluginAnswerBuffer(context, output, answer.c_str(), answer.size(), "application/json");
       break;
@@ -121,12 +129,7 @@
     case OrthancPluginHttpMethod_Put:
     {
       Json::Value body;
-      Json::Reader reader;
-      if (!reader.parse(reinterpret_cast<const char*>(request->body),
-                        reinterpret_cast<const char*>(request->body) + request->bodySize, body))
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-      }
+      OrthancPlugins::ParseJsonBody(body, request);
       
       Orthanc::WebServiceParameters parameters(body);
       
@@ -243,6 +246,119 @@
 }
 
 
+void DeleteClient(OrthancPluginRestOutput* output,
+                const char* /*url*/,
+                const OrthancPluginHttpRequest* request)
+{
+  OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
+
+  if (request->method != OrthancPluginHttpMethod_Post)
+  {
+    OrthancPluginSendMethodNotAllowed(context, output, "POST");
+  }
+  else
+  {
+    static const char* const LEVEL = "Level";
+    static const char* const HAS_DELETE = "HasDelete";
+    static const char* const SERIES_INSTANCE_UID = "SeriesInstanceUID";
+    static const char* const STUDY_INSTANCE_UID = "StudyInstanceUID";
+    static const char* const SOP_INSTANCE_UID = "SOPInstanceUID";
+
+    const std::string serverName = request->groups[0];
+
+    const Orthanc::WebServiceParameters& server = 
+      OrthancPlugins::DicomWebServers::GetInstance().GetServer(serverName);
+
+    std::string value;
+    if (server.LookupUserProperty(value, HAS_DELETE) &&
+        value != "1")
+    {
+      throw Orthanc::OrthancException(
+        Orthanc::ErrorCode_BadFileFormat,
+        "Cannot delete on DICOMweb server, check out property \"HasDelete\": " + serverName);
+    }
+
+    Json::Value body;
+    OrthancPlugins::ParseJsonBody(body, request);
+
+    if (body.type() != Json::objectValue ||
+        !body.isMember(LEVEL) ||
+        !body.isMember(STUDY_INSTANCE_UID) ||
+        body[LEVEL].type() != Json::stringValue ||
+        body[STUDY_INSTANCE_UID].type() != Json::stringValue)
+    {
+      throw Orthanc::OrthancException(
+        Orthanc::ErrorCode_BadFileFormat,
+        "The request body must contain a JSON object with fields \"Level\" and \"StudyInstanceUID\"");
+    }
+
+    Orthanc::ResourceType level = Orthanc::StringToResourceType(body[LEVEL].asCString());
+
+    const std::string study = body[STUDY_INSTANCE_UID].asString();
+
+    std::string series;    
+    if (level == Orthanc::ResourceType_Series ||
+        level == Orthanc::ResourceType_Instance)
+    {
+      if (!body.isMember(SERIES_INSTANCE_UID) ||
+          body[SERIES_INSTANCE_UID].type() != Json::stringValue)
+      {
+        throw Orthanc::OrthancException(
+          Orthanc::ErrorCode_BadFileFormat,
+          "The request body must contain the field \"SeriesInstanceUID\"");
+      }
+      else
+      {
+        series = body[SERIES_INSTANCE_UID].asString();
+      }
+    }
+
+    std::string instance;    
+    if (level == Orthanc::ResourceType_Instance)
+    {
+      if (!body.isMember(SOP_INSTANCE_UID) ||
+          body[SOP_INSTANCE_UID].type() != Json::stringValue)
+      {
+        throw Orthanc::OrthancException(
+          Orthanc::ErrorCode_BadFileFormat,
+          "The request body must contain the field \"SOPInstanceUID\"");
+      }
+      else
+      {
+        instance = body[SOP_INSTANCE_UID].asString();
+      }
+    }
+
+    std::string uri;
+    switch (level)
+    {
+      case Orthanc::ResourceType_Study:
+        uri = "/studies/" + study;
+        break;
+
+      case Orthanc::ResourceType_Series:
+        uri = "/studies/" + study + "/series/" + series;
+        break;
+
+      case Orthanc::ResourceType_Instance:
+        uri = "/studies/" + study + "/series/" + series + "/instances/" + instance;
+        break;
+
+      default:
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
+    }
+
+    OrthancPlugins::HttpClient client;
+    OrthancPlugins::DicomWebServers::GetInstance().ConfigureHttpClient(client, serverName, uri);
+    client.SetMethod(OrthancPluginHttpMethod_Delete);
+    client.Execute();
+
+    std::string tmp = "{}";
+    OrthancPluginAnswerBuffer(context, output, tmp.c_str(), tmp.size(), "application/json");
+  }
+}
+
+
 static bool DisplayPerformanceWarning(OrthancPluginContext* context)
 {
   (void) DisplayPerformanceWarning;   // Disable warning about unused function
@@ -482,6 +598,7 @@
         OrthancPlugins::RegisterRestCallback<GetFromServer>(root + "servers/([^/]*)/get", true);
         OrthancPlugins::RegisterRestCallback<RetrieveFromServer>(root + "servers/([^/]*)/retrieve", true);
         OrthancPlugins::RegisterRestCallback<QidoClient>(root + "servers/([^/]*)/qido", true);
+        OrthancPlugins::RegisterRestCallback<DeleteClient>(root + "servers/([^/]*)/delete", true);
       }
       else
       {