changeset 397:941ea46e9e26 lua-scripting

lua filter of new instances
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 02 May 2013 16:34:00 +0200
parents 9784f19f7e1b
children 2d269089078f 5a3a4a25e568
files Core/Lua/LuaContext.cpp Core/Lua/LuaContext.h OrthancServer/ServerContext.cpp OrthancServer/ServerEnumerations.cpp OrthancServer/ServerEnumerations.h OrthancServer/main.cpp Resources/Toolbox.lua UnitTests/Lua.cpp
diffstat 8 files changed, 109 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Lua/LuaContext.cpp	Thu May 02 11:02:15 2013 +0200
+++ b/Core/Lua/LuaContext.cpp	Thu May 02 16:34:00 2013 +0200
@@ -70,7 +70,7 @@
       lua_pop(L, 1);
     }
 
-    LOG(WARNING) << "Lua: " << result;         
+    LOG(INFO) << "Lua says: " << result;         
 
     return 0;
   }
@@ -121,4 +121,13 @@
     EmbeddedResources::GetFileResource(command, resource);
     Execute(command);
   }
+
+
+  bool LuaContext::IsExistingFunction(const char* name)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+    lua_settop(lua_, 0);
+    lua_getglobal(lua_, name);
+    return lua_type(lua_, -1) == LUA_TFUNCTION;
+  }
 }
--- a/Core/Lua/LuaContext.h	Thu May 02 11:02:15 2013 +0200
+++ b/Core/Lua/LuaContext.h	Thu May 02 16:34:00 2013 +0200
@@ -64,5 +64,7 @@
     void Execute(const std::string& command);
 
     void Execute(EmbeddedResources::FileResourceId resource);
+
+    bool IsExistingFunction(const char* name);
   };
 }
--- a/OrthancServer/ServerContext.cpp	Thu May 02 11:02:15 2013 +0200
+++ b/OrthancServer/ServerContext.cpp	Thu May 02 16:34:00 2013 +0200
@@ -33,12 +33,15 @@
 #include "ServerContext.h"
 
 #include "../Core/HttpServer/FilesystemHttpSender.h"
+#include "../Core/Lua/LuaFunctionCall.h"
+#include "ServerToolbox.h"
 
 #include <glog/logging.h>
 #include <EmbeddedResources.h>
 
 #define ENABLE_DICOM_CACHE  1
 
+static const char* RECEIVED_INSTANCE_FILTER = "ReceivedInstanceFilter";
 
 static const size_t DICOM_CACHE_SIZE = 2;
 
@@ -85,6 +88,23 @@
                                    const Json::Value& dicomJson,
                                    const std::string& remoteAet)
   {
+    // Test if the instance must be filtered out
+    if (lua_.IsExistingFunction(RECEIVED_INSTANCE_FILTER))
+    {
+      Json::Value simplified;
+      SimplifyTags(simplified, dicomJson);
+
+      LuaFunctionCall call(lua_, RECEIVED_INSTANCE_FILTER);
+      call.PushJSON(simplified);
+      call.PushString(remoteAet);
+
+      if (!call.ExecutePredicate())
+      {
+        LOG(INFO) << "An incoming instance has been discarded by a filter";
+        return StoreStatus_FilteredOut;
+      }
+    }
+
     if (compressionEnabled_)
     {
       accessor_.SetCompressionForNextOperations(CompressionType_Zlib);
@@ -111,17 +131,21 @@
 
     switch (status)
     {
-    case StoreStatus_Success:
-      LOG(INFO) << "New instance stored";
-      break;
+      case StoreStatus_Success:
+        LOG(INFO) << "New instance stored";
+        break;
+
+      case StoreStatus_AlreadyStored:
+        LOG(INFO) << "Already stored";
+        break;
 
-    case StoreStatus_AlreadyStored:
-      LOG(INFO) << "Already stored";
-      break;
+      case StoreStatus_Failure:
+        LOG(ERROR) << "Store failure";
+        break;
 
-    case StoreStatus_Failure:
-      LOG(ERROR) << "Store failure";
-      break;
+      default:
+        // This should never happen
+        break;
     }
 
     return status;
--- a/OrthancServer/ServerEnumerations.cpp	Thu May 02 11:02:15 2013 +0200
+++ b/OrthancServer/ServerEnumerations.cpp	Thu May 02 16:34:00 2013 +0200
@@ -112,6 +112,9 @@
       case StoreStatus_Failure:
         return "Failure";
 
+      case StoreStatus_FilteredOut:
+        return "FilteredOut";
+
       default:
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
--- a/OrthancServer/ServerEnumerations.h	Thu May 02 11:02:15 2013 +0200
+++ b/OrthancServer/ServerEnumerations.h	Thu May 02 16:34:00 2013 +0200
@@ -47,7 +47,8 @@
   {
     StoreStatus_Success,
     StoreStatus_AlreadyStored,
-    StoreStatus_Failure
+    StoreStatus_Failure,
+    StoreStatus_FilteredOut     // Removed by NewInstanceFilter
   };
 
 
--- a/OrthancServer/main.cpp	Thu May 02 11:02:15 2013 +0200
+++ b/OrthancServer/main.cpp	Thu May 02 16:34:00 2013 +0200
@@ -65,20 +65,7 @@
   {
     if (dicomFile.size() > 0)
     {
-      LuaContext& lua = server_.GetLuaContext();
-      // TODO : Is existing trigger ?
-      LuaFunctionCall call(lua, "NewInstanceFilter");
-      call.PushJSON(dicomJson);
-      call.PushString(remoteAet);
-
-      if (call.ExecutePredicate())
-      {
-        server_.Store(&dicomFile[0], dicomFile.size(), dicomSummary, dicomJson, remoteAet);
-      }
-      else
-      {
-        LOG(WARNING) << "An instance has been discarded by a filter";
-      }
+      server_.Store(&dicomFile[0], dicomFile.size(), dicomSummary, dicomJson, remoteAet);
     }
   }
 };
--- a/Resources/Toolbox.lua	Thu May 02 11:02:15 2013 +0200
+++ b/Resources/Toolbox.lua	Thu May 02 16:34:00 2013 +0200
@@ -1,18 +1,18 @@
---[[ printRecursive(struct, [limit], [indent])   Recursively print arbitrary data. 
+--[[ PrintRecursive(struct, [limit], [indent])   Recursively print arbitrary data. 
 Set limit (default 100) to stanch infinite loops.
 Indents tables as [KEY] VALUE, nested tables as [KEY] [KEY]...[KEY] VALUE
 Set indent ("") to prefix each line:    Mytable [KEY] [KEY]...[KEY] VALUE
 Source: https://gist.github.com/stuby/5445834#file-rprint-lua
 --]]
 
-function printRecursive(s, l, i) -- recursive Print (structure, limit, indent)
+function PrintRecursive(s, l, i) -- recursive Print (structure, limit, indent)
    l = (l) or 100; i = i or "";	-- default item limit, indent string
    if (l<1) then print "ERROR: Item limit reached."; return l-1 end;
    local ts = type(s);
    if (ts ~= "table") then print (i,ts,s); return l-1 end
    print (i,ts);           -- print "table"
    for k,v in pairs(s) do  -- print "[KEY] VALUE"
-      l = printRecursive(v, l, i.."\t["..tostring(k).."]");
+      l = PrintRecursive(v, l, i.."\t["..tostring(k).."]");
       if (l < 0) then break end
    end
    return l
--- a/UnitTests/Lua.cpp	Thu May 02 11:02:15 2013 +0200
+++ b/UnitTests/Lua.cpp	Thu May 02 16:34:00 2013 +0200
@@ -5,64 +5,68 @@
 
 TEST(Lua, Simple)
 {
-  try
-  {
-    Orthanc::LuaContext lua;
-    lua.Execute(Orthanc::EmbeddedResources::LUA_TOOLBOX);
-    lua.Execute("a={}");
-    lua.Execute("a['x'] = 10");
-    lua.Execute("a['y'] = {}");
-    lua.Execute("a['y'][1] = 20");
-    lua.Execute("a['y'][2] = 20");
-    lua.Execute("rPrint(a)");
+  Orthanc::LuaContext lua;
+  lua.Execute(Orthanc::EmbeddedResources::LUA_TOOLBOX);
+  lua.Execute("a={}");
+  lua.Execute("a['x'] = 10");
+  lua.Execute("a['y'] = {}");
+  lua.Execute("a['y'][1] = 20");
+  lua.Execute("a['y'][2] = 20");
+  lua.Execute("PrintRecursive(a)");
 
-    lua.Execute("function f(a) print(a.bool) return a.bool,20,30,40,50,60 end");
+  lua.Execute("function f(a) print(a.bool) return a.bool,20,30,40,50,60 end");
 
-    Json::Value v, vv, o;
-    //v["a"] = "b";
-    v.append("hello");
-    v.append("world");
-    v.append("42");
-    vv.append("coucou");
-    vv.append("toi");
-    v.append(vv);
-    o = Json::objectValue;
-    o["x"] = 10;
-    o["y"] = 20;
-    o["z"] = 20.5f;
-    v.append(o);
+  Json::Value v, vv, o;
+  //v["a"] = "b";
+  v.append("hello");
+  v.append("world");
+  v.append("42");
+  vv.append("sub");
+  vv.append("set");
+  v.append(vv);
+  o = Json::objectValue;
+  o["x"] = 10;
+  o["y"] = 20;
+  o["z"] = 20.5f;
+  v.append(o);
 
-    {
-      Orthanc::LuaFunctionCall f(lua, "rPrint");
-      f.PushJSON(v);
-      f.Execute();
-    }
+  {
+    Orthanc::LuaFunctionCall f(lua, "PrintRecursive");
+    f.PushJSON(v);
+    f.Execute();
+  }
 
-    {
-      Orthanc::LuaFunctionCall f(lua, "f");
-      f.PushJSON(o);
-      ASSERT_THROW(f.ExecutePredicate(), Orthanc::LuaException);
-    }
-
-    o["bool"] = false;
+  {
+    Orthanc::LuaFunctionCall f(lua, "f");
+    f.PushJSON(o);
+    ASSERT_THROW(f.ExecutePredicate(), Orthanc::LuaException);
+  }
 
-    {
-      Orthanc::LuaFunctionCall f(lua, "f");
-      f.PushJSON(o);
-      ASSERT_FALSE(f.ExecutePredicate());
-    }
-
-    o["bool"] = true;
+  o["bool"] = false;
 
-    {
-      Orthanc::LuaFunctionCall f(lua, "f");
-      f.PushJSON(o);
-      ASSERT_TRUE(f.ExecutePredicate());
-    }
+  {
+    Orthanc::LuaFunctionCall f(lua, "f");
+    f.PushJSON(o);
+    ASSERT_FALSE(f.ExecutePredicate());
+  }
 
-  }
-  catch (Orthanc::LuaException e)
+  o["bool"] = true;
+
   {
-    std::cerr << "EXCEPTION: [" << e.What() << "]" << std::endl;
+    Orthanc::LuaFunctionCall f(lua, "f");
+    f.PushJSON(o);
+    ASSERT_TRUE(f.ExecutePredicate());
   }
 }
+
+
+TEST(Lua, Existing)
+{
+  Orthanc::LuaContext lua;
+  lua.Execute("a={}");
+  lua.Execute("function f() end");
+
+  ASSERT_TRUE(lua.IsExistingFunction("f"));
+  ASSERT_FALSE(lua.IsExistingFunction("a"));
+  ASSERT_FALSE(lua.IsExistingFunction("Dummy"));
+}