comparison UnitTestsSources/MultiThreadingTests.cpp @ 2573:3372c5255333 jobs

StoreScuJob, Orthanc Explorer for jobs
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 09 May 2018 17:56:14 +0200
parents 2e879c796ec7
children 055d7d4a823f
comparison
equal deleted inserted replaced
2570:2e879c796ec7 2573:3372c5255333
601 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); 601 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success));
602 } 602 }
603 603
604 604
605 605
606 #include "../OrthancServer/ServerContext.h"
607
608 namespace Orthanc
609 {
610 class InstancesIteratorJob : public IJob
611 {
612 private:
613 bool started_;
614 std::vector<std::string> instances_;
615 size_t position_;
616
617 public:
618 InstancesIteratorJob() :
619 started_(false),
620 position_(0)
621 {
622 }
623
624 void Reserve(size_t size)
625 {
626 if (started_)
627 {
628 throw OrthancException(ErrorCode_BadSequenceOfCalls);
629 }
630 else
631 {
632 instances_.reserve(size);
633 }
634 }
635
636 void AddInstance(const std::string& instance)
637 {
638 if (started_)
639 {
640 throw OrthancException(ErrorCode_BadSequenceOfCalls);
641 }
642 else
643 {
644 instances_.push_back(instance);
645 }
646 }
647
648 virtual void Start()
649 {
650 started_ = true;
651 }
652
653 virtual float GetProgress()
654 {
655 if (instances_.size() == 0)
656 {
657 return 0;
658 }
659 else
660 {
661 return (static_cast<float>(position_) /
662 static_cast<float>(instances_.size()));
663 }
664 }
665
666 bool IsStarted() const
667 {
668 return started_;
669 }
670
671 bool IsDone() const
672 {
673 if (instances_.size() == 0)
674 {
675 return true;
676 }
677 else
678 {
679 return (position_ == instances_.size() - 1);
680 }
681 }
682
683 void Next()
684 {
685 if (IsDone())
686 {
687 throw OrthancException(ErrorCode_BadSequenceOfCalls);
688 }
689 else
690 {
691 position_ += 1;
692 }
693 }
694
695 const std::string& GetCurrentInstance() const
696 {
697 if (IsDone())
698 {
699 throw OrthancException(ErrorCode_BadSequenceOfCalls);
700 }
701 else
702 {
703 return instances_[position_];
704 }
705 }
706 };
707
708
709 class StoreScuJob : public InstancesIteratorJob
710 {
711 private:
712 ServerContext& context_;
713 std::string localAet_;
714 RemoteModalityParameters remote_;
715 bool permissive_;
716 std::string moveOriginatorAet_;
717 uint16_t moveOriginatorId_;
718 std::auto_ptr<DicomUserConnection> connection_;
719 std::set<std::string> failedInstances_;
720
721 void Open()
722 {
723 if (connection_.get() == NULL)
724 {
725 connection_.reset(new DicomUserConnection);
726 connection_->SetLocalApplicationEntityTitle(localAet_);
727 connection_->SetRemoteModality(remote_);
728 connection_->Open();
729 }
730 }
731
732 public:
733 StoreScuJob(ServerContext& context) :
734 context_(context),
735 localAet_("ORTHANC"),
736 permissive_(false),
737 moveOriginatorId_(0) // By default, not a C-MOVE
738 {
739 }
740
741 const std::string& GetLocalAet() const
742 {
743 return localAet_;
744 }
745
746 void SetLocalAet(const std::string& aet)
747 {
748 if (IsStarted())
749 {
750 throw OrthancException(ErrorCode_BadSequenceOfCalls);
751 }
752 else
753 {
754 localAet_ = aet;
755 }
756 }
757
758 const RemoteModalityParameters& GetRemoteModality() const
759 {
760 return remote_;
761 }
762
763 void SetRemoteModality(const RemoteModalityParameters& remote)
764 {
765 if (IsStarted())
766 {
767 throw OrthancException(ErrorCode_BadSequenceOfCalls);
768 }
769 else
770 {
771 remote_ = remote;
772 }
773 }
774
775 bool IsPermissive() const
776 {
777 return permissive_;
778 }
779
780 void SetPermissive(bool permissive)
781 {
782 if (IsStarted())
783 {
784 throw OrthancException(ErrorCode_BadSequenceOfCalls);
785 }
786 else
787 {
788 permissive_ = permissive;
789 }
790 }
791
792 bool HasMoveOriginator() const
793 {
794 return moveOriginatorId_ != 0;
795 }
796
797 const std::string& GetMoveOriginatorAet() const
798 {
799 if (HasMoveOriginator())
800 {
801 return moveOriginatorAet_;
802 }
803 else
804 {
805 throw OrthancException(ErrorCode_BadSequenceOfCalls);
806 }
807 }
808
809 uint16_t GetMoveOriginatorId() const
810 {
811 if (HasMoveOriginator())
812 {
813 return moveOriginatorId_;
814 }
815 else
816 {
817 throw OrthancException(ErrorCode_BadSequenceOfCalls);
818 }
819 }
820
821 void SetMoveOriginator(const std::string& aet,
822 int id)
823 {
824 if (IsStarted())
825 {
826 throw OrthancException(ErrorCode_BadSequenceOfCalls);
827 }
828 else if (id < 0 ||
829 id >= 65536)
830 {
831 throw OrthancException(ErrorCode_ParameterOutOfRange);
832 }
833 else
834 {
835 moveOriginatorId_ = static_cast<uint16_t>(id);
836 moveOriginatorAet_ = aet;
837 }
838 }
839
840 virtual JobStepResult* ExecuteStep()
841 {
842 if (IsDone())
843 {
844 return new JobStepResult(JobStepCode_Success);
845 }
846
847 Open();
848
849 bool ok = false;
850
851 try
852 {
853 std::string dicom;
854 context_.ReadDicom(dicom, GetCurrentInstance());
855
856 if (HasMoveOriginator())
857 {
858 connection_->Store(dicom, moveOriginatorAet_, moveOriginatorId_);
859 }
860 else
861 {
862 connection_->Store(dicom);
863 }
864
865 ok = true;
866 }
867 catch (OrthancException& e)
868 {
869 }
870
871 if (!ok)
872 {
873 if (permissive_)
874 {
875 failedInstances_.insert(GetCurrentInstance());
876 }
877 else
878 {
879 return new JobStepResult(JobStepCode_Failure);
880 }
881 }
882
883 Next();
884
885 return new JobStepResult(IsDone() ? JobStepCode_Success : JobStepCode_Continue);
886 }
887
888 virtual void ReleaseResources() // For pausing jobs
889 {
890 connection_.release();
891 }
892
893 virtual void GetDescription(Json::Value& value)
894 {
895 value["Type"] = "C-STORE";
896 value["LocalAet"] = localAet_;
897
898 Json::Value v;
899 remote_.ToJson(v);
900 value["Target"] = v;
901
902 if (HasMoveOriginator())
903 {
904 value["MoveOriginatorAET"] = GetMoveOriginatorAet();
905 value["MoveOriginatorID"] = GetMoveOriginatorId();
906 }
907
908 v = Json::arrayValue;
909 for (std::set<std::string>::const_iterator it = failedInstances_.begin();
910 it != failedInstances_.end(); ++it)
911 {
912 v.append(*it);
913 }
914
915 value["FailedInstances"] = v;
916 }
917 };
918 }
919
920
921 606
922 TEST(JobsEngine, Basic) 607 TEST(JobsEngine, Basic)
923 { 608 {
924 JobsEngine engine; 609 JobsEngine engine;
925 610