comparison OrthancServer/LuaScripting.cpp @ 1435:6406f5493d92

refactoring: Lua toolbox
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Jun 2015 16:46:23 +0200
parents 461e7554bff7
children 0a3e3be59094
comparison
equal deleted inserted replaced
1434:f9cd40166269 1435:6406f5493d92
45 #include "OrthancRestApi/OrthancRestApi.h" 45 #include "OrthancRestApi/OrthancRestApi.h"
46 46
47 #include <glog/logging.h> 47 #include <glog/logging.h>
48 #include <EmbeddedResources.h> 48 #include <EmbeddedResources.h>
49 49
50 static const char* RECEIVED_INSTANCE_FILTER = "ReceivedInstanceFilter";
51 static const char* ON_STORED_INSTANCE = "OnStoredInstance";
52
53 50
54 namespace Orthanc 51 namespace Orthanc
55 { 52 {
56 IServerCommand* LuaScripting::ParseOperation(const std::string& operation, 53 IServerCommand* LuaScripting::ParseOperation(const std::string& operation,
57 const Json::Value& parameters) 54 const Json::Value& parameters)
58 { 55 {
59 if (operation == "delete") 56 if (operation == "delete")
60 { 57 {
61 LOG(INFO) << "Lua script to delete instance " << parameters["Instance"].asString(); 58 LOG(INFO) << "Lua script to delete resource " << parameters["Resource"].asString();
62 return new DeleteInstanceCommand(context_); 59 return new DeleteInstanceCommand(context_);
63 } 60 }
64 61
65 if (operation == "store-scu") 62 if (operation == "store-scu")
66 { 63 {
73 { 70 {
74 localAet = context_.GetDefaultLocalApplicationEntityTitle(); 71 localAet = context_.GetDefaultLocalApplicationEntityTitle();
75 } 72 }
76 73
77 std::string modality = parameters["Modality"].asString(); 74 std::string modality = parameters["Modality"].asString();
78 LOG(INFO) << "Lua script to send instance " << parameters["Instance"].asString() 75 LOG(INFO) << "Lua script to send resource " << parameters["Resource"].asString()
79 << " to modality " << modality << " using Store-SCU"; 76 << " to modality " << modality << " using Store-SCU";
80 return new StoreScuCommand(context_, localAet, 77 return new StoreScuCommand(context_, localAet,
81 Configuration::GetModalityUsingSymbolicName(modality), true); 78 Configuration::GetModalityUsingSymbolicName(modality), true);
82 } 79 }
83 80
84 if (operation == "store-peer") 81 if (operation == "store-peer")
85 { 82 {
86 std::string peer = parameters["Peer"].asString(); 83 std::string peer = parameters["Peer"].asString();
87 LOG(INFO) << "Lua script to send instance " << parameters["Instance"].asString() 84 LOG(INFO) << "Lua script to send resource " << parameters["Resource"].asString()
88 << " to peer " << peer << " using HTTP"; 85 << " to peer " << peer << " using HTTP";
89 86
90 OrthancPeerParameters parameters; 87 OrthancPeerParameters parameters;
91 Configuration::GetOrthancPeer(parameters, peer); 88 Configuration::GetOrthancPeer(parameters, peer);
92 return new StorePeerCommand(context_, parameters, true); 89 return new StorePeerCommand(context_, parameters, true);
93 } 90 }
94 91
95 if (operation == "modify") 92 if (operation == "modify")
96 { 93 {
97 LOG(INFO) << "Lua script to modify instance " << parameters["Instance"].asString(); 94 LOG(INFO) << "Lua script to modify resource " << parameters["Resource"].asString();
98 DicomModification modification; 95 DicomModification modification;
99 OrthancRestApi::ParseModifyRequest(modification, parameters); 96 OrthancRestApi::ParseModifyRequest(modification, parameters);
100 97
101 std::auto_ptr<ModifyInstanceCommand> command(new ModifyInstanceCommand(context_, modification)); 98 std::auto_ptr<ModifyInstanceCommand> command(new ModifyInstanceCommand(context_, modification));
102 return command.release(); 99 return command.release();
103 } 100 }
104 101
105 if (operation == "call-system") 102 if (operation == "call-system")
106 { 103 {
107 LOG(INFO) << "Lua script to call system command on " << parameters["Instance"].asString(); 104 LOG(INFO) << "Lua script to call system command on " << parameters["Resource"].asString();
108 105
109 const Json::Value& argsIn = parameters["Arguments"]; 106 const Json::Value& argsIn = parameters["Arguments"];
110 if (argsIn.type() != Json::arrayValue) 107 if (argsIn.type() != Json::arrayValue)
111 { 108 {
112 throw OrthancException(ErrorCode_BadParameterType); 109 throw OrthancException(ErrorCode_BadParameterType);
145 142
146 throw OrthancException(ErrorCode_ParameterOutOfRange); 143 throw OrthancException(ErrorCode_ParameterOutOfRange);
147 } 144 }
148 145
149 146
147 void LuaScripting::InitializeJob()
148 {
149 lua_.Execute("_InitializeJob()");
150 }
151
152
153 void LuaScripting::SubmitJob(const std::string& description)
154 {
155 Json::Value operations;
156 LuaFunctionCall call2(lua_, "_AccessJob");
157 call2.ExecuteToJson(operations);
158
159 if (operations.type() != Json::arrayValue)
160 {
161 throw OrthancException(ErrorCode_InternalError);
162 }
163
164 ServerJob job;
165 ServerCommandInstance* previousCommand = NULL;
166
167 for (Json::Value::ArrayIndex i = 0; i < operations.size(); ++i)
168 {
169 if (operations[i].type() != Json::objectValue ||
170 !operations[i].isMember("Operation"))
171 {
172 throw OrthancException(ErrorCode_InternalError);
173 }
174
175 const Json::Value& parameters = operations[i];
176 std::string operation = parameters["Operation"].asString();
177
178 ServerCommandInstance& command = job.AddCommand(ParseOperation(operation, operations[i]));
179
180 if (!parameters.isMember("Resource"))
181 {
182 throw OrthancException(ErrorCode_InternalError);
183 }
184
185 std::string resource = parameters["Resource"].asString();
186 if (resource.empty())
187 {
188 previousCommand->ConnectOutput(command);
189 }
190 else
191 {
192 command.AddInput(resource);
193 }
194
195 previousCommand = &command;
196 }
197
198 job.SetDescription(description);
199 context_.GetScheduler().Submit(job);
200 }
201
202
150 LuaScripting::LuaScripting(ServerContext& context) : context_(context) 203 LuaScripting::LuaScripting(ServerContext& context) : context_(context)
151 { 204 {
152 lua_.Execute(Orthanc::EmbeddedResources::LUA_TOOLBOX); 205 lua_.Execute(Orthanc::EmbeddedResources::LUA_TOOLBOX);
153 lua_.SetHttpProxy(Configuration::GetGlobalStringParameter("HttpProxy", "")); 206 lua_.SetHttpProxy(Configuration::GetGlobalStringParameter("HttpProxy", ""));
154 } 207 }
158 const Json::Value& simplifiedTags, 211 const Json::Value& simplifiedTags,
159 const Json::Value& metadata, 212 const Json::Value& metadata,
160 const std::string& remoteAet, 213 const std::string& remoteAet,
161 const std::string& calledAet) 214 const std::string& calledAet)
162 { 215 {
163 if (lua_.IsExistingFunction(ON_STORED_INSTANCE)) 216 static const char* NAME = "OnStoredInstance";
164 { 217
165 lua_.Execute("_InitializeJob()"); 218 if (lua_.IsExistingFunction(NAME))
166 219 {
167 LuaFunctionCall call(lua_, ON_STORED_INSTANCE); 220 InitializeJob();
221
222 LuaFunctionCall call(lua_, NAME);
168 call.PushString(instanceId); 223 call.PushString(instanceId);
169 call.PushJson(simplifiedTags); 224 call.PushJson(simplifiedTags);
170 call.PushJson(metadata); 225 call.PushJson(metadata);
171 call.PushJson(remoteAet); 226 call.PushJson(remoteAet);
172 call.PushJson(calledAet); 227 call.PushJson(calledAet);
173 call.Execute(); 228 call.Execute();
174 229
175 Json::Value operations; 230 SubmitJob(std::string("Lua script: ") + NAME);
176 LuaFunctionCall call2(lua_, "_AccessJob");
177 call2.ExecuteToJson(operations);
178
179 if (operations.type() != Json::arrayValue)
180 {
181 throw OrthancException(ErrorCode_InternalError);
182 }
183
184 ServerJob job;
185 ServerCommandInstance* previousCommand = NULL;
186
187 for (Json::Value::ArrayIndex i = 0; i < operations.size(); ++i)
188 {
189 if (operations[i].type() != Json::objectValue ||
190 !operations[i].isMember("Operation"))
191 {
192 throw OrthancException(ErrorCode_InternalError);
193 }
194
195 const Json::Value& parameters = operations[i];
196 std::string operation = parameters["Operation"].asString();
197
198 ServerCommandInstance& command = job.AddCommand(ParseOperation(operation, operations[i]));
199
200 if (!parameters.isMember("Instance"))
201 {
202 throw OrthancException(ErrorCode_InternalError);
203 }
204
205 std::string instance = parameters["Instance"].asString();
206 if (instance.empty())
207 {
208 previousCommand->ConnectOutput(command);
209 }
210 else
211 {
212 command.AddInput(instance);
213 }
214
215 previousCommand = &command;
216 }
217
218 job.SetDescription(std::string("Lua script: ") + ON_STORED_INSTANCE);
219 context_.GetScheduler().Submit(job);
220 } 231 }
221 } 232 }
222 233
223 234
224 void LuaScripting::SignalStoredInstance(const std::string& publicId, 235 void LuaScripting::SignalStoredInstance(const std::string& publicId,
242 ApplyOnStoredInstance(publicId, simplifiedTags, metadata, 253 ApplyOnStoredInstance(publicId, simplifiedTags, metadata,
243 instance.GetRemoteAet(), instance.GetCalledAet()); 254 instance.GetRemoteAet(), instance.GetCalledAet());
244 } 255 }
245 256
246 257
258
259 void LuaScripting::OnStableResource(const ServerIndexChange& change)
260 {
261 const char* name;
262
263 switch (change.GetChangeType())
264 {
265 case ChangeType_StablePatient:
266 name = "OnStablePatient";
267 break;
268
269 case ChangeType_StableStudy:
270 name = "OnStableStudy";
271 break;
272
273 case ChangeType_StableSeries:
274 name = "OnStableSeries";
275 break;
276
277 default:
278 throw OrthancException(ErrorCode_InternalError);
279 }
280
281
282 Json::Value tags;
283 //if (context_.GetIndex().LookupResource(tags, change.GetPublicId(), change.GetResourceType()))
284 {
285 boost::mutex::scoped_lock lock(mutex_);
286
287 if (lua_.IsExistingFunction(name))
288 {
289 InitializeJob();
290
291 LuaFunctionCall call(lua_, name);
292 call.PushString(change.GetPublicId());
293 call.PushJson(tags);
294 call.Execute();
295
296 SubmitJob(std::string("Lua script: ") + name);
297 }
298 }
299 }
300
301
302
247 void LuaScripting::SignalChange(const ServerIndexChange& change) 303 void LuaScripting::SignalChange(const ServerIndexChange& change)
248 { 304 {
249 boost::mutex::scoped_lock lock(mutex_); 305 if (change.GetChangeType() == ChangeType_StablePatient ||
250 306 change.GetChangeType() == ChangeType_StableStudy ||
251 // TODO 307 change.GetChangeType() == ChangeType_StableSeries)
308 {
309 OnStableResource(change);
310 }
252 } 311 }
253 312
254 313
255 bool LuaScripting::FilterIncomingInstance(const Json::Value& simplified, 314 bool LuaScripting::FilterIncomingInstance(const Json::Value& simplified,
256 const std::string& remoteAet) 315 const std::string& remoteAet)
257 { 316 {
317 static const char* NAME = "ReceivedInstanceFilter";
318
258 boost::mutex::scoped_lock lock(mutex_); 319 boost::mutex::scoped_lock lock(mutex_);
259 320
260 if (lua_.IsExistingFunction(RECEIVED_INSTANCE_FILTER)) 321 if (lua_.IsExistingFunction(NAME))
261 { 322 {
262 LuaFunctionCall call(lua_, RECEIVED_INSTANCE_FILTER); 323 LuaFunctionCall call(lua_, NAME);
263 call.PushJson(simplified); 324 call.PushJson(simplified);
264 call.PushString(remoteAet); 325 call.PushString(remoteAet);
265 326
266 if (!call.ExecutePredicate()) 327 if (!call.ExecutePredicate())
267 { 328 {