changeset 1435:6406f5493d92

refactoring: Lua toolbox
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Jun 2015 16:46:23 +0200
parents f9cd40166269
children 0a3e3be59094
files OrthancServer/LuaScripting.cpp OrthancServer/LuaScripting.h Resources/Toolbox.lua
diffstat 3 files changed, 164 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/LuaScripting.cpp	Tue Jun 30 16:04:05 2015 +0200
+++ b/OrthancServer/LuaScripting.cpp	Tue Jun 30 16:46:23 2015 +0200
@@ -47,9 +47,6 @@
 #include <glog/logging.h>
 #include <EmbeddedResources.h>
 
-static const char* RECEIVED_INSTANCE_FILTER = "ReceivedInstanceFilter";
-static const char* ON_STORED_INSTANCE = "OnStoredInstance";
-
 
 namespace Orthanc
 {
@@ -58,7 +55,7 @@
   {
     if (operation == "delete")
     {
-      LOG(INFO) << "Lua script to delete instance " << parameters["Instance"].asString();
+      LOG(INFO) << "Lua script to delete resource " << parameters["Resource"].asString();
       return new DeleteInstanceCommand(context_);
     }
 
@@ -75,7 +72,7 @@
       }
 
       std::string modality = parameters["Modality"].asString();
-      LOG(INFO) << "Lua script to send instance " << parameters["Instance"].asString()
+      LOG(INFO) << "Lua script to send resource " << parameters["Resource"].asString()
                 << " to modality " << modality << " using Store-SCU";
       return new StoreScuCommand(context_, localAet,
                                  Configuration::GetModalityUsingSymbolicName(modality), true);
@@ -84,7 +81,7 @@
     if (operation == "store-peer")
     {
       std::string peer = parameters["Peer"].asString();
-      LOG(INFO) << "Lua script to send instance " << parameters["Instance"].asString()
+      LOG(INFO) << "Lua script to send resource " << parameters["Resource"].asString()
                 << " to peer " << peer << " using HTTP";
 
       OrthancPeerParameters parameters;
@@ -94,7 +91,7 @@
 
     if (operation == "modify")
     {
-      LOG(INFO) << "Lua script to modify instance " << parameters["Instance"].asString();
+      LOG(INFO) << "Lua script to modify resource " << parameters["Resource"].asString();
       DicomModification modification;
       OrthancRestApi::ParseModifyRequest(modification, parameters);
 
@@ -104,7 +101,7 @@
 
     if (operation == "call-system")
     {
-      LOG(INFO) << "Lua script to call system command on " << parameters["Instance"].asString();
+      LOG(INFO) << "Lua script to call system command on " << parameters["Resource"].asString();
 
       const Json::Value& argsIn = parameters["Arguments"];
       if (argsIn.type() != Json::arrayValue)
@@ -147,6 +144,62 @@
   }
 
 
+  void LuaScripting::InitializeJob()
+  {
+    lua_.Execute("_InitializeJob()");
+  }
+
+
+  void LuaScripting::SubmitJob(const std::string& description)
+  {
+    Json::Value operations;
+    LuaFunctionCall call2(lua_, "_AccessJob");
+    call2.ExecuteToJson(operations);
+     
+    if (operations.type() != Json::arrayValue)
+    {
+      throw OrthancException(ErrorCode_InternalError);
+    }
+
+    ServerJob job;
+    ServerCommandInstance* previousCommand = NULL;
+
+    for (Json::Value::ArrayIndex i = 0; i < operations.size(); ++i)
+    {
+      if (operations[i].type() != Json::objectValue ||
+          !operations[i].isMember("Operation"))
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+
+      const Json::Value& parameters = operations[i];
+      std::string operation = parameters["Operation"].asString();
+
+      ServerCommandInstance& command = job.AddCommand(ParseOperation(operation, operations[i]));
+        
+      if (!parameters.isMember("Resource"))
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+
+      std::string resource = parameters["Resource"].asString();
+      if (resource.empty())
+      {
+        previousCommand->ConnectOutput(command);
+      }
+      else 
+      {
+        command.AddInput(resource);
+      }
+
+      previousCommand = &command;
+    }
+
+    job.SetDescription(description);
+    context_.GetScheduler().Submit(job);
+  }
+
+
   LuaScripting::LuaScripting(ServerContext& context) : context_(context)
   {
     lua_.Execute(Orthanc::EmbeddedResources::LUA_TOOLBOX);
@@ -160,11 +213,13 @@
                                            const std::string& remoteAet,
                                            const std::string& calledAet)
   {
-    if (lua_.IsExistingFunction(ON_STORED_INSTANCE))
+    static const char* NAME = "OnStoredInstance";
+
+    if (lua_.IsExistingFunction(NAME))
     {
-      lua_.Execute("_InitializeJob()");
+      InitializeJob();
 
-      LuaFunctionCall call(lua_, ON_STORED_INSTANCE);
+      LuaFunctionCall call(lua_, NAME);
       call.PushString(instanceId);
       call.PushJson(simplifiedTags);
       call.PushJson(metadata);
@@ -172,51 +227,7 @@
       call.PushJson(calledAet);
       call.Execute();
 
-      Json::Value operations;
-      LuaFunctionCall call2(lua_, "_AccessJob");
-      call2.ExecuteToJson(operations);
-     
-      if (operations.type() != Json::arrayValue)
-      {
-        throw OrthancException(ErrorCode_InternalError);
-      }
-
-      ServerJob job;
-      ServerCommandInstance* previousCommand = NULL;
-
-      for (Json::Value::ArrayIndex i = 0; i < operations.size(); ++i)
-      {
-        if (operations[i].type() != Json::objectValue ||
-            !operations[i].isMember("Operation"))
-        {
-          throw OrthancException(ErrorCode_InternalError);
-        }
-
-        const Json::Value& parameters = operations[i];
-        std::string operation = parameters["Operation"].asString();
-
-        ServerCommandInstance& command = job.AddCommand(ParseOperation(operation, operations[i]));
-        
-        if (!parameters.isMember("Instance"))
-        {
-          throw OrthancException(ErrorCode_InternalError);
-        }
-
-        std::string instance = parameters["Instance"].asString();
-        if (instance.empty())
-        {
-          previousCommand->ConnectOutput(command);
-        }
-        else 
-        {
-          command.AddInput(instance);
-        }
-
-        previousCommand = &command;
-      }
-
-      job.SetDescription(std::string("Lua script: ") + ON_STORED_INSTANCE);
-      context_.GetScheduler().Submit(job);
+      SubmitJob(std::string("Lua script: ") + NAME);
     }
   }
 
@@ -244,22 +255,72 @@
   }
 
 
+  
+  void LuaScripting::OnStableResource(const ServerIndexChange& change)
+  {
+    const char* name;
+
+    switch (change.GetChangeType())
+    {
+      case ChangeType_StablePatient:
+        name = "OnStablePatient";
+        break;
+
+      case ChangeType_StableStudy:
+        name = "OnStableStudy";
+        break;
+
+      case ChangeType_StableSeries:
+        name = "OnStableSeries";
+        break;
+
+      default:
+        throw OrthancException(ErrorCode_InternalError);
+    }
+
+
+    Json::Value tags;
+    //if (context_.GetIndex().LookupResource(tags, change.GetPublicId(), change.GetResourceType()))
+    {
+      boost::mutex::scoped_lock lock(mutex_);
+
+      if (lua_.IsExistingFunction(name))
+      {
+        InitializeJob();
+
+        LuaFunctionCall call(lua_, name);
+        call.PushString(change.GetPublicId());
+        call.PushJson(tags);
+        call.Execute();
+
+        SubmitJob(std::string("Lua script: ") + name);
+      }
+    }
+  }
+
+
+
   void LuaScripting::SignalChange(const ServerIndexChange& change)
   {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    // TODO
+    if (change.GetChangeType() == ChangeType_StablePatient ||
+        change.GetChangeType() == ChangeType_StableStudy ||
+        change.GetChangeType() == ChangeType_StableSeries)
+    {
+      OnStableResource(change);
+    }
   }
 
 
   bool LuaScripting::FilterIncomingInstance(const Json::Value& simplified,
                                             const std::string& remoteAet)
   {
+    static const char* NAME = "ReceivedInstanceFilter";
+
     boost::mutex::scoped_lock lock(mutex_);
 
-    if (lua_.IsExistingFunction(RECEIVED_INSTANCE_FILTER))
+    if (lua_.IsExistingFunction(NAME))
     {
-      LuaFunctionCall call(lua_, RECEIVED_INSTANCE_FILTER);
+      LuaFunctionCall call(lua_, NAME);
       call.PushJson(simplified);
       call.PushString(remoteAet);
 
--- a/OrthancServer/LuaScripting.h	Tue Jun 30 16:04:05 2015 +0200
+++ b/OrthancServer/LuaScripting.h	Tue Jun 30 16:46:23 2015 +0200
@@ -52,6 +52,12 @@
     IServerCommand* ParseOperation(const std::string& operation,
                                    const Json::Value& parameters);
 
+    void InitializeJob();
+
+    void SubmitJob(const std::string& description);
+
+    void OnStableResource(const ServerIndexChange& change);
+
     boost::mutex    mutex_;
     LuaContext      lua_;
     ServerContext&  context_;
--- a/Resources/Toolbox.lua	Tue Jun 30 16:04:05 2015 +0200
+++ b/Resources/Toolbox.lua	Tue Jun 30 16:46:23 2015 +0200
@@ -32,81 +32,92 @@
 end
 
 
-function SendToModality(instanceId, modality, localAet)
-   if instanceId == nil then
-      error('Cannot send a nonexistent instance')
+function SendToModality(resourceId, modality, localAet)
+   if resourceId == nil then
+      error('Cannot send a nonexistent resource')
    end
 
    table.insert(_job, { 
                    Operation = 'store-scu', 
-                   Instance = instanceId,
+                   Resource = resourceId,
                    Modality = modality,
                    LocalAet = localAet
                 })
-   return instanceId
+   return resourceId
 end
 
 
-function SendToPeer(instanceId, peer)
-   if instanceId == nil then
-      error('Cannot send a nonexistent instance')
+function SendToPeer(resourceId, peer)
+   if resourceId == nil then
+      error('Cannot send a nonexistent resource')
    end
 
    table.insert(_job, { 
                    Operation = 'store-peer', 
-                   Instance = instanceId,
+                   Resource = resourceId,
                    Peer = peer
                 })
-   return instanceId
+   return resourceId
 end
 
 
-function Delete(instanceId)
-   if instanceId == nil then
-      error('Cannot delete a nonexistent instance')
+function Delete(resourceId)
+   if resourceId == nil then
+      error('Cannot delete a nonexistent resource')
    end
 
    table.insert(_job, { 
                    Operation = 'delete', 
-                   Instance = instanceId
+                   Resource = resourceId
                 })
    return nil  -- Forbid chaining
 end
 
 
-function ModifyInstance(instanceId, replacements, removals, removePrivateTags)
-   if instanceId == nil then
-      error('Cannot modify a nonexistent instance')
+function ModifyResource(resourceId, replacements, removals, removePrivateTags)
+   if resourceId == nil then
+      error('Cannot modify a nonexistent resource')
    end
 
-   if instanceId == '' then
-      error('Cannot modify twice an instance');
+   if resourceId == '' then
+      error('Cannot modify twice an resource');
    end
 
    table.insert(_job, { 
                    Operation = 'modify', 
-                   Instance = instanceId,
+                   Resource = resourceId,
                    Replace = replacements, 
                    Remove = removals,
                    RemovePrivateTags = removePrivateTags 
                 })
+
    return ''  -- Chain with another operation
 end
 
 
-function CallSystem(instanceId, command, args)
-   if instanceId == nil then
-      error('Cannot modify a nonexistent instance')
+function ModifyInstance(resourceId, replacements, removals, removePrivateTags)
+   return ModifyResource(resourceId, replacements, removals, removePrivateTags)
+end
+
+
+-- This function is only applicable to individual instances
+function CallSystem(resourceId, command, args)
+   if resourceId == nil then
+      error('Cannot execute a system call on a nonexistent resource')
+   end
+
+   if command == nil then
+      error('No command was specified for system call')
    end
 
    table.insert(_job, { 
                    Operation = 'call-system', 
-                   Instance = instanceId,
+                   Resource = resourceId,
                    Command = command,
                    Arguments = args
                 })
 
-   return instanceId
+   return resourceId
 end