Mercurial > hg > orthanc
comparison OrthancServer/OrthancFindRequestHandler.cpp @ 1888:512b6e76f531
Lua: "IncomingFindRequestFilter()" to apply filters to incoming C-Find requests
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 11 Dec 2015 16:39:51 +0100 |
parents | 4e7c318a3f69 |
children | d7f63122c7f3 |
comparison
equal
deleted
inserted
replaced
1887:5e0a25642056 | 1888:512b6e76f531 |
---|---|
32 | 32 |
33 #include "PrecompiledHeadersServer.h" | 33 #include "PrecompiledHeadersServer.h" |
34 #include "OrthancFindRequestHandler.h" | 34 #include "OrthancFindRequestHandler.h" |
35 | 35 |
36 #include "../Core/DicomFormat/DicomArray.h" | 36 #include "../Core/DicomFormat/DicomArray.h" |
37 #include "../Core/Lua/LuaFunctionCall.h" | |
37 #include "../Core/Logging.h" | 38 #include "../Core/Logging.h" |
38 #include "FromDcmtkBridge.h" | 39 #include "FromDcmtkBridge.h" |
39 #include "OrthancInitialization.h" | 40 #include "OrthancInitialization.h" |
40 #include "Search/LookupResource.h" | 41 #include "Search/LookupResource.h" |
41 #include "ServerToolbox.h" | 42 #include "ServerToolbox.h" |
157 | 158 |
158 return true; | 159 return true; |
159 } | 160 } |
160 | 161 |
161 | 162 |
163 bool OrthancFindRequestHandler::ApplyLuaFilter(DicomMap& target, | |
164 const DicomMap& source, | |
165 const std::string& remoteIp, | |
166 const std::string& remoteAet, | |
167 const std::string& calledAet) | |
168 { | |
169 static const char* NAME = "IncomingFindRequestFilter"; | |
170 | |
171 Json::Value output; | |
172 | |
173 { | |
174 LuaScripting::Locker locker(context_.GetLua()); | |
175 | |
176 if (!locker.GetLua().IsExistingFunction(NAME)) | |
177 { | |
178 return false; | |
179 } | |
180 | |
181 Json::Value tmp = Json::objectValue; | |
182 DicomArray a(source); | |
183 | |
184 for (size_t i = 0; i < a.GetSize(); i++) | |
185 { | |
186 const DicomValue& v = a.GetElement(i).GetValue(); | |
187 std::string s = (v.IsNull() || v.IsBinary()) ? "" : v.GetContent(); | |
188 tmp[a.GetElement(i).GetTag().Format()] = s; | |
189 } | |
190 | |
191 Json::Value origin = Json::objectValue; | |
192 origin["RemoteIp"] = remoteIp; | |
193 origin["RemoteAet"] = remoteAet; | |
194 origin["CalledAet"] = calledAet; | |
195 | |
196 LuaFunctionCall call(locker.GetLua(), NAME); | |
197 call.PushJson(tmp); | |
198 call.PushJson(origin); | |
199 | |
200 call.ExecuteToJson(output, true); | |
201 } | |
202 | |
203 // The Lua context is released at this point | |
204 | |
205 if (output.type() != Json::objectValue) | |
206 { | |
207 LOG(ERROR) << "Lua: IncomingFindRequestFilter must return a table"; | |
208 throw OrthancException(ErrorCode_LuaBadOutput); | |
209 } | |
210 | |
211 Json::Value::Members members = output.getMemberNames(); | |
212 | |
213 for (size_t i = 0; i < members.size(); i++) | |
214 { | |
215 if (output[members[i]].type() != Json::stringValue) | |
216 { | |
217 LOG(ERROR) << "Lua: IncomingFindRequestFilter must return a table mapping names of DICOM tags to strings"; | |
218 throw OrthancException(ErrorCode_LuaBadOutput); | |
219 } | |
220 | |
221 DicomTag tag(FromDcmtkBridge::ParseTag(members[i])); | |
222 target.SetValue(tag, output[members[i]].asString()); | |
223 } | |
224 | |
225 return true; | |
226 } | |
227 | |
228 | |
162 void OrthancFindRequestHandler::Handle(DicomFindAnswers& answers, | 229 void OrthancFindRequestHandler::Handle(DicomFindAnswers& answers, |
163 const DicomMap& input, | 230 const DicomMap& input, |
164 const std::list<DicomTag>& sequencesToReturn, | 231 const std::list<DicomTag>& sequencesToReturn, |
165 const std::string& remoteIp, | 232 const std::string& remoteIp, |
166 const std::string& remoteAet, | 233 const std::string& remoteAet, |
179 | 246 |
180 bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false); | 247 bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false); |
181 | 248 |
182 | 249 |
183 /** | 250 /** |
251 * Possibly apply the user-supplied Lua filter. | |
252 **/ | |
253 | |
254 DicomMap lua; | |
255 const DicomMap* filteredInput = &input; | |
256 | |
257 if (ApplyLuaFilter(lua, input, remoteIp, remoteAet, calledAet)) | |
258 { | |
259 filteredInput = &lua; | |
260 } | |
261 | |
262 | |
263 /** | |
184 * Retrieve the query level. | 264 * Retrieve the query level. |
185 **/ | 265 **/ |
186 | 266 |
187 const DicomValue* levelTmp = input.TestAndGetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL); | 267 assert(filteredInput != NULL); |
268 const DicomValue* levelTmp = filteredInput->TestAndGetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL); | |
188 if (levelTmp == NULL || | 269 if (levelTmp == NULL || |
189 levelTmp->IsNull() || | 270 levelTmp->IsNull() || |
190 levelTmp->IsBinary()) | 271 levelTmp->IsBinary()) |
191 { | 272 { |
192 LOG(ERROR) << "C-FIND request without the tag 0008,0052 (QueryRetrieveLevel)"; | 273 LOG(ERROR) << "C-FIND request without the tag 0008,0052 (QueryRetrieveLevel)"; |
202 { | 283 { |
203 throw OrthancException(ErrorCode_NotImplemented); | 284 throw OrthancException(ErrorCode_NotImplemented); |
204 } | 285 } |
205 | 286 |
206 | 287 |
207 DicomArray query(input); | 288 DicomArray query(*filteredInput); |
208 LOG(INFO) << "DICOM C-Find request at level: " << EnumerationToString(level); | 289 LOG(INFO) << "DICOM C-Find request at level: " << EnumerationToString(level); |
209 | 290 |
210 for (size_t i = 0; i < query.GetSize(); i++) | 291 for (size_t i = 0; i < query.GetSize(); i++) |
211 { | 292 { |
212 if (!query.GetElement(i).GetValue().IsNull()) | 293 if (!query.GetElement(i).GetValue().IsNull()) |