Mercurial > hg > orthanc-stone
comparison Framework/Oracle/GenericOracleRunner.cpp @ 1134:87fbeb823375 broker
allocating messages from oracle commands on the stack
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 06 Nov 2019 15:16:45 +0100 |
parents | 8e3763d1736a |
children | a0a33e5ea5bb |
comparison
equal
deleted
inserted
replaced
1133:0e3a3be313fd | 1134:87fbeb823375 |
---|---|
98 << " to " << answer.size() << " bytes"; | 98 << " to " << answer.size() << " bytes"; |
99 } | 99 } |
100 } | 100 } |
101 | 101 |
102 | 102 |
103 static IMessage* Execute(const HttpCommand& command) | 103 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
104 IMessageEmitter& emitter, | |
105 HttpCommand& command) | |
104 { | 106 { |
105 Orthanc::HttpClient client; | 107 Orthanc::HttpClient client; |
106 client.SetUrl(command.GetUrl()); | 108 client.SetUrl(command.GetUrl()); |
107 client.SetMethod(command.GetMethod()); | 109 client.SetMethod(command.GetMethod()); |
108 client.SetTimeout(command.GetTimeout()); | 110 client.SetTimeout(command.GetTimeout()); |
124 Orthanc::HttpClient::HttpHeaders answerHeaders; | 126 Orthanc::HttpClient::HttpHeaders answerHeaders; |
125 client.ApplyAndThrowException(answer, answerHeaders); | 127 client.ApplyAndThrowException(answer, answerHeaders); |
126 | 128 |
127 DecodeAnswer(answer, answerHeaders); | 129 DecodeAnswer(answer, answerHeaders); |
128 | 130 |
129 return new HttpCommand::SuccessMessage(command, answerHeaders, answer); | 131 HttpCommand::SuccessMessage message(command, answerHeaders, answer); |
130 } | 132 emitter.EmitMessage(receiver, message); |
131 | 133 } |
132 | 134 |
133 static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, | 135 |
134 const OrthancRestApiCommand& command) | 136 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
137 IMessageEmitter& emitter, | |
138 const Orthanc::WebServiceParameters& orthanc, | |
139 OrthancRestApiCommand& command) | |
135 { | 140 { |
136 Orthanc::HttpClient client(orthanc, command.GetUri()); | 141 Orthanc::HttpClient client(orthanc, command.GetUri()); |
137 client.SetMethod(command.GetMethod()); | 142 client.SetMethod(command.GetMethod()); |
138 client.SetTimeout(command.GetTimeout()); | 143 client.SetTimeout(command.GetTimeout()); |
139 | 144 |
149 Orthanc::HttpClient::HttpHeaders answerHeaders; | 154 Orthanc::HttpClient::HttpHeaders answerHeaders; |
150 client.ApplyAndThrowException(answer, answerHeaders); | 155 client.ApplyAndThrowException(answer, answerHeaders); |
151 | 156 |
152 DecodeAnswer(answer, answerHeaders); | 157 DecodeAnswer(answer, answerHeaders); |
153 | 158 |
154 return new OrthancRestApiCommand::SuccessMessage(command, answerHeaders, answer); | 159 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); |
155 } | 160 emitter.EmitMessage(receiver, message); |
156 | 161 } |
157 | 162 |
158 static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, | 163 |
159 const GetOrthancImageCommand& command) | 164 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
165 IMessageEmitter& emitter, | |
166 const Orthanc::WebServiceParameters& orthanc, | |
167 GetOrthancImageCommand& command) | |
160 { | 168 { |
161 Orthanc::HttpClient client(orthanc, command.GetUri()); | 169 Orthanc::HttpClient client(orthanc, command.GetUri()); |
162 client.SetTimeout(command.GetTimeout()); | 170 client.SetTimeout(command.GetTimeout()); |
163 | 171 |
164 CopyHttpHeaders(client, command.GetHttpHeaders()); | 172 CopyHttpHeaders(client, command.GetHttpHeaders()); |
167 Orthanc::HttpClient::HttpHeaders answerHeaders; | 175 Orthanc::HttpClient::HttpHeaders answerHeaders; |
168 client.ApplyAndThrowException(answer, answerHeaders); | 176 client.ApplyAndThrowException(answer, answerHeaders); |
169 | 177 |
170 DecodeAnswer(answer, answerHeaders); | 178 DecodeAnswer(answer, answerHeaders); |
171 | 179 |
172 return command.ProcessHttpAnswer(answer, answerHeaders); | 180 command.ProcessHttpAnswer(receiver, emitter, answer, answerHeaders); |
173 } | 181 } |
174 | 182 |
175 | 183 |
176 static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, | 184 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
177 const GetOrthancWebViewerJpegCommand& command) | 185 IMessageEmitter& emitter, |
186 const Orthanc::WebServiceParameters& orthanc, | |
187 GetOrthancWebViewerJpegCommand& command) | |
178 { | 188 { |
179 Orthanc::HttpClient client(orthanc, command.GetUri()); | 189 Orthanc::HttpClient client(orthanc, command.GetUri()); |
180 client.SetTimeout(command.GetTimeout()); | 190 client.SetTimeout(command.GetTimeout()); |
181 | 191 |
182 CopyHttpHeaders(client, command.GetHttpHeaders()); | 192 CopyHttpHeaders(client, command.GetHttpHeaders()); |
185 Orthanc::HttpClient::HttpHeaders answerHeaders; | 195 Orthanc::HttpClient::HttpHeaders answerHeaders; |
186 client.ApplyAndThrowException(answer, answerHeaders); | 196 client.ApplyAndThrowException(answer, answerHeaders); |
187 | 197 |
188 DecodeAnswer(answer, answerHeaders); | 198 DecodeAnswer(answer, answerHeaders); |
189 | 199 |
190 return command.ProcessHttpAnswer(answer); | 200 command.ProcessHttpAnswer(receiver, emitter, answer); |
191 } | 201 } |
192 | 202 |
193 | 203 |
194 static std::string GetPath(const std::string& root, | 204 static std::string GetPath(const std::string& root, |
195 const std::string& file) | 205 const std::string& file) |
210 LOG(TRACE) << "Oracle reading file: " << c.string(); | 220 LOG(TRACE) << "Oracle reading file: " << c.string(); |
211 return c.string(); | 221 return c.string(); |
212 } | 222 } |
213 | 223 |
214 | 224 |
215 static IMessage* Execute(const std::string& root, | 225 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
216 ReadFileCommand& command) | 226 IMessageEmitter& emitter, |
227 const std::string& root, | |
228 ReadFileCommand& command) | |
217 { | 229 { |
218 std::string path = GetPath(root, command.GetPath()); | 230 std::string path = GetPath(root, command.GetPath()); |
219 | 231 |
220 std::string content; | 232 std::string content; |
221 Orthanc::SystemToolbox::ReadFile(content, path, true /* log */); | 233 Orthanc::SystemToolbox::ReadFile(content, path, true /* log */); |
222 | 234 |
223 return new ReadFileCommand::SuccessMessage(command, content); | 235 ReadFileCommand::SuccessMessage message(command, content); |
236 emitter.EmitMessage(receiver, message); | |
224 } | 237 } |
225 | 238 |
226 | 239 |
227 #if ORTHANC_ENABLE_DCMTK == 1 | 240 #if ORTHANC_ENABLE_DCMTK == 1 |
228 static ParseDicomFileCommand::SuccessMessage* Execute(const std::string& root, | 241 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
229 const ParseDicomFileCommand& command) | 242 IMessageEmitter& emitter, |
243 const std::string& root, | |
244 ParseDicomFileCommand& command) | |
230 { | 245 { |
231 std::string path = GetPath(root, command.GetPath()); | 246 std::string path = GetPath(root, command.GetPath()); |
232 | 247 |
233 if (!Orthanc::SystemToolbox::IsRegularFile(path)) | 248 if (!Orthanc::SystemToolbox::IsRegularFile(path)) |
234 { | 249 { |
269 | 284 |
270 printf("Reading %s\n", path.c_str()); | 285 printf("Reading %s\n", path.c_str()); |
271 | 286 |
272 if (ok) | 287 if (ok) |
273 { | 288 { |
274 return new ParseDicomFileCommand::SuccessMessage | 289 Orthanc::ParsedDicomFile parsed(dicom); |
275 (command, dicom, static_cast<size_t>(fileSize), command.IsPixelDataIncluded()); | 290 ParseDicomFileCommand::SuccessMessage message |
291 (command, parsed, static_cast<size_t>(fileSize), command.IsPixelDataIncluded()); | |
292 emitter.EmitMessage(receiver, message); | |
276 } | 293 } |
277 else | 294 else |
278 { | 295 { |
279 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | 296 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, |
280 "Cannot parse file: " + path); | 297 "Cannot parse file: " + path); |
281 } | 298 } |
282 } | 299 } |
283 | 300 |
284 | 301 |
285 static ParseDicomFileCommand::SuccessMessage* Execute(boost::shared_ptr<ParsedDicomFileCache> cache, | 302 static void RunInternal(boost::weak_ptr<IObserver> receiver, |
286 const std::string& root, | 303 IMessageEmitter& emitter, |
287 const ParseDicomFileCommand& command) | 304 boost::shared_ptr<ParsedDicomFileCache> cache, |
305 const std::string& root, | |
306 ParseDicomFileCommand& command) | |
288 { | 307 { |
289 #if 0 | 308 #if 0 |
290 // The code to use the cache is buggy in multithreaded environments => TODO FIX | 309 // The code to use the cache is buggy in multithreaded environments => TODO FIX |
291 if (cache.get()) | 310 if (cache.get()) |
292 { | 311 { |
297 reader.HasPixelData())) | 316 reader.HasPixelData())) |
298 { | 317 { |
299 // Reuse the DICOM file from the cache | 318 // Reuse the DICOM file from the cache |
300 return new ParseDicomFileCommand::SuccessMessage( | 319 return new ParseDicomFileCommand::SuccessMessage( |
301 command, reader.GetDicom(), reader.GetFileSize(), reader.HasPixelData()); | 320 command, reader.GetDicom(), reader.GetFileSize(), reader.HasPixelData()); |
321 emitter.EmitMessage(receiver, message); | |
322 return; | |
302 } | 323 } |
303 } | 324 } |
304 | 325 |
305 // Not in the cache, first read and parse the DICOM file | 326 // Not in the cache, first read and parse the DICOM file |
306 std::auto_ptr<ParseDicomFileCommand::SuccessMessage> message(Execute(root, command)); | 327 std::auto_ptr<ParseDicomFileCommand::SuccessMessage> message(RunInternal(root, command)); |
307 | 328 |
308 // Secondly, store it into the cache for future use | 329 // Secondly, store it into the cache for future use |
309 assert(&message->GetOrigin() == &command); | 330 assert(&message->GetOrigin() == &command); |
310 cache->Acquire(message->GetOrigin().GetPath(), message->GetDicom(), | 331 cache->Acquire(message->GetOrigin().GetPath(), message->GetDicom(), |
311 message->GetFileSize(), message->HasPixelData()); | 332 message->GetFileSize(), message->HasPixelData()); |
313 return message.release(); | 334 return message.release(); |
314 } | 335 } |
315 else | 336 else |
316 { | 337 { |
317 // No cache available | 338 // No cache available |
318 return Execute(root, command); | 339 return RunInternal(root, command); |
319 } | 340 } |
320 #else | 341 #else |
321 return Execute(root, command); | 342 return RunInternal(receiver, emitter, root, command); |
322 #endif | 343 #endif |
323 } | 344 } |
324 | 345 |
325 #endif | 346 #endif |
326 | 347 |
327 | 348 |
328 IMessage* GenericOracleRunner::Run(IOracleCommand& command) | 349 void GenericOracleRunner::Run(boost::weak_ptr<IObserver> receiver, |
329 { | 350 IMessageEmitter& emitter, |
351 IOracleCommand& command) | |
352 { | |
353 Orthanc::ErrorCode error = Orthanc::ErrorCode_Success; | |
354 | |
330 try | 355 try |
331 { | 356 { |
332 switch (command.GetType()) | 357 switch (command.GetType()) |
333 { | 358 { |
334 case IOracleCommand::Type_Sleep: | 359 case IOracleCommand::Type_Sleep: |
335 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, | 360 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, |
336 "Sleep command cannot be executed by the runner"); | 361 "Sleep command cannot be executed by the runner"); |
337 | 362 |
338 case IOracleCommand::Type_Http: | 363 case IOracleCommand::Type_Http: |
339 return Execute(dynamic_cast<const HttpCommand&>(command)); | 364 RunInternal(receiver, emitter, dynamic_cast<HttpCommand&>(command)); |
365 break; | |
340 | 366 |
341 case IOracleCommand::Type_OrthancRestApi: | 367 case IOracleCommand::Type_OrthancRestApi: |
342 return Execute(orthanc_, dynamic_cast<const OrthancRestApiCommand&>(command)); | 368 RunInternal(receiver, emitter, orthanc_, |
369 dynamic_cast<OrthancRestApiCommand&>(command)); | |
370 break; | |
343 | 371 |
344 case IOracleCommand::Type_GetOrthancImage: | 372 case IOracleCommand::Type_GetOrthancImage: |
345 return Execute(orthanc_, dynamic_cast<const GetOrthancImageCommand&>(command)); | 373 RunInternal(receiver, emitter, orthanc_, |
374 dynamic_cast<GetOrthancImageCommand&>(command)); | |
375 break; | |
346 | 376 |
347 case IOracleCommand::Type_GetOrthancWebViewerJpeg: | 377 case IOracleCommand::Type_GetOrthancWebViewerJpeg: |
348 return Execute(orthanc_, dynamic_cast<const GetOrthancWebViewerJpegCommand&>(command)); | 378 RunInternal(receiver, emitter, orthanc_, |
379 dynamic_cast<GetOrthancWebViewerJpegCommand&>(command)); | |
380 break; | |
349 | 381 |
350 case IOracleCommand::Type_ReadFile: | 382 case IOracleCommand::Type_ReadFile: |
351 return Execute(rootDirectory_, dynamic_cast<ReadFileCommand&>(command)); | 383 RunInternal(receiver, emitter, rootDirectory_, |
384 dynamic_cast<ReadFileCommand&>(command)); | |
385 break; | |
352 | 386 |
353 case IOracleCommand::Type_ParseDicomFile: | 387 case IOracleCommand::Type_ParseDicomFile: |
354 #if ORTHANC_ENABLE_DCMTK == 1 | 388 #if ORTHANC_ENABLE_DCMTK == 1 |
355 return Execute(dicomCache_, rootDirectory_, | 389 RunInternal(receiver, emitter, dicomCache_, rootDirectory_, |
356 dynamic_cast<const ParseDicomFileCommand&>(command)); | 390 dynamic_cast<ParseDicomFileCommand&>(command)); |
391 break; | |
357 #else | 392 #else |
358 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, | 393 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, |
359 "DCMTK must be enabled to parse DICOM files"); | 394 "DCMTK must be enabled to parse DICOM files"); |
360 #endif | 395 #endif |
361 | 396 |
364 } | 399 } |
365 } | 400 } |
366 catch (Orthanc::OrthancException& e) | 401 catch (Orthanc::OrthancException& e) |
367 { | 402 { |
368 LOG(ERROR) << "Exception within the oracle: " << e.What(); | 403 LOG(ERROR) << "Exception within the oracle: " << e.What(); |
369 return new OracleCommandExceptionMessage(command, e); | 404 error = e.GetErrorCode(); |
370 } | 405 } |
371 catch (...) | 406 catch (...) |
372 { | 407 { |
373 LOG(ERROR) << "Threaded exception within the oracle"; | 408 LOG(ERROR) << "Threaded exception within the oracle"; |
374 return new OracleCommandExceptionMessage(command, Orthanc::ErrorCode_InternalError); | 409 error = Orthanc::ErrorCode_InternalError; |
375 } | 410 } |
411 | |
412 OracleCommandExceptionMessage message(command, error); | |
413 emitter.EmitMessage(receiver, message); | |
376 } | 414 } |
377 } | 415 } |