1 /**
2  * Orthanc - A Lightweight, RESTful DICOM Store
3  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4  * Department, University Hospital of Liege, Belgium
5  * Copyright (C) 2017-2021 Osimis S.A., Belgium
6  *
7  * This program is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * In addition, as a special exception, the copyright holders of this
13  * program give permission to link the code of its release with the
14  * OpenSSL project's "OpenSSL" library (or with modified versions of it
15  * that use the same license as the "OpenSSL" library), and distribute
16  * the linked executables. You must obey the GNU General Public License
17  * in all respects for all of the code used other than "OpenSSL". If you
18  * modify file(s) with this exception, you may extend this exception to
19  * your version of the file(s), but you are not obligated to do so. If
20  * you do not wish to do so, delete this exception statement from your
21  * version. If you delete this exception statement from all source files
22  * in the program, then also delete it here.
23  *
24  * This program is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27  * General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  **/
32 
33 
34 #pragma once
35 
36 #include "DicomInstanceToStore.h"
37 #include "ServerIndexChange.h"
38 #include "ServerJobs/LuaJobManager.h"
39 
40 #include "../../OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h"
41 #include "../../OrthancFramework/Sources/Lua/LuaContext.h"
42 
43 namespace Orthanc
44 {
45   class ServerContext;
46 
47   class LuaScripting : public boost::noncopyable
48   {
49   private:
50     enum State
51     {
52       State_Setup,
53       State_Running,
54       State_Done
55     };
56 
57     class ExecuteEvent;
58     class IEvent;
59     class OnStoredInstanceEvent;
60     class StableResourceEvent;
61     class JobEvent;
62     class DeleteEvent;
63     class UpdateEvent;
64 
65     static ServerContext* GetServerContext(lua_State *state);
66 
67     static int RestApiPostOrPut(lua_State *state,
68                                 bool isPost);
69     static int RestApiGet(lua_State *state);
70     static int RestApiPost(lua_State *state);
71     static int RestApiPut(lua_State *state);
72     static int RestApiDelete(lua_State *state);
73     static int GetOrthancConfiguration(lua_State *state);
74 
75     size_t ParseOperation(LuaJobManager::Lock& lock,
76                           const std::string& operation,
77                           const Json::Value& parameters);
78 
79     void InitializeJob();
80 
81     void SubmitJob();
82 
83     boost::recursive_mutex   mutex_;
84     LuaContext               lua_;
85     ServerContext&           context_;
86     LuaJobManager            jobManager_;
87     State                    state_;
88     boost::thread            eventThread_;
89     SharedMessageQueue       pendingEvents_;
90 
91     static void EventThread(LuaScripting* that);
92 
93     void LoadGlobalConfiguration();
94 
95   public:
96     class Lock : public boost::noncopyable
97     {
98     private:
99       LuaScripting&                        that_;
100       boost::recursive_mutex::scoped_lock  lock_;
101 
102     public:
Lock(LuaScripting & that)103       explicit Lock(LuaScripting& that) :
104         that_(that),
105         lock_(that.mutex_)
106       {
107       }
108 
GetLua()109       LuaContext& GetLua()
110       {
111         return that_.lua_;
112       }
113     };
114 
115     explicit LuaScripting(ServerContext& context);
116 
117     ~LuaScripting();
118 
119     void Start();
120 
121     void Stop();
122 
123     void SignalStoredInstance(const std::string& publicId,
124                               const DicomInstanceToStore& instance,
125                               const Json::Value& simplifiedTags);
126 
127     void SignalChange(const ServerIndexChange& change);
128 
129     bool FilterIncomingInstance(const DicomInstanceToStore& instance,
130                                 const Json::Value& simplifiedTags);
131 
132     void Execute(const std::string& command);
133 
134     void SignalJobSubmitted(const std::string& jobId);
135 
136     void SignalJobSuccess(const std::string& jobId);
137 
138     void SignalJobFailure(const std::string& jobId);
139 
GetDicomConnectionManager()140     TimeoutDicomConnectionManager& GetDicomConnectionManager()
141     {
142       return jobManager_.GetDicomConnectionManager();
143     }
144   };
145 }
146