changeset 4919:676e03e69703

added origin in OrthancPluginReceivedInstanceCallback
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 23 Feb 2022 09:30:42 +0100
parents 95378de340d4
children ce64d8995a41
files OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/OrthancPlugins.h OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp OrthancServer/Sources/ServerContext.cpp
diffstat 5 files changed, 74 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Wed Feb 23 06:36:29 2022 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Wed Feb 23 09:30:42 2022 +0100
@@ -398,6 +398,8 @@
         std::unique_ptr<MallocMemoryBuffer> result(new MallocMemoryBuffer);
 
         OrthancPluginMemoryBuffer64 buffer;
+        buffer.size = 0;
+        buffer.data = NULL;
         
         OrthancPluginErrorCode error = readWhole_(&buffer, uuid.c_str(), Plugins::Convert(type));
 
@@ -1714,6 +1716,7 @@
         sizeof(int32_t) != sizeof(OrthancPluginMetricsType) ||
         sizeof(int32_t) != sizeof(OrthancPluginDicomWebBinaryMode) ||
         sizeof(int32_t) != sizeof(OrthancPluginStorageCommitmentFailureReason) ||
+        sizeof(int32_t) != sizeof(OrthancPluginReceivedInstanceAction) ||
         static_cast<int>(OrthancPluginDicomToJsonFlags_IncludeBinary) != static_cast<int>(DicomToJsonFlags_IncludeBinary) ||
         static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePrivateTags) != static_cast<int>(DicomToJsonFlags_IncludePrivateTags) ||
         static_cast<int>(OrthancPluginDicomToJsonFlags_IncludeUnknownTags) != static_cast<int>(DicomToJsonFlags_IncludeUnknownTags) ||
@@ -2285,28 +2288,32 @@
   }
 
 
-  OrthancPluginReceivedInstanceCallbackResult OrthancPlugins::ApplyReceivedInstanceCallbacks(
+  OrthancPluginReceivedInstanceAction OrthancPlugins::ApplyReceivedInstanceCallbacks(
     MallocMemoryBuffer& modified,
     const void* receivedDicom,
-    size_t receivedDicomSize)
+    size_t receivedDicomSize,
+    RequestOrigin origin)
   {
     boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_);
 
     if (pimpl_->receivedInstanceCallback_ == NULL)
     {
-      return OrthancPluginReceivedInstanceCallbackResult_KeepAsIs;
+      return OrthancPluginReceivedInstanceAction_KeepAsIs;
     }
     else
     {
-      OrthancPluginReceivedInstanceCallbackResult callbackResult;
+      OrthancPluginReceivedInstanceAction action;
       
       {
         OrthancPluginMemoryBuffer64 buffer;
-        callbackResult = (*pimpl_->receivedInstanceCallback_) (&buffer, receivedDicom, receivedDicomSize);
+        buffer.size = 0;
+        buffer.data = NULL;
+
+        action = (*pimpl_->receivedInstanceCallback_) (&buffer, receivedDicom, receivedDicomSize, Plugins::Convert(origin));
         modified.Assign(buffer.data, buffer.size, ::free);
       }
 
-      return callbackResult;
+      return action;
     }
   }
 
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h	Wed Feb 23 06:36:29 2022 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h	Wed Feb 23 09:30:42 2022 +0100
@@ -276,9 +276,10 @@
     virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
                                                   const Json::Value& simplified) ORTHANC_OVERRIDE;
 
-    OrthancPluginReceivedInstanceCallbackResult ApplyReceivedInstanceCallbacks(MallocMemoryBuffer& modified,
-                                                                               const void* receivedDicomBuffer,
-                                                                               size_t receivedDicomBufferSize);
+    OrthancPluginReceivedInstanceAction ApplyReceivedInstanceCallbacks(MallocMemoryBuffer& modified,
+                                                                       const void* receivedDicomBuffer,
+                                                                       size_t receivedDicomBufferSize,
+                                                                       RequestOrigin origin);
 
     bool HasStorageArea() const;
 
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Feb 23 06:36:29 2022 +0100
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Feb 23 09:30:42 2022 +0100
@@ -27,7 +27,7 @@
  *    - Possibly register a callback to refresh its metrics using OrthancPluginRegisterRefreshMetricsCallback().
  *    - Possibly register a callback to answer chunked HTTP transfers using ::OrthancPluginRegisterChunkedRestCallback().
  *    - Possibly register a callback for Storage Commitment SCP using ::OrthancPluginRegisterStorageCommitmentScpCallback().
- *    - Possibly register a callback to filter incoming DICOM instance using OrthancPluginRegisterIncomingDicomInstanceFilter().
+ *    - Possibly register a callback to keep/discard/modify incoming DICOM instances using OrthancPluginRegisterReceivedInstanceCallback().
  *    - Possibly register a custom transcoder for DICOM images using OrthancPluginRegisterTranscoderCallback().
  * -# <tt>void OrthancPluginFinalize()</tt>:
  *    This function is invoked by Orthanc during its shutdown. The plugin
@@ -1004,16 +1004,16 @@
 
 
   /**
-   * The return value of ReceivedInstanceCallback
+   * The action to be taken after ReceivedInstanceCallback is triggered
    **/
   typedef enum
   {
-    OrthancPluginReceivedInstanceCallbackResult_KeepAsIs = 1, /*!< Keep the instance as is */
-    OrthancPluginReceivedInstanceCallbackResult_Modify = 2,   /*!< Modify the instance */
-    OrthancPluginReceivedInstanceCallbackResult_Discard = 3,  /*!< Tell Orthanc to discard the instance */
-
-    _OrthancPluginReceivedInstanceCallbackResult_INTERNAL = 0x7fffffff
-  } OrthancPluginReceivedInstanceCallbackResult;
+    OrthancPluginReceivedInstanceAction_KeepAsIs = 1, /*!< Keep the instance as is */
+    OrthancPluginReceivedInstanceAction_Modify = 2,   /*!< Modify the instance */
+    OrthancPluginReceivedInstanceAction_Discard = 3,  /*!< Discard the instance */
+
+    _OrthancPluginReceivedInstanceAction_INTERNAL = 0x7fffffff
+  } OrthancPluginReceivedInstanceAction;
 
 
   /**
@@ -1856,7 +1856,8 @@
         sizeof(int32_t) != sizeof(OrthancPluginConstraintType) ||
         sizeof(int32_t) != sizeof(OrthancPluginMetricsType) ||
         sizeof(int32_t) != sizeof(OrthancPluginDicomWebBinaryMode) ||
-        sizeof(int32_t) != sizeof(OrthancPluginStorageCommitmentFailureReason))
+        sizeof(int32_t) != sizeof(OrthancPluginStorageCommitmentFailureReason) ||
+        sizeof(int32_t) != sizeof(OrthancPluginReceivedInstanceAction))
     {
       /* Mismatch in the size of the enumerations */
       return 0;
@@ -2119,7 +2120,7 @@
    * @warning Your callback function will be called synchronously with
    * the core of Orthanc. This implies that deadlocks might emerge if
    * you call other core primitives of Orthanc in your callback (such
-   * deadlocks are particular visible in the presence of other plugins
+   * deadlocks are particularly visible in the presence of other plugins
    * or Lua scripts). It is thus strongly advised to avoid any call to
    * the REST API of Orthanc in the callback. If you have to call
    * other primitives of Orthanc, you should make these calls in a
@@ -3297,7 +3298,7 @@
    * @warning Your callback function will be called synchronously with
    * the core of Orthanc. This implies that deadlocks might emerge if
    * you call other core primitives of Orthanc in your callback (such
-   * deadlocks are particular visible in the presence of other plugins
+   * deadlocks are particularly visible in the presence of other plugins
    * or Lua scripts). It is thus strongly advised to avoid any call to
    * the REST API of Orthanc in the callback. If you have to call
    * other primitives of Orthanc, you should make these calls in a
@@ -7755,7 +7756,7 @@
    * @warning Your callback function will be called synchronously with
    * the core of Orthanc. This implies that deadlocks might emerge if
    * you call other core primitives of Orthanc in your callback (such
-   * deadlocks are particular visible in the presence of other plugins
+   * deadlocks are particularly visible in the presence of other plugins
    * or Lua scripts). It is thus strongly advised to avoid any call to
    * the REST API of Orthanc in the callback. If you have to call
    * other primitives of Orthanc, you should make these calls in a
@@ -7766,6 +7767,7 @@
    * @param callback The callback.
    * @return 0 if success, other value if error.
    * @ingroup Callbacks
+   * @deprecated In new plugins, OrthancPluginRegisterReceivedInstanceCallback() should be used
    **/
   ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingDicomInstanceFilter(
     OrthancPluginContext*                     context,
@@ -7813,7 +7815,7 @@
    * @warning Your callback function will be called synchronously with
    * the core of Orthanc. This implies that deadlocks might emerge if
    * you call other core primitives of Orthanc in your callback (such
-   * deadlocks are particular visible in the presence of other plugins
+   * deadlocks are particularly visible in the presence of other plugins
    * or Lua scripts). It is thus strongly advised to avoid any call to
    * the REST API of Orthanc in the callback. If you have to call
    * other primitives of Orthanc, you should make these calls in a
@@ -7836,31 +7838,35 @@
   }
 
   /**
-   * @brief Callback to possibly modify a DICOM instance received
+   * @brief Callback to keep/discard/modify a DICOM instance received
    * by Orthanc from any source (C-STORE or REST API)
    *
    * Signature of a callback function that is triggered whenever
-   * Orthanc receives a new DICOM instance (through DICOM protocol or 
-   * REST API), and that answers a possibly modified version of the 
-   * DICOM that should be stored in Orthanc.  
-   *
-   * This callback is called immediately after reception: before 
-   * transcoding and before filtering (FilterIncomingInstance).
-   *
-   * @param receivedDicomBuffer A buffer containing the received DICOM (input).
+   * Orthanc receives a new DICOM instance (through DICOM protocol or
+   * REST API), and that specifies an action to be applied to this
+   * newly received instance. The instance can be kept as it is, can
+   * be modified by the plugin, or can be discarded.
+   *
+   * This callback is invoked immediately after reception, i.e. before
+   * transcoding and before filtering
+   * (cf. OrthancPluginRegisterIncomingDicomInstanceFilter()).
+   *
+   * @param modifiedDicomBuffer A buffer containing the modified DICOM (output)
+   * @param receivedDicomBuffer A buffer containing the received DICOM (input)
    * @param receivedDicomBufferSize The size of the received DICOM (input)
-   * @param modifiedDicomBuffer A buffer containing the modified DICOM (output).
+   * @param origin The origin of the DICOM instance (input)
    * This buffer will be freed by the Orthanc core and must have been allocated 
    * using OrthancPluginCreateMemoryBuffer64().
-   * @return OrthancPluginReceivedInstanceCallbackResult_KeepAsIs to accept the instance as is,
-   *         OrthancPluginReceivedInstanceCallbackResult_Modified to store the modified DICOM,
-   *         OrthancPluginReceivedInstanceCallbackResult_Discard to tell Orthanc to discard the instance.
+   * @return `OrthancPluginReceivedInstanceAction_KeepAsIs` to accept the instance as is,<br/>
+   *         `OrthancPluginReceivedInstanceAction_Modify` to store the modified DICOM contained in `modifiedDicomBuffer`,<br/>
+   *         `OrthancPluginReceivedInstanceAction_Discard` to tell Orthanc to discard the instance.
    * @ingroup Callback
    **/
-  typedef OrthancPluginReceivedInstanceCallbackResult (*OrthancPluginReceivedInstanceCallback) (
+  typedef OrthancPluginReceivedInstanceAction (*OrthancPluginReceivedInstanceCallback) (
     OrthancPluginMemoryBuffer64* modifiedDicomBuffer,
     const void* receivedDicomBuffer,
-    uint64_t receivedDicomBufferSize);
+    uint64_t receivedDicomBufferSize,
+    OrthancPluginInstanceOrigin origin);
 
 
   typedef struct
@@ -7869,14 +7875,13 @@
   } _OrthancPluginReceivedInstanceCallback;
 
   /**
-   * @brief Register a callback to possibly modify a DICOM instance received
-   * by Orthanc through any source (C-STORE or REST API)
-   *
+   * @brief Register a callback to keep/discard/modify a DICOM instance received
+   * by Orthanc from any source (C-STORE or REST API)
    *
    * @warning Your callback function will be called synchronously with
    * the core of Orthanc. This implies that deadlocks might emerge if
    * you call other core primitives of Orthanc in your callback (such
-   * deadlocks are particular visible in the presence of other plugins
+   * deadlocks are particularly visible in the presence of other plugins
    * or Lua scripts). It is thus strongly advised to avoid any call to
    * the REST API of Orthanc in the callback. If you have to call
    * other primitives of Orthanc, you should make these calls in a
--- a/OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp	Wed Feb 23 06:36:29 2022 +0100
+++ b/OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp	Wed Feb 23 09:30:42 2022 +0100
@@ -33,9 +33,10 @@
 
 
 
-OrthancPluginReceivedInstanceCallbackResult ReceivedInstanceCallback(OrthancPluginMemoryBuffer64* modifiedDicomBuffer,
-                                                                     const void* receivedDicomBuffer,
-                                                                     uint64_t receivedDicomBufferSize)
+OrthancPluginReceivedInstanceAction ReceivedInstanceCallback(OrthancPluginMemoryBuffer64* modifiedDicomBuffer,
+                                                             const void* receivedDicomBuffer,
+                                                             uint64_t receivedDicomBufferSize,
+                                                             OrthancPluginInstanceOrigin origin)
 {
   Orthanc::ParsedDicomFile dicom(receivedDicomBuffer, receivedDicomBufferSize);
   std::string institutionName = "My institution";
@@ -48,7 +49,7 @@
   OrthancPluginCreateMemoryBuffer64(OrthancPlugins::GetGlobalContext(), modifiedDicomBuffer, modifiedDicom.size());
   memcpy(modifiedDicomBuffer->data, modifiedDicom.c_str(), modifiedDicom.size());
   
-  return OrthancPluginReceivedInstanceCallbackResult_Modify;
+  return OrthancPluginReceivedInstanceAction_Modify;
 }
 
 
@@ -61,14 +62,14 @@
     Orthanc::InitializeFramework("", true);
 
     /* Check the version of the Orthanc core */
-    // if (OrthancPluginCheckVersion(c) == 0)
-    // {
-    //   OrthancPlugins::ReportMinimalOrthancVersion(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
-    //                                               ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
-    //                                               ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
-    //   return -1;
-    // }
-
+    if (OrthancPluginCheckVersion(c) == 0)
+    {
+      OrthancPlugins::ReportMinimalOrthancVersion(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
+                                                  ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
+                                                  ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
+      return -1;
+    }
+    
     OrthancPlugins::LogWarning("Sanitizer plugin is initializing");
     OrthancPluginSetDescription(c, "Sample plugin to sanitize incoming DICOM instances.");
 
--- a/OrthancServer/Sources/ServerContext.cpp	Wed Feb 23 06:36:29 2022 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp	Wed Feb 23 09:30:42 2022 +0100
@@ -698,12 +698,12 @@
     {
       // New in Orthanc 1.10.0
 
-      OrthancPluginReceivedInstanceCallbackResult action = GetPlugins().ApplyReceivedInstanceCallbacks(
-        modifiedBuffer, receivedDicom.GetBufferData(), receivedDicom.GetBufferSize());
+      OrthancPluginReceivedInstanceAction action = GetPlugins().ApplyReceivedInstanceCallbacks(
+        modifiedBuffer, receivedDicom.GetBufferData(), receivedDicom.GetBufferSize(), receivedDicom.GetOrigin().GetRequestOrigin());
 
       switch (action)
       {
-        case OrthancPluginReceivedInstanceCallbackResult_Discard:
+        case OrthancPluginReceivedInstanceAction_Discard:
         {
           CLOG(INFO, PLUGINS) << "A plugin has discarded the instance in its ReceivedInstanceCallback";
           StoreResult result;
@@ -711,16 +711,17 @@
           return result;
         }
           
-        case OrthancPluginReceivedInstanceCallbackResult_KeepAsIs:
+        case OrthancPluginReceivedInstanceAction_KeepAsIs:
+          // This path is also used when no ReceivedInstanceCallback is installed by the plugins
           break;
 
-        case OrthancPluginReceivedInstanceCallbackResult_Modify:
+        case OrthancPluginReceivedInstanceAction_Modify:
           if (modifiedBuffer.GetSize() > 0 &&
               modifiedBuffer.GetData() != NULL)
           {
             CLOG(INFO, PLUGINS) << "A plugin has modified the instance in its ReceivedInstanceCallback";        
             modifiedDicom.reset(DicomInstanceToStore::CreateFromBuffer(modifiedBuffer.GetData(), modifiedBuffer.GetSize()));
-            modifiedDicom->SetOrigin(dicom->GetOrigin());
+            modifiedDicom->SetOrigin(receivedDicom.GetOrigin());
             dicom = modifiedDicom.get();
           }
           else