diff OrthancServer/ServerJobs/DicomModalityStoreJob.cpp @ 3734:4fc24b69446a storage-commitment

triggering storage commitment scu from REST API
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 10 Mar 2020 13:22:02 +0100
parents 2a170a8f1faf
children 77183afbf55e
line wrap: on
line diff
--- a/OrthancServer/ServerJobs/DicomModalityStoreJob.cpp	Mon Mar 09 17:19:45 2020 +0100
+++ b/OrthancServer/ServerJobs/DicomModalityStoreJob.cpp	Tue Mar 10 13:22:02 2020 +0100
@@ -72,14 +72,39 @@
       LOG(WARNING) << "An instance was removed after the job was issued: " << instance;
       return false;
     }
+    
+    std::string sopClassUid, sopInstanceUid;
 
     if (HasMoveOriginator())
     {
-      connection_->Store(dicom, moveOriginatorAet_, moveOriginatorId_);
+      connection_->Store(sopClassUid, sopInstanceUid, dicom, moveOriginatorAet_, moveOriginatorId_);
     }
     else
     {
-      connection_->Store(dicom);
+      connection_->Store(sopClassUid, sopInstanceUid, dicom);
+    }
+
+    if (storageCommitment_)
+    {
+      sopClassUids_.push_back(sopClassUid);
+      sopInstanceUids_.push_back(sopInstanceUid);
+
+      if (sopClassUids_.size() != sopInstanceUids_.size() ||
+          sopClassUids_.size() > GetInstancesCount())
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+      
+      if (sopClassUids_.size() == GetInstancesCount())
+      {      
+        LOG(INFO) << "Sending storage commitment request to modality: "
+                  << remote_.GetApplicationEntityTitle();
+        
+        assert(IsStarted());
+        OpenConnection();
+        
+        connection_->RequestStorageCommitment(transactionUid_, sopClassUids_, sopInstanceUids_);
+      }
     }
 
     //boost::this_thread::sleep(boost::posix_time::milliseconds(500));
@@ -97,7 +122,8 @@
   DicomModalityStoreJob::DicomModalityStoreJob(ServerContext& context) :
     context_(context),
     localAet_("ORTHANC"),
-    moveOriginatorId_(0)  // By default, not a C-MOVE
+    moveOriginatorId_(0),      // By default, not a C-MOVE
+    storageCommitment_(false)  // By default, no storage commitment
   {
   }
 
@@ -179,6 +205,44 @@
   }
 
 
+  void DicomModalityStoreJob::ResetStorageCommitment()
+  {
+    if (storageCommitment_)
+    {
+      transactionUid_ = Toolbox::GenerateDicomPrivateUniqueIdentifier();
+      sopClassUids_.reserve(GetInstancesCount());
+      sopInstanceUids_.reserve(GetInstancesCount());
+    }
+  }
+  
+
+  void DicomModalityStoreJob::Start()
+  {
+    SetOfInstancesJob::Start();
+    ResetStorageCommitment();
+  }
+
+
+  void DicomModalityStoreJob::Reset()
+  {
+    SetOfInstancesJob::Reset();
+
+    /**
+     * "After the N-EVENT-REPORT has been sent, the Transaction UID is
+     * no longer active and shall not be reused for other
+     * transactions." => Need to reset the transaction UID here
+     * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.3.html
+     **/
+    ResetStorageCommitment();
+  }
+  
+
+  void DicomModalityStoreJob::EnableStorageCommitment(bool enabled)
+  {
+    storageCommitment_ = enabled;
+  }
+  
+
   void DicomModalityStoreJob::GetPublicContent(Json::Value& value)
   {
     SetOfInstancesJob::GetPublicContent(value);
@@ -191,6 +255,11 @@
       value["MoveOriginatorAET"] = GetMoveOriginatorAet();
       value["MoveOriginatorID"] = GetMoveOriginatorId();
     }
+
+    if (storageCommitment_)
+    {
+      value["StorageCommitmentTransactionUID"] = transactionUid_;
+    }
   }
 
 
@@ -198,6 +267,7 @@
   static const char* REMOTE = "Remote";
   static const char* MOVE_ORIGINATOR_AET = "MoveOriginatorAet";
   static const char* MOVE_ORIGINATOR_ID = "MoveOriginatorId";
+  static const char* STORAGE_COMMITMENT = "StorageCommitment";
   
 
   DicomModalityStoreJob::DicomModalityStoreJob(ServerContext& context,
@@ -210,6 +280,7 @@
     moveOriginatorAet_ = SerializationToolbox::ReadString(serialized, MOVE_ORIGINATOR_AET);
     moveOriginatorId_ = static_cast<uint16_t>
       (SerializationToolbox::ReadUnsignedInteger(serialized, MOVE_ORIGINATOR_ID));
+    EnableStorageCommitment(SerializationToolbox::ReadBoolean(serialized, STORAGE_COMMITMENT));
   }
 
 
@@ -225,6 +296,7 @@
       remote_.Serialize(target[REMOTE], true /* force advanced format */);
       target[MOVE_ORIGINATOR_AET] = moveOriginatorAet_;
       target[MOVE_ORIGINATOR_ID] = moveOriginatorId_;
+      target[STORAGE_COMMITMENT] = storageCommitment_;
       return true;
     }
   }