changeset 973:2d817288cad4

added python storage commitment
author Alain Mazy <am@osimis.io>
date Mon, 28 Aug 2023 18:45:57 +0200
parents e72f8d52d94b
children 01f61385877f
files Sphinx/source/plugins/python.rst Sphinx/source/plugins/python/storage-commitment-default.py
diffstat 2 files changed, 48 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Sphinx/source/plugins/python.rst	Thu Aug 24 12:57:46 2023 +0200
+++ b/Sphinx/source/plugins/python.rst	Mon Aug 28 18:45:57 2023 +0200
@@ -642,7 +642,7 @@
 to handle HL7 such as `python-hl7 library
 <https://python-hl7.readthedocs.io/en/latest/>`__.
 
-The following Python script reproduces features similar to the
+The following Python script reproduces features similar to the 
 :ref:`sample modality worklists plugin <worklists-plugin>`:
 
 .. literalinclude:: python/worklist.py
@@ -800,6 +800,19 @@
                     :language: python
 
 
+Storage Commitment SCP (new in 4.1)
+...................................
+
+Starting with release 4.1 of the Python plugin, it is possible to
+provide your own implementation of the :ref:`Storage Commitment <storage-commitment>`.
+
+This can be used, e.g, to check that you have backup the orthanc data in a
+long term storage.
+
+.. literalinclude:: python/storage-commitment-default.py
+                    :language: python
+
+
 Performance and concurrency
 ---------------------------
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sphinx/source/plugins/python/storage-commitment-default.py	Mon Aug 28 18:45:57 2023 +0200
@@ -0,0 +1,34 @@
+import orthanc
+import json
+
+# this plugins provides the same behavior as the default Orthanc implementation
+
+def StorageCommitmentScpCallback(jobId, transactionUid, sopClassUids, sopInstanceUids, remoteAet, calledAet):
+    # At the beginning of a Storage Commitment operation, you can build a custom data structure
+    # that will be provided as the "data" argument in the StorageCommitmentLookup
+    return None
+
+
+# Reference: `StorageCommitmentScpJob::Lookup` in `OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp`
+def StorageCommitmentLookup(sopClassUid, sopInstanceUid, data):
+    success = False
+    reason = orthanc.StorageCommitmentFailureReason.NO_SUCH_OBJECT_INSTANCE
+
+    result = json.loads(orthanc.RestApiPost("/tools/lookup", sopInstanceUid))
+    if len(result) == 1:
+        tags = json.loads(orthanc.RestApiGet(result[0]["Path"] + "/simplified-tags"))
+        if all(tag in tags for tag in ["SOPClassUID", "SOPInstanceUID"]) and \
+            tags["SOPInstanceUID"] == sopInstanceUid:
+            if tags["SOPClassUID"] == sopClassUid:
+                success = True
+                reason = orthanc.StorageCommitmentFailureReason.SUCCESS
+            else:
+                # Mismatch in the SOP class UID
+                reason = orthanc.StorageCommitmentFailureReason.CLASS_INSTANCE_CONFLICT
+
+    orthanc.LogInfo("  Storage commitment SCP job: " + ("Success" if success else "Failure") + \
+                    " while looking for " + sopClassUid + " / " + sopInstanceUid)
+
+    return reason
+
+orthanc.RegisterStorageCommitmentScpCallback(StorageCommitmentScpCallback, StorageCommitmentLookup)
\ No newline at end of file