comparison Samples/Sdl/Loader.cpp @ 639:d1f4521b9bbb

OracleCommandExceptionMessage
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 10 May 2019 10:35:46 +0200
parents e626f38c5512
children e706188d6078
comparison
equal deleted inserted replaced
638:e626f38c5512 639:d1f4521b9bbb
136 } 136 }
137 }; 137 };
138 138
139 139
140 140
141 class OracleCommandExceptionMessage :
142 public OrthancStone::BaseMessage<OrthancStone::MessageType_OrthancException>
143 {
144 private:
145 const IOracleCommand& command_;
146 Orthanc::OrthancException exception_;
147
148 public:
149 OracleCommandExceptionMessage(const IOracleCommand& command,
150 const Orthanc::OrthancException& exception) :
151 command_(command),
152 exception_(exception)
153 {
154 }
155
156 OracleCommandExceptionMessage(const IOracleCommand& command,
157 const Orthanc::ErrorCode& error) :
158 command_(command),
159 exception_(error)
160 {
161 }
162
163 const IOracleCommand& GetCommand() const
164 {
165 return command_;
166 }
167
168 const Orthanc::OrthancException& GetException() const
169 {
170 return exception_;
171 }
172 };
173
174
141 typedef std::map<std::string, std::string> HttpHeaders; 175 typedef std::map<std::string, std::string> HttpHeaders;
142 176
143 class OrthancRestApiCommand : public OracleCommandWithPayload 177 class OrthancRestApiCommand : public OracleCommandWithPayload
144 { 178 {
145 public: 179 public:
179 return headers_; 213 return headers_;
180 } 214 }
181 }; 215 };
182 216
183 217
184 class FailureMessage : public OrthancStone::OriginMessage<OrthancStone::MessageType_HttpRequestError, // TODO
185 OrthancRestApiCommand>
186 {
187 private:
188 Orthanc::HttpStatus status_;
189
190 public:
191 FailureMessage(const OrthancRestApiCommand& command,
192 Orthanc::HttpStatus status) :
193 OriginMessage(command),
194 status_(status)
195 {
196 }
197
198 Orthanc::HttpStatus GetHttpStatus() const
199 {
200 return status_;
201 }
202 };
203
204
205 private: 218 private:
206 Orthanc::HttpMethod method_; 219 Orthanc::HttpMethod method_;
207 std::string uri_; 220 std::string uri_;
208 std::string body_; 221 std::string body_;
209 HttpHeaders headers_; 222 HttpHeaders headers_;
210 unsigned int timeout_; 223 unsigned int timeout_;
211 224
212 std::auto_ptr< OrthancStone::MessageHandler<SuccessMessage> > successCallback_; 225 std::auto_ptr< OrthancStone::MessageHandler<SuccessMessage> > successCallback_;
213 std::auto_ptr< OrthancStone::MessageHandler<FailureMessage> > failureCallback_; 226 std::auto_ptr< OrthancStone::MessageHandler<OracleCommandExceptionMessage> > failureCallback_;
214 227
215 public: 228 public:
216 OrthancRestApiCommand() : 229 OrthancRestApiCommand() :
217 method_(Orthanc::HttpMethod_Get), 230 method_(Orthanc::HttpMethod_Get),
218 uri_("/"), 231 uri_("/"),
333 return mime_; 346 return mime_;
334 } 347 }
335 }; 348 };
336 349
337 350
338 class FailureMessage : public OrthancStone::OriginMessage<OrthancStone::MessageType_HttpRequestError, // TODO
339 DecodeOrthancImageCommand>
340 {
341 private:
342 Orthanc::HttpStatus status_;
343
344 public:
345 FailureMessage(const DecodeOrthancImageCommand& command,
346 Orthanc::HttpStatus status) :
347 OriginMessage(command),
348 status_(status)
349 {
350 }
351
352 Orthanc::HttpStatus GetHttpStatus() const
353 {
354 return status_;
355 }
356 };
357
358
359 private: 351 private:
360 std::string uri_; 352 std::string uri_;
361 HttpHeaders headers_; 353 HttpHeaders headers_;
362 unsigned int timeout_; 354 unsigned int timeout_;
363 355
364 std::auto_ptr< OrthancStone::MessageHandler<SuccessMessage> > successCallback_; 356 std::auto_ptr< OrthancStone::MessageHandler<SuccessMessage> > successCallback_;
365 std::auto_ptr< OrthancStone::MessageHandler<FailureMessage> > failureCallback_; 357 std::auto_ptr< OrthancStone::MessageHandler<OracleCommandExceptionMessage> > failureCallback_;
366 358
367 public: 359 public:
368 DecodeOrthancImageCommand() : 360 DecodeOrthancImageCommand() :
369 uri_("/"), 361 uri_("/"),
370 timeout_(10) 362 timeout_(10)
434 const Orthanc::ImageAccessor& GetImage() const 426 const Orthanc::ImageAccessor& GetImage() const
435 { 427 {
436 return *image_; 428 return *image_;
437 } 429 }
438 }; 430 };
439
440
441 class FailureMessage : public OrthancStone::OriginMessage<OrthancStone::MessageType_HttpRequestError, // TODO
442 DecodeOrthancWebViewerJpegCommand>
443 {
444 private:
445 Orthanc::HttpStatus status_;
446
447 public:
448 FailureMessage(const DecodeOrthancWebViewerJpegCommand& command,
449 Orthanc::HttpStatus status) :
450 OriginMessage(command),
451 status_(status)
452 {
453 }
454
455 Orthanc::HttpStatus GetHttpStatus() const
456 {
457 return status_;
458 }
459 };
460
461 431
462 private: 432 private:
463 std::string instanceId_; 433 std::string instanceId_;
464 unsigned int frame_; 434 unsigned int frame_;
465 unsigned int quality_; 435 unsigned int quality_;
466 HttpHeaders headers_; 436 HttpHeaders headers_;
467 unsigned int timeout_; 437 unsigned int timeout_;
468 438
469 std::auto_ptr< OrthancStone::MessageHandler<SuccessMessage> > successCallback_; 439 std::auto_ptr< OrthancStone::MessageHandler<SuccessMessage> > successCallback_;
470 std::auto_ptr< OrthancStone::MessageHandler<FailureMessage> > failureCallback_; 440 std::auto_ptr< OrthancStone::MessageHandler<OracleCommandExceptionMessage> > failureCallback_;
471 441
472 public: 442 public:
473 DecodeOrthancWebViewerJpegCommand() : 443 DecodeOrthancWebViewerJpegCommand() :
474 frame_(0), 444 frame_(0),
475 quality_(95), 445 quality_(95),
666 client.SetBody(command.GetBody()); 636 client.SetBody(command.GetBody());
667 } 637 }
668 638
669 std::string answer; 639 std::string answer;
670 HttpHeaders answerHeaders; 640 HttpHeaders answerHeaders;
671 641 client.ApplyAndThrowException(answer, answerHeaders);
672 bool success; 642
673 try 643 DecodeAnswer(answer, answerHeaders);
674 { 644
675 success = client.Apply(answer, answerHeaders); 645 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer);
676 DecodeAnswer(answer, answerHeaders); 646 emitter_.EmitMessage(receiver, message);
677 }
678 catch (Orthanc::OrthancException& e)
679 {
680 success = false;
681 }
682
683 if (success)
684 {
685 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer);
686 emitter_.EmitMessage(receiver, message);
687 }
688 else
689 {
690 OrthancRestApiCommand::FailureMessage message(command, client.GetLastStatus());
691 emitter_.EmitMessage(receiver, message);
692 }
693 } 647 }
694 648
695 649
696 void Execute(const OrthancStone::IObserver& receiver, 650 void Execute(const OrthancStone::IObserver& receiver,
697 const DecodeOrthancImageCommand& command) 651 const DecodeOrthancImageCommand& command)
701 655
702 CopyHttpHeaders(client, command.GetHttpHeaders()); 656 CopyHttpHeaders(client, command.GetHttpHeaders());
703 657
704 std::string answer; 658 std::string answer;
705 HttpHeaders answerHeaders; 659 HttpHeaders answerHeaders;
706 660 client.ApplyAndThrowException(answer, answerHeaders);
707 bool success; 661
708 try 662 DecodeAnswer(answer, answerHeaders);
709 { 663
710 success = client.Apply(answer, answerHeaders); 664 Orthanc::MimeType contentType = Orthanc::MimeType_Binary;
711 } 665
712 catch (Orthanc::OrthancException& e) 666 for (HttpHeaders::const_iterator it = answerHeaders.begin();
713 { 667 it != answerHeaders.end(); ++it)
714 success = false; 668 {
715 } 669 std::string s;
716 670 Orthanc::Toolbox::ToLowerCase(s, it->first);
717 if (success) 671
718 { 672 if (s == "content-type")
719 DecodeAnswer(answer, answerHeaders); 673 {
720 674 contentType = Orthanc::StringToMimeType(it->second);
721 Orthanc::MimeType contentType = Orthanc::MimeType_Binary; 675 break;
722 676 }
723 for (HttpHeaders::const_iterator it = answerHeaders.begin(); 677 }
724 it != answerHeaders.end(); ++it) 678
725 { 679 std::auto_ptr<Orthanc::ImageAccessor> image;
726 std::string s; 680
727 Orthanc::Toolbox::ToLowerCase(s, it->first); 681 switch (contentType)
728 682 {
729 if (s == "content-type") 683 case Orthanc::MimeType_Png:
730 { 684 {
731 contentType = Orthanc::StringToMimeType(it->second); 685 image.reset(new Orthanc::PngReader);
732 break; 686 dynamic_cast<Orthanc::PngReader&>(*image).ReadFromMemory(answer);
733 } 687 break;
734 } 688 }
735 689
736 std::auto_ptr<Orthanc::ImageAccessor> image; 690 case Orthanc::MimeType_Pam:
737 691 {
738 switch (contentType) 692 image.reset(new Orthanc::PamReader);
739 { 693 dynamic_cast<Orthanc::PamReader&>(*image).ReadFromMemory(answer);
740 case Orthanc::MimeType_Png: 694 break;
741 { 695 }
742 image.reset(new Orthanc::PngReader); 696
743 dynamic_cast<Orthanc::PngReader&>(*image).ReadFromMemory(answer); 697 case Orthanc::MimeType_Jpeg:
744 break; 698 {
745 } 699 image.reset(new Orthanc::JpegReader);
746 700 dynamic_cast<Orthanc::JpegReader&>(*image).ReadFromMemory(answer);
747 case Orthanc::MimeType_Pam: 701 break;
748 { 702 }
749 image.reset(new Orthanc::PamReader); 703
750 dynamic_cast<Orthanc::PamReader&>(*image).ReadFromMemory(answer); 704 default:
751 break; 705 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol,
752 } 706 "Unsupported HTTP Content-Type for an image: " +
753 707 std::string(Orthanc::EnumerationToString(contentType)));
754 case Orthanc::MimeType_Jpeg: 708 }
755 { 709
756 image.reset(new Orthanc::JpegReader); 710 DecodeOrthancImageCommand::SuccessMessage message(command, image.release(), contentType);
757 dynamic_cast<Orthanc::JpegReader&>(*image).ReadFromMemory(answer); 711 emitter_.EmitMessage(receiver, message);
758 break;
759 }
760
761 default:
762 // TODO - Emit error message?
763 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol,
764 "Unsupported HTTP Content-Type for an image: " +
765 std::string(Orthanc::EnumerationToString(contentType)));
766 }
767
768 DecodeOrthancImageCommand::SuccessMessage message(command, image.release(), contentType);
769 emitter_.EmitMessage(receiver, message);
770 }
771 else
772 {
773 DecodeOrthancImageCommand::FailureMessage message(command, client.GetLastStatus());
774 emitter_.EmitMessage(receiver, message);
775 }
776 } 712 }
777 713
778 714
779 void Execute(const OrthancStone::IObserver& receiver, 715 void Execute(const OrthancStone::IObserver& receiver,
780 const DecodeOrthancWebViewerJpegCommand& command) 716 const DecodeOrthancWebViewerJpegCommand& command)
784 720
785 CopyHttpHeaders(client, command.GetHttpHeaders()); 721 CopyHttpHeaders(client, command.GetHttpHeaders());
786 722
787 std::string answer; 723 std::string answer;
788 HttpHeaders answerHeaders; 724 HttpHeaders answerHeaders;
789 725 client.ApplyAndThrowException(answer, answerHeaders);
790 bool success; 726
791 try 727 DecodeAnswer(answer, answerHeaders);
792 { 728
793 success = client.Apply(answer, answerHeaders); 729 Json::Value value;
794 } 730 Json::Reader reader;
795 catch (Orthanc::OrthancException& e) 731 if (reader.parse(answer, value))
796 { 732 {
797 success = false; 733 std::cout << value.toStyledString() << std::endl;
798 } 734 }
799 735
800 if (success) 736 //DecodeOrthancWebViewerJpegCommand::SuccessMessage message(command, image.release(), contentType);
801 { 737 //emitter_.EmitMessage(receiver, message);
802 DecodeAnswer(answer, answerHeaders);
803
804 Json::Value value;
805 Json::Reader reader;
806 if (reader.parse(answer, value))
807 {
808 std::cout << value.toStyledString() << std::endl;
809 }
810
811 //DecodeOrthancWebViewerJpegCommand::SuccessMessage message(command, image.release(), contentType);
812 //emitter_.EmitMessage(receiver, message);
813 }
814 else
815 {
816 DecodeOrthancWebViewerJpegCommand::FailureMessage message(command, client.GetLastStatus());
817 emitter_.EmitMessage(receiver, message);
818 }
819 } 738 }
820 739
821 740
822 741
823 void Step() 742 void Step()
852 } 771 }
853 } 772 }
854 catch (Orthanc::OrthancException& e) 773 catch (Orthanc::OrthancException& e)
855 { 774 {
856 LOG(ERROR) << "Exception within the oracle: " << e.What(); 775 LOG(ERROR) << "Exception within the oracle: " << e.What();
776 emitter_.EmitMessage(item.GetReceiver(), OracleCommandExceptionMessage(item.GetCommand(), e));
857 } 777 }
858 catch (...) 778 catch (...)
859 { 779 {
860 LOG(ERROR) << "Native exception within the oracle"; 780 LOG(ERROR) << "Native exception within the oracle";
781 emitter_.EmitMessage(item.GetReceiver(), OracleCommandExceptionMessage
782 (item.GetCommand(), Orthanc::ErrorCode_InternalError));
861 } 783 }
862 } 784 }
863 } 785 }
864 786
865 787
1006 928
1007 929
1008 virtual void EmitMessage(const OrthancStone::IObserver& observer, 930 virtual void EmitMessage(const OrthancStone::IObserver& observer,
1009 const OrthancStone::IMessage& message) 931 const OrthancStone::IMessage& message)
1010 { 932 {
1011 boost::unique_lock<boost::shared_mutex> lock(mutex_); 933 try
1012 oracleObservable_.EmitMessage(observer, message); 934 {
935 boost::unique_lock<boost::shared_mutex> lock(mutex_);
936 oracleObservable_.EmitMessage(observer, message);
937 }
938 catch (Orthanc::OrthancException& e)
939 {
940 LOG(ERROR) << "Exception while emitting a message: " << e.What();
941 }
1013 } 942 }
1014 943
1015 944
1016 class ReaderLock : public boost::noncopyable 945 class ReaderLock : public boost::noncopyable
1017 { 946 {
1518 void Handle(const Refactoring::DecodeOrthancImageCommand::SuccessMessage& message) 1447 void Handle(const Refactoring::DecodeOrthancImageCommand::SuccessMessage& message)
1519 { 1448 {
1520 printf("IMAGE %dx%d\n", message.GetImage().GetWidth(), message.GetImage().GetHeight()); 1449 printf("IMAGE %dx%d\n", message.GetImage().GetWidth(), message.GetImage().GetHeight());
1521 } 1450 }
1522 1451
1523 void Handle(const Refactoring::OrthancRestApiCommand::FailureMessage& message) 1452 void Handle(const Refactoring::OracleCommandExceptionMessage& message)
1524 { 1453 {
1525 printf("ERROR %d\n", message.GetHttpStatus()); 1454 printf("EXCEPTION: [%s] on command type %d\n", message.GetException().What(), message.GetCommand().GetType());
1455
1456 switch (message.GetCommand().GetType())
1457 {
1458 case Refactoring::IOracleCommand::Type_DecodeOrthancWebViewerJpeg:
1459 printf("URI: [%s]\n", dynamic_cast<const Refactoring::DecodeOrthancWebViewerJpegCommand&>
1460 (message.GetCommand()).GetUri().c_str());
1461 break;
1462
1463 default:
1464 break;
1465 }
1526 } 1466 }
1527 1467
1528 public: 1468 public:
1529 Toto(OrthancStone::IObservable& oracle) : 1469 Toto(OrthancStone::IObservable& oracle) :
1530 IObserver(oracle.GetBroker()) 1470 IObserver(oracle.GetBroker())
1534 <Toto, Refactoring::OrthancRestApiCommand::SuccessMessage>(*this, &Toto::Handle)); 1474 <Toto, Refactoring::OrthancRestApiCommand::SuccessMessage>(*this, &Toto::Handle));
1535 1475
1536 oracle.RegisterObserverCallback 1476 oracle.RegisterObserverCallback
1537 (new OrthancStone::Callable 1477 (new OrthancStone::Callable
1538 <Toto, Refactoring::DecodeOrthancImageCommand::SuccessMessage>(*this, &Toto::Handle)); 1478 <Toto, Refactoring::DecodeOrthancImageCommand::SuccessMessage>(*this, &Toto::Handle));
1479
1480 oracle.RegisterObserverCallback
1481 (new OrthancStone::Callable
1482 <Toto, Refactoring::OracleCommandExceptionMessage>(*this, &Toto::Handle));
1539 } 1483 }
1540 }; 1484 };
1541 1485
1542 1486
1543 void Run(Refactoring::NativeApplicationContext& context) 1487 void Run(Refactoring::NativeApplicationContext& context)