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