changeset 5310:b5c502bcaf99

added a route to DELETE /jobs/../archive
author Alain Mazy <am@osimis.io>
date Mon, 12 Jun 2023 18:42:06 +0200
parents fb231da5c0f1
children 79fa77e9fa0d b43a3f0b57b2
files NEWS OrthancFramework/Sources/Cache/SharedArchive.cpp OrthancFramework/Sources/Cache/SharedArchive.h OrthancFramework/Sources/JobsEngine/IJob.h OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp OrthancFramework/Sources/JobsEngine/JobsRegistry.h OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h OrthancFramework/UnitTestsSources/JobsTests.cpp OrthancServer/Plugins/Engine/PluginsJob.h OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp OrthancServer/Sources/ServerJobs/ArchiveJob.cpp OrthancServer/Sources/ServerJobs/ArchiveJob.h OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.cpp OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.h OrthancServer/UnitTestsSources/ServerJobsTests.cpp
diffstat 18 files changed, 148 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Jun 07 10:48:14 2023 +0200
+++ b/NEWS	Mon Jun 12 18:42:06 2023 +0200
@@ -1,6 +1,13 @@
 Pending changes in the mainline
 ===============================
 
+REST API
+--------
+
+* API version upgraded to 21
+* added a route to delete the output of an asynchronous job (right now only for archive jobs):
+  e.g. DELETE /jobs/../archive
+
 Maintenance
 -----------
 
--- a/OrthancFramework/Sources/Cache/SharedArchive.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/Cache/SharedArchive.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -102,7 +102,7 @@
 
   std::string SharedArchive::Add(IDynamicObject* obj)
   {
-    boost::mutex::scoped_lock lock(mutex_);
+    boost::recursive_mutex::scoped_lock lock(mutex_);
 
     if (archive_.size() == maxSize_)
     {
@@ -122,7 +122,7 @@
 
   void SharedArchive::Remove(const std::string& id)
   {
-    boost::mutex::scoped_lock lock(mutex_);
+    boost::recursive_mutex::scoped_lock lock(mutex_);
     RemoveInternal(id);      
   }
 
@@ -132,7 +132,7 @@
     items.clear();
 
     {
-      boost::mutex::scoped_lock lock(mutex_);
+      boost::recursive_mutex::scoped_lock lock(mutex_);
 
       for (Archive::const_iterator it = archive_.begin();
            it != archive_.end(); ++it)
--- a/OrthancFramework/Sources/Cache/SharedArchive.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/Cache/SharedArchive.h	Mon Jun 12 18:42:06 2023 +0200
@@ -44,9 +44,9 @@
   private:
     typedef std::map<std::string, IDynamicObject*>  Archive;
 
-    size_t         maxSize_;
-    boost::mutex   mutex_;
-    Archive        archive_;
+    size_t                  maxSize_;
+    boost::recursive_mutex  mutex_;
+    Archive                 archive_;
     LeastRecentlyUsedIndex<std::string> lru_;
 
     void RemoveInternal(const std::string& id);
@@ -55,8 +55,8 @@
     class ORTHANC_PUBLIC Accessor : public boost::noncopyable
     {
     private:
-      boost::mutex::scoped_lock  lock_;
-      IDynamicObject*            item_;
+      boost::recursive_mutex::scoped_lock lock_;
+      IDynamicObject*                     item_;
 
     public:
       Accessor(SharedArchive& that,
--- a/OrthancFramework/Sources/JobsEngine/IJob.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/IJob.h	Mon Jun 12 18:42:06 2023 +0200
@@ -62,5 +62,9 @@
                            MimeType& mime,
                            std::string& filename,
                            const std::string& key) = 0;
+
+    // This function can only be called if the job has reached its
+    // "success" state
+    virtual bool DeleteOutput(const std::string& key) = 0;
   };
 }
--- a/OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -679,6 +679,33 @@
     }
   }
 
+  bool JobsRegistry::DeleteJobOutput(const std::string& job,
+                                     const std::string& key)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+    CheckInvariants();
+
+    JobsIndex::const_iterator found = jobsIndex_.find(job);
+
+    if (found == jobsIndex_.end())
+    {
+      return false;
+    }
+    else
+    {
+      const JobHandler& handler = *found->second;
+
+      if (handler.GetState() == JobState_Success)
+      {
+        return handler.GetJob().DeleteOutput(key);
+      }
+      else
+      {
+        return false;
+      }
+    }
+  }
+
 
   void JobsRegistry::SubmitInternal(std::string& id,
                                     JobHandler* handler)
--- a/OrthancFramework/Sources/JobsEngine/JobsRegistry.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobsRegistry.h	Mon Jun 12 18:42:06 2023 +0200
@@ -153,6 +153,9 @@
                       const std::string& job,
                       const std::string& key);
 
+    bool DeleteJobOutput(const std::string& job,
+                         const std::string& key);
+
     void Serialize(Json::Value& target);
 
     void Submit(std::string& id,
--- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -447,13 +447,6 @@
     return true;
   }
 
-  bool SequenceOfOperationsJob::GetOutput(std::string& output,
-                                          MimeType& mime,
-                                          std::string& filename,
-                                          const std::string& key)
-  {
-    return false;
-  }
 
   void SequenceOfOperationsJob::AwakeTrailingSleep()
   {
--- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h	Mon Jun 12 18:42:06 2023 +0200
@@ -127,7 +127,15 @@
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
                            std::string& filename,
-                           const std::string& key) ORTHANC_OVERRIDE;
+                           const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
 
     void AwakeTrailingSleep();
   };
--- a/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -269,14 +269,6 @@
     return true;
   }
 
-  bool SetOfCommandsJob::GetOutput(std::string &output,
-                                   MimeType &mime,
-                                   std::string& filename,
-                                   const std::string &key)
-  {
-    return false;
-  }
-
 
   SetOfCommandsJob::SetOfCommandsJob(ICommandUnserializer* unserializer,
                                      const Json::Value& source) :
--- a/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h	Mon Jun 12 18:42:06 2023 +0200
@@ -106,6 +106,14 @@
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
                            std::string& filename,
-                           const std::string& key) ORTHANC_OVERRIDE;
+                           const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };
 }
--- a/OrthancFramework/UnitTestsSources/JobsTests.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancFramework/UnitTestsSources/JobsTests.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -131,6 +131,11 @@
     {
       return false;
     }
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };
 
 
--- a/OrthancServer/Plugins/Engine/PluginsJob.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsJob.h	Mon Jun 12 18:42:06 2023 +0200
@@ -76,6 +76,12 @@
       // TODO
       return false;
     }
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE
+    {
+      // TODO
+      return false;
+    }
   };
 }
 
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -770,6 +770,36 @@
   }
 
 
+  static void DeleteJobOutput(RestApiDeleteCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      call.GetDocumentation()
+        .SetTag("Jobs")
+        .SetSummary("Delete a job output")
+        .SetDescription("Delete the output produced by a job. As of Orthanc 1.12.1, only the jobs that generate a "
+                        "DICOMDIR media or a ZIP archive provide such an output (with `key` equals to `archive`).")
+        .SetUriArgument("id", "Identifier of the job of interest")
+        .SetUriArgument("key", "Name of the output of interest");
+      return;
+    }
+
+    std::string job = call.GetUriComponent("id", "");
+    std::string key = call.GetUriComponent("key", "");
+
+    if (OrthancRestApi::GetContext(call).GetJobsEngine().
+        GetRegistry().DeleteJobOutput(job, key))
+    {
+      call.GetOutput().AnswerBuffer("", MimeType_PlainText);
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_InexistentItem,
+                             "Job has no such output: " + key);
+    }
+  }
+
+
   enum JobAction
   {
     JobAction_Cancel,
@@ -1113,6 +1143,7 @@
     Register("/jobs/{id}/resubmit", ApplyJobAction<JobAction_Resubmit>);
     Register("/jobs/{id}/resume", ApplyJobAction<JobAction_Resume>);
     Register("/jobs/{id}/{key}", GetJobOutput);
+    Register("/jobs/{id}/{key}", DeleteJobOutput);
 
     // New in Orthanc 1.9.0
     Register("/tools/accepted-transfer-syntaxes", GetAcceptedTransferSyntaxes);
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -1459,4 +1459,27 @@
       return false;
     }
   }
+
+  bool ArchiveJob::DeleteOutput(const std::string& key)
+  {   
+    if (key == "archive" &&
+        !mediaArchiveId_.empty())
+    {
+      SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_);
+
+      if (accessor.IsValid())
+      {
+        context_.GetMediaArchive().Remove(mediaArchiveId_);
+        return true;
+      }
+      else
+      {
+        return false;
+      }
+    }    
+    else
+    {
+      return false;
+    }
+  }
 }
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.h	Mon Jun 12 18:42:06 2023 +0200
@@ -120,5 +120,7 @@
                            MimeType& mime,
                            std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE;
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE;
   };
 }
--- a/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -295,15 +295,6 @@
   }
 
 
-  bool ThreadedSetOfInstancesJob::GetOutput(std::string &output,
-                                            MimeType &mime,
-                                            std::string& filename,
-                                            const std::string &key)
-  {
-    return false;
-  }
-
-
   size_t ThreadedSetOfInstancesJob::GetInstancesCount() const
   {
     boost::recursive_mutex::scoped_lock lock(mutex_);
--- a/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.h	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.h	Mon Jun 12 18:42:06 2023 +0200
@@ -152,7 +152,15 @@
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
                            std::string& filename,
-                           const std::string& key) ORTHANC_OVERRIDE;
+                           const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
 
     bool IsFailedInstance(const std::string& instance) const;
 
--- a/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Wed Jun 07 10:48:14 2023 +0200
+++ b/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Mon Jun 12 18:42:06 2023 +0200
@@ -134,6 +134,11 @@
     {
       return false;
     }
+
+    virtual bool DeleteOutput(const std::string& key) ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };