Mercurial > hg > orthanc-stone
comparison Framework/Oracle/ThreadedOracle.cpp @ 1077:d7a18a3cd6f9 broker
IOracleRunner
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 17 Oct 2019 16:51:41 +0200 |
parents | 81b29bc7c3d4 |
children | 4383382db01d |
comparison
equal
deleted
inserted
replaced
1076:008dbc4ceb62 | 1077:d7a18a3cd6f9 |
---|---|
19 **/ | 19 **/ |
20 | 20 |
21 | 21 |
22 #include "ThreadedOracle.h" | 22 #include "ThreadedOracle.h" |
23 | 23 |
24 #include "GetOrthancImageCommand.h" | |
25 #include "GetOrthancWebViewerJpegCommand.h" | |
26 #include "HttpCommand.h" | |
27 #include "OrthancRestApiCommand.h" | |
28 #include "SleepOracleCommand.h" | 24 #include "SleepOracleCommand.h" |
29 #include "OracleCommandExceptionMessage.h" | 25 |
30 | 26 #include <Core/Logging.h> |
31 #include <Core/Compression/GzipCompressor.h> | |
32 #include <Core/HttpClient.h> | |
33 #include <Core/OrthancException.h> | 27 #include <Core/OrthancException.h> |
34 #include <Core/Toolbox.h> | |
35 | |
36 | 28 |
37 namespace OrthancStone | 29 namespace OrthancStone |
38 { | 30 { |
39 class ThreadedOracle::Item : public Orthanc::IDynamicObject | 31 class ThreadedOracle::Item : public Orthanc::IDynamicObject |
40 { | 32 { |
158 content_ = stillSleeping; | 150 content_ = stillSleeping; |
159 } | 151 } |
160 }; | 152 }; |
161 | 153 |
162 | 154 |
163 static void CopyHttpHeaders(Orthanc::HttpClient& client, | 155 void ThreadedOracle::Step() |
164 const Orthanc::HttpClient::HttpHeaders& headers) | 156 { |
165 { | 157 std::auto_ptr<Orthanc::IDynamicObject> object(queue_.Dequeue(100)); |
166 for (Orthanc::HttpClient::HttpHeaders::const_iterator | 158 |
167 it = headers.begin(); it != headers.end(); it++ ) | 159 if (object.get() != NULL) |
168 { | 160 { |
169 client.AddHeader(it->first, it->second); | 161 Item& item = dynamic_cast<Item&>(*object); |
170 } | 162 |
171 } | 163 if (item.GetCommand().GetType() == IOracleCommand::Type_Sleep) |
172 | 164 { |
173 | 165 SleepOracleCommand& command = dynamic_cast<SleepOracleCommand&>(item.GetCommand()); |
174 static void DecodeAnswer(std::string& answer, | |
175 const Orthanc::HttpClient::HttpHeaders& headers) | |
176 { | |
177 Orthanc::HttpCompression contentEncoding = Orthanc::HttpCompression_None; | |
178 | |
179 for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); | |
180 it != headers.end(); ++it) | |
181 { | |
182 std::string s; | |
183 Orthanc::Toolbox::ToLowerCase(s, it->first); | |
184 | |
185 if (s == "content-encoding") | |
186 { | |
187 if (it->second == "gzip") | |
188 { | |
189 contentEncoding = Orthanc::HttpCompression_Gzip; | |
190 } | |
191 else | |
192 { | |
193 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, | |
194 "Unsupported HTTP Content-Encoding: " + it->second); | |
195 } | |
196 | |
197 break; | |
198 } | |
199 } | |
200 | |
201 if (contentEncoding == Orthanc::HttpCompression_Gzip) | |
202 { | |
203 std::string compressed; | |
204 answer.swap(compressed); | |
205 | 166 |
206 Orthanc::GzipCompressor compressor; | 167 std::auto_ptr<SleepOracleCommand> copy(new SleepOracleCommand(command.GetDelay())); |
207 compressor.Uncompress(answer, compressed.c_str(), compressed.size()); | 168 |
208 | 169 if (command.HasPayload()) |
209 LOG(INFO) << "Uncompressing gzip Encoding: from " << compressed.size() | 170 { |
210 << " to " << answer.size() << " bytes"; | 171 copy->SetPayload(command.ReleasePayload()); |
211 } | 172 } |
212 } | 173 |
213 | 174 sleepingCommands_->Add(item.GetReceiver(), copy.release()); |
214 | 175 } |
215 static void Execute(IMessageEmitter& emitter, | 176 else |
216 boost::weak_ptr<IObserver>& receiver, | 177 { |
217 const HttpCommand& command) | 178 GenericOracleRunner runner(emitter_, orthanc_); |
218 { | 179 runner.Run(item.GetReceiver(), item.GetCommand()); |
219 Orthanc::HttpClient client; | |
220 client.SetUrl(command.GetUrl()); | |
221 client.SetMethod(command.GetMethod()); | |
222 client.SetTimeout(command.GetTimeout()); | |
223 | |
224 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
225 | |
226 if (command.GetMethod() == Orthanc::HttpMethod_Post || | |
227 command.GetMethod() == Orthanc::HttpMethod_Put) | |
228 { | |
229 client.SetBody(command.GetBody()); | |
230 } | |
231 | |
232 std::string answer; | |
233 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
234 client.ApplyAndThrowException(answer, answerHeaders); | |
235 | |
236 DecodeAnswer(answer, answerHeaders); | |
237 | |
238 HttpCommand::SuccessMessage message(command, answerHeaders, answer); | |
239 emitter.EmitMessage(receiver, message); | |
240 } | |
241 | |
242 | |
243 static void Execute(IMessageEmitter& emitter, | |
244 const Orthanc::WebServiceParameters& orthanc, | |
245 boost::weak_ptr<IObserver>& receiver, | |
246 const OrthancRestApiCommand& command) | |
247 { | |
248 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
249 client.SetMethod(command.GetMethod()); | |
250 client.SetTimeout(command.GetTimeout()); | |
251 | |
252 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
253 | |
254 if (command.GetMethod() == Orthanc::HttpMethod_Post || | |
255 command.GetMethod() == Orthanc::HttpMethod_Put) | |
256 { | |
257 client.SetBody(command.GetBody()); | |
258 } | |
259 | |
260 std::string answer; | |
261 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
262 client.ApplyAndThrowException(answer, answerHeaders); | |
263 | |
264 DecodeAnswer(answer, answerHeaders); | |
265 | |
266 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); | |
267 emitter.EmitMessage(receiver, message); | |
268 } | |
269 | |
270 | |
271 static void Execute(IMessageEmitter& emitter, | |
272 const Orthanc::WebServiceParameters& orthanc, | |
273 boost::weak_ptr<IObserver>& receiver, | |
274 const GetOrthancImageCommand& command) | |
275 { | |
276 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
277 client.SetTimeout(command.GetTimeout()); | |
278 | |
279 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
280 | |
281 std::string answer; | |
282 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
283 client.ApplyAndThrowException(answer, answerHeaders); | |
284 | |
285 DecodeAnswer(answer, answerHeaders); | |
286 | |
287 command.ProcessHttpAnswer(emitter, receiver, answer, answerHeaders); | |
288 } | |
289 | |
290 | |
291 static void Execute(IMessageEmitter& emitter, | |
292 const Orthanc::WebServiceParameters& orthanc, | |
293 boost::weak_ptr<IObserver>& receiver, | |
294 const GetOrthancWebViewerJpegCommand& command) | |
295 { | |
296 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
297 client.SetTimeout(command.GetTimeout()); | |
298 | |
299 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
300 | |
301 std::string answer; | |
302 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
303 client.ApplyAndThrowException(answer, answerHeaders); | |
304 | |
305 DecodeAnswer(answer, answerHeaders); | |
306 | |
307 command.ProcessHttpAnswer(emitter, receiver, answer); | |
308 } | |
309 | |
310 | |
311 void ThreadedOracle::Step() | |
312 { | |
313 std::auto_ptr<Orthanc::IDynamicObject> object(queue_.Dequeue(100)); | |
314 | |
315 if (object.get() != NULL) | |
316 { | |
317 Item& item = dynamic_cast<Item&>(*object); | |
318 | |
319 try | |
320 { | |
321 switch (item.GetCommand().GetType()) | |
322 { | |
323 case IOracleCommand::Type_Sleep: | |
324 { | |
325 SleepOracleCommand& command = dynamic_cast<SleepOracleCommand&>(item.GetCommand()); | |
326 | |
327 std::auto_ptr<SleepOracleCommand> copy(new SleepOracleCommand(command.GetDelay())); | |
328 | |
329 if (command.HasPayload()) | |
330 { | |
331 copy->SetPayload(command.ReleasePayload()); | |
332 } | |
333 | |
334 sleepingCommands_->Add(item.GetReceiver(), copy.release()); | |
335 | |
336 break; | |
337 } | |
338 | |
339 case IOracleCommand::Type_Http: | |
340 Execute(emitter_, item.GetReceiver(), | |
341 dynamic_cast<const HttpCommand&>(item.GetCommand())); | |
342 break; | |
343 | |
344 case IOracleCommand::Type_OrthancRestApi: | |
345 Execute(emitter_, orthanc_, item.GetReceiver(), | |
346 dynamic_cast<const OrthancRestApiCommand&>(item.GetCommand())); | |
347 break; | |
348 | |
349 case IOracleCommand::Type_GetOrthancImage: | |
350 Execute(emitter_, orthanc_, item.GetReceiver(), | |
351 dynamic_cast<const GetOrthancImageCommand&>(item.GetCommand())); | |
352 break; | |
353 | |
354 case IOracleCommand::Type_GetOrthancWebViewerJpeg: | |
355 Execute(emitter_, orthanc_, item.GetReceiver(), | |
356 dynamic_cast<const GetOrthancWebViewerJpegCommand&>(item.GetCommand())); | |
357 break; | |
358 | |
359 default: | |
360 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
361 } | |
362 } | |
363 catch (Orthanc::OrthancException& e) | |
364 { | |
365 LOG(ERROR) << "Exception within the oracle: " << e.What(); | |
366 emitter_.EmitMessage(item.GetReceiver(), OracleCommandExceptionMessage(item.GetCommand(), e)); | |
367 } | |
368 catch (...) | |
369 { | |
370 LOG(ERROR) << "Threaded exception within the oracle"; | |
371 emitter_.EmitMessage(item.GetReceiver(), OracleCommandExceptionMessage | |
372 (item.GetCommand(), Orthanc::ErrorCode_InternalError)); | |
373 } | 180 } |
374 } | 181 } |
375 } | 182 } |
376 | 183 |
377 | 184 |