# HG changeset patch # User Sebastien Jodogne # Date 1583870020 -3600 # Node ID bff4da769f6f5975aa568f9e4ecf7f67a4da2d05 # Parent f29843323daf952cea764a9b777d16559411c968 new route: "/storage-commitment/{...}/remove" diff -r f29843323daf -r bff4da769f6f NEWS --- a/NEWS Tue Mar 10 20:33:01 2020 +0100 +++ b/NEWS Tue Mar 10 20:53:40 2020 +0100 @@ -10,17 +10,20 @@ -------- * API version has been upgraded to 5 -* Added "/peers/{id}/system" route to test the connectivity with a remote peer (and eventually - retrieve its version number) -* "/changes": Allow the "limit" argument to be greater than 100 -* "/instances/{id}/preview": Now takes the windowing into account -* "/tools/log-level": Possibility to access and change the log level without restarting Orthanc -* Added "/instances/{id}/frames/{frame}/rendered" and "/instances/{id}/rendered" routes - to render frames, taking windowing and resizing into account -* "/instances": Support "Content-Encoding: gzip" to upload gzip-compressed DICOM files -* ".../modify" and "/tools/create-dicom": New option "PrivateCreator" for private tags -* Added "/modalities/{...}/storage-commitment" route -* "/modalities/{...}/store" now accepts the Boolean argument "StorageCommitment" +* Added: + - "/peers/{id}/system": Test the connectivity with a remote peer + (and also retrieve its version number) + - "/tools/log-level": Access and/or change the log level without restarting Orthanc + - "/instances/{id}/frames/{frame}/rendered" and "/instances/{id}/rendered": + Render frames, taking windowing and resizing into account + - "/modalities/{...}/storage-commitment": Trigger storage commitment SCU + - "/storage-commitment/{...}": Access storage commitment reports + - "/storage-commitment/{...}/remove": Remove instances from storage commitment reports +* Improved: + - "/changes": Allow the "limit" argument to be greater than 100 + - "/instances": Support "Content-Encoding: gzip" to upload gzip-compressed DICOM files + - ".../modify" and "/tools/create-dicom": New option "PrivateCreator" for private tags + - "/modalities/{...}/store": New Boolean argument "StorageCommitment" Plugins ------- diff -r f29843323daf -r bff4da769f6f OrthancServer/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Tue Mar 10 20:33:01 2020 +0100 +++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Tue Mar 10 20:53:40 2020 +0100 @@ -1423,6 +1423,54 @@ } + static void RemoveAfterStorageCommitment(RestApiPostCall& call) + { + ServerContext& context = OrthancRestApi::GetContext(call); + + const std::string& transactionUid = call.GetUriComponent("id", ""); + + { + StorageCommitmentReports::Accessor accessor( + context.GetStorageCommitmentReports(), transactionUid); + + if (!accessor.IsValid()) + { + throw OrthancException(ErrorCode_InexistentItem, + "No storage commitment transaction with UID: " + transactionUid); + } + else if (accessor.GetReport().GetStatus() != StorageCommitmentReports::Report::Status_Success) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls, + "Cannot remove DICOM instances after failure " + "in storage commitment transaction: " + transactionUid); + } + else + { + std::vector sopInstanceUids; + accessor.GetReport().GetSuccessSopInstanceUids(sopInstanceUids); + + for (size_t i = 0; i < sopInstanceUids.size(); i++) + { + std::vector orthancId; + context.GetIndex().LookupIdentifierExact( + orthancId, ResourceType_Instance, DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUids[i]); + + for (size_t j = 0; j < orthancId.size(); j++) + { + LOG(INFO) << "Storage commitment - Removing SOP instance UID / Orthanc ID: " + << sopInstanceUids[i] << " / " << orthancId[j]; + + Json::Value tmp; + context.GetIndex().DeleteResource(tmp, orthancId[j], ResourceType_Instance); + } + } + + call.GetOutput().AnswerBuffer("{}", MimeType_Json); + } + } + } + + void OrthancRestApi::RegisterModalities() { Register("/modalities", ListModalities); @@ -1467,7 +1515,9 @@ Register("/modalities/{id}/find-worklist", DicomFindWorklist); + // Storage commitment Register("/modalities/{id}/storage-commitment", StorageCommitmentScu); Register("/storage-commitment/{id}", GetStorageCommitmentReport); + Register("/storage-commitment/{id}/remove", RemoveAfterStorageCommitment); } } diff -r f29843323daf -r bff4da769f6f OrthancServer/StorageCommitmentReports.cpp --- a/OrthancServer/StorageCommitmentReports.cpp Tue Mar 10 20:33:01 2020 +0100 +++ b/OrthancServer/StorageCommitmentReports.cpp Tue Mar 10 20:53:40 2020 +0100 @@ -167,6 +167,20 @@ } + void StorageCommitmentReports::Report::GetSuccessSopInstanceUids( + std::vector& target) const + { + target.clear(); + target.reserve(success_.size()); + + for (std::list::const_iterator + it = success_.begin(); it != success_.end(); ++it) + { + target.push_back(it->sopInstanceUid_); + } + } + + StorageCommitmentReports::~StorageCommitmentReports() { while (!content_.IsEmpty()) diff -r f29843323daf -r bff4da769f6f OrthancServer/StorageCommitmentReports.h --- a/OrthancServer/StorageCommitmentReports.h Tue Mar 10 20:33:01 2020 +0100 +++ b/OrthancServer/StorageCommitmentReports.h Tue Mar 10 20:53:40 2020 +0100 @@ -93,6 +93,8 @@ Status GetStatus() const; void Format(Json::Value& json) const; + + void GetSuccessSopInstanceUids(std::vector& target) const; }; private: