Mercurial > hg > orthanc
comparison Plugins/Engine/OrthancPlugins.cpp @ 1999:364cc624eb65
New URI "/modalities/.../move" to issue C-Move SCU requests
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 26 May 2016 14:24:56 +0200 |
parents | f0acfa753973 |
children | 39329372b667 |
comparison
equal
deleted
inserted
replaced
1998:9b61701c35f2 | 1999:364cc624eb65 |
---|---|
314 OnStoredCallbacks onStoredCallbacks_; | 314 OnStoredCallbacks onStoredCallbacks_; |
315 OnChangeCallbacks onChangeCallbacks_; | 315 OnChangeCallbacks onChangeCallbacks_; |
316 OrthancPluginFindCallback findCallback_; | 316 OrthancPluginFindCallback findCallback_; |
317 OrthancPluginWorklistCallback worklistCallback_; | 317 OrthancPluginWorklistCallback worklistCallback_; |
318 OrthancPluginDecodeImageCallback decodeImageCallback_; | 318 OrthancPluginDecodeImageCallback decodeImageCallback_; |
319 _OrthancPluginMoveCallback moveCallbacks_; | |
319 IncomingHttpRequestFilters incomingHttpRequestFilters_; | 320 IncomingHttpRequestFilters incomingHttpRequestFilters_; |
320 std::auto_ptr<StorageAreaFactory> storageArea_; | 321 std::auto_ptr<StorageAreaFactory> storageArea_; |
321 boost::recursive_mutex restCallbackMutex_; | 322 boost::recursive_mutex restCallbackMutex_; |
322 boost::recursive_mutex storedCallbackMutex_; | 323 boost::recursive_mutex storedCallbackMutex_; |
323 boost::recursive_mutex changeCallbackMutex_; | 324 boost::recursive_mutex changeCallbackMutex_; |
324 boost::mutex findCallbackMutex_; | 325 boost::mutex findCallbackMutex_; |
326 boost::mutex moveCallbackMutex_; | |
325 boost::mutex worklistCallbackMutex_; | 327 boost::mutex worklistCallbackMutex_; |
326 boost::mutex decodeImageCallbackMutex_; | 328 boost::mutex decodeImageCallbackMutex_; |
327 boost::recursive_mutex invokeServiceMutex_; | 329 boost::recursive_mutex invokeServiceMutex_; |
328 Properties properties_; | 330 Properties properties_; |
329 int argc_; | 331 int argc_; |
337 worklistCallback_(NULL), | 339 worklistCallback_(NULL), |
338 decodeImageCallback_(NULL), | 340 decodeImageCallback_(NULL), |
339 argc_(1), | 341 argc_(1), |
340 argv_(NULL) | 342 argv_(NULL) |
341 { | 343 { |
344 memset(&moveCallbacks_, 0, sizeof(moveCallbacks_)); | |
342 } | 345 } |
343 }; | 346 }; |
344 | 347 |
345 | 348 |
346 | 349 |
533 } | 536 } |
534 | 537 |
535 default: | 538 default: |
536 throw OrthancException(ErrorCode_InternalError); | 539 throw OrthancException(ErrorCode_InternalError); |
537 } | 540 } |
541 } | |
542 }; | |
543 | |
544 | |
545 | |
546 class OrthancPlugins::MoveHandler : public IMoveRequestHandler | |
547 { | |
548 private: | |
549 class Driver : public IMoveRequestIterator | |
550 { | |
551 private: | |
552 void* driver_; | |
553 unsigned int count_; | |
554 unsigned int pos_; | |
555 OrthancPluginApplyMove apply_; | |
556 OrthancPluginFreeMove free_; | |
557 | |
558 public: | |
559 Driver(void* driver, | |
560 unsigned int count, | |
561 OrthancPluginApplyMove apply, | |
562 OrthancPluginFreeMove free) : | |
563 driver_(driver), | |
564 count_(count), | |
565 pos_(0), | |
566 apply_(apply), | |
567 free_(free) | |
568 { | |
569 if (driver_ == NULL) | |
570 { | |
571 throw OrthancException(ErrorCode_Plugin); | |
572 } | |
573 } | |
574 | |
575 virtual ~Driver() | |
576 { | |
577 if (driver_ != NULL) | |
578 { | |
579 free_(driver_); | |
580 driver_ = NULL; | |
581 } | |
582 } | |
583 | |
584 virtual unsigned int GetSubOperationCount() const | |
585 { | |
586 return count_; | |
587 } | |
588 | |
589 virtual Status DoNext() | |
590 { | |
591 if (pos_ >= count_) | |
592 { | |
593 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
594 } | |
595 else | |
596 { | |
597 OrthancPluginErrorCode error = apply_(driver_); | |
598 if (error != OrthancPluginErrorCode_Success) | |
599 { | |
600 LOG(ERROR) << "Error while doing C-Move from plugin: " << EnumerationToString(static_cast<ErrorCode>(error)); | |
601 return Status_Failure; | |
602 } | |
603 else | |
604 { | |
605 pos_++; | |
606 return Status_Success; | |
607 } | |
608 } | |
609 } | |
610 }; | |
611 | |
612 | |
613 _OrthancPluginMoveCallback params_; | |
614 | |
615 | |
616 static std::string ReadTag(const DicomMap& input, | |
617 const DicomTag& tag) | |
618 { | |
619 const DicomValue* value = input.TestAndGetValue(tag); | |
620 if (value != NULL && | |
621 !value->IsBinary() && | |
622 !value->IsNull()) | |
623 { | |
624 return value->GetContent(); | |
625 } | |
626 else | |
627 { | |
628 return std::string(); | |
629 } | |
630 } | |
631 | |
632 | |
633 | |
634 public: | |
635 MoveHandler(OrthancPlugins& that) | |
636 { | |
637 boost::mutex::scoped_lock lock(that.pimpl_->moveCallbackMutex_); | |
638 params_ = that.pimpl_->moveCallbacks_; | |
639 | |
640 if (params_.callback == NULL || | |
641 params_.getMoveSize == NULL || | |
642 params_.applyMove == NULL || | |
643 params_.freeMove == NULL) | |
644 { | |
645 throw OrthancException(ErrorCode_Plugin); | |
646 } | |
647 } | |
648 | |
649 virtual IMoveRequestIterator* Handle(const std::string& targetAet, | |
650 const DicomMap& input, | |
651 const std::string& remoteIp, | |
652 const std::string& remoteAet, | |
653 const std::string& calledAet, | |
654 uint16_t messageId) | |
655 { | |
656 std::string levelString = ReadTag(input, DICOM_TAG_QUERY_RETRIEVE_LEVEL); | |
657 std::string patientId = ReadTag(input, DICOM_TAG_PATIENT_ID); | |
658 std::string accessionNumber = ReadTag(input, DICOM_TAG_ACCESSION_NUMBER); | |
659 std::string studyInstanceUid = ReadTag(input, DICOM_TAG_STUDY_INSTANCE_UID); | |
660 std::string seriesInstanceUid = ReadTag(input, DICOM_TAG_SERIES_INSTANCE_UID); | |
661 std::string sopInstanceUid = ReadTag(input, DICOM_TAG_SOP_INSTANCE_UID); | |
662 | |
663 OrthancPluginResourceType level = OrthancPluginResourceType_None; | |
664 | |
665 if (!levelString.empty()) | |
666 { | |
667 level = Plugins::Convert(StringToResourceType(levelString.c_str())); | |
668 } | |
669 | |
670 void* driver = params_.callback(level, | |
671 patientId.empty() ? NULL : patientId.c_str(), | |
672 accessionNumber.empty() ? NULL : accessionNumber.c_str(), | |
673 studyInstanceUid.empty() ? NULL : studyInstanceUid.c_str(), | |
674 seriesInstanceUid.empty() ? NULL : seriesInstanceUid.c_str(), | |
675 sopInstanceUid.empty() ? NULL : sopInstanceUid.c_str(), | |
676 remoteAet.c_str(), | |
677 calledAet.c_str(), | |
678 targetAet.c_str(), | |
679 messageId); | |
680 | |
681 if (driver == NULL) | |
682 { | |
683 LOG(ERROR) << "Plugin cannot create a driver for an incoming C-MOVE request"; | |
684 throw OrthancException(ErrorCode_Plugin); | |
685 } | |
686 | |
687 unsigned int size = params_.getMoveSize(driver); | |
688 | |
689 return new Driver(driver, size, params_.applyMove, params_.freeMove); | |
538 } | 690 } |
539 }; | 691 }; |
540 | 692 |
541 | 693 |
542 | 694 |
879 pimpl_->findCallback_ = p.callback; | 1031 pimpl_->findCallback_ = p.callback; |
880 } | 1032 } |
881 } | 1033 } |
882 | 1034 |
883 | 1035 |
1036 void OrthancPlugins::RegisterMoveCallback(const void* parameters) | |
1037 { | |
1038 const _OrthancPluginMoveCallback& p = | |
1039 *reinterpret_cast<const _OrthancPluginMoveCallback*>(parameters); | |
1040 | |
1041 boost::mutex::scoped_lock lock(pimpl_->moveCallbackMutex_); | |
1042 | |
1043 if (pimpl_->moveCallbacks_.callback != NULL) | |
1044 { | |
1045 LOG(ERROR) << "Can only register one plugin to handle C-MOVE requests"; | |
1046 throw OrthancException(ErrorCode_Plugin); | |
1047 } | |
1048 else | |
1049 { | |
1050 LOG(INFO) << "Plugin has registered a callback to handle C-MOVE requests"; | |
1051 pimpl_->moveCallbacks_ = p; | |
1052 } | |
1053 } | |
1054 | |
1055 | |
884 void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) | 1056 void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) |
885 { | 1057 { |
886 const _OrthancPluginDecodeImageCallback& p = | 1058 const _OrthancPluginDecodeImageCallback& p = |
887 *reinterpret_cast<const _OrthancPluginDecodeImageCallback*>(parameters); | 1059 *reinterpret_cast<const _OrthancPluginDecodeImageCallback*>(parameters); |
888 | 1060 |
1980 | 2152 |
1981 case _OrthancPluginService_RegisterFindCallback: | 2153 case _OrthancPluginService_RegisterFindCallback: |
1982 RegisterFindCallback(parameters); | 2154 RegisterFindCallback(parameters); |
1983 return true; | 2155 return true; |
1984 | 2156 |
2157 case _OrthancPluginService_RegisterMoveCallback: | |
2158 RegisterMoveCallback(parameters); | |
2159 return true; | |
2160 | |
1985 case _OrthancPluginService_RegisterDecodeImageCallback: | 2161 case _OrthancPluginService_RegisterDecodeImageCallback: |
1986 RegisterDecodeImageCallback(parameters); | 2162 RegisterDecodeImageCallback(parameters); |
1987 return true; | 2163 return true; |
1988 | 2164 |
1989 case _OrthancPluginService_RegisterIncomingHttpRequestFilter: | 2165 case _OrthancPluginService_RegisterIncomingHttpRequestFilter: |
2664 boost::mutex::scoped_lock lock(pimpl_->findCallbackMutex_); | 2840 boost::mutex::scoped_lock lock(pimpl_->findCallbackMutex_); |
2665 return pimpl_->findCallback_ != NULL; | 2841 return pimpl_->findCallback_ != NULL; |
2666 } | 2842 } |
2667 | 2843 |
2668 | 2844 |
2845 IMoveRequestHandler* OrthancPlugins::ConstructMoveRequestHandler() | |
2846 { | |
2847 if (HasMoveHandler()) | |
2848 { | |
2849 return new MoveHandler(*this); | |
2850 } | |
2851 else | |
2852 { | |
2853 return NULL; | |
2854 } | |
2855 } | |
2856 | |
2857 | |
2858 bool OrthancPlugins::HasMoveHandler() | |
2859 { | |
2860 boost::mutex::scoped_lock lock(pimpl_->moveCallbackMutex_); | |
2861 return pimpl_->moveCallbacks_.callback != NULL; | |
2862 } | |
2863 | |
2864 | |
2669 bool OrthancPlugins::HasCustomImageDecoder() | 2865 bool OrthancPlugins::HasCustomImageDecoder() |
2670 { | 2866 { |
2671 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); | 2867 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); |
2672 return (pimpl_->decodeImageCallback_ != NULL); | 2868 return (pimpl_->decodeImageCallback_ != NULL); |
2673 } | 2869 } |