comparison OrthancServer/Sources/ServerContext.cpp @ 4988:8fba26292a9f

Housekeeper plugin: finalizing + integration tests ok
author Alain Mazy <am@osimis.io>
date Sat, 30 Apr 2022 19:39:40 +0200
parents c8cdf5163cd2
children 2f30aa99c2db
comparison
equal deleted inserted replaced
4986:a25e74fad379 4988:8fba26292a9f
493 } 493 }
494 494
495 495
496 ServerContext::StoreResult ServerContext::StoreAfterTranscoding(std::string& resultPublicId, 496 ServerContext::StoreResult ServerContext::StoreAfterTranscoding(std::string& resultPublicId,
497 DicomInstanceToStore& dicom, 497 DicomInstanceToStore& dicom,
498 StoreInstanceMode mode) 498 StoreInstanceMode mode,
499 bool isReconstruct)
499 { 500 {
500 bool overwrite; 501 bool overwrite;
501 switch (mode) 502 switch (mode)
502 { 503 {
503 case StoreInstanceMode_Default: 504 case StoreInstanceMode_Default:
542 Toolbox::SimplifyDicomAsJson(simplifiedTags, dicomAsJson, DicomToJsonFormat_Human); 543 Toolbox::SimplifyDicomAsJson(simplifiedTags, dicomAsJson, DicomToJsonFormat_Human);
543 544
544 // Test if the instance must be filtered out 545 // Test if the instance must be filtered out
545 StoreResult result; 546 StoreResult result;
546 547
548 if (!isReconstruct) // skip all filters if this is a reconstruction
547 { 549 {
548 boost::shared_lock<boost::shared_mutex> lock(listenersMutex_); 550 boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);
549 551
550 for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it) 552 for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
551 { 553 {
613 615
614 typedef std::map<MetadataType, std::string> InstanceMetadata; 616 typedef std::map<MetadataType, std::string> InstanceMetadata;
615 InstanceMetadata instanceMetadata; 617 InstanceMetadata instanceMetadata;
616 result.SetStatus(index_.Store( 618 result.SetStatus(index_.Store(
617 instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite, 619 instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite,
618 hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset)); 620 hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset, isReconstruct));
619 621
620 // Only keep the metadata for the "instance" level 622 // Only keep the metadata for the "instance" level
621 dicom.ClearMetadata(); 623 dicom.ClearMetadata();
622 624
623 for (InstanceMetadata::const_iterator it = instanceMetadata.begin(); 625 for (InstanceMetadata::const_iterator it = instanceMetadata.begin();
634 { 636 {
635 accessor.Remove(dicomUntilPixelData); 637 accessor.Remove(dicomUntilPixelData);
636 } 638 }
637 } 639 }
638 640
639 switch (result.GetStatus()) 641 if (!isReconstruct) // skip logs in case of reconstruction
640 { 642 {
641 case StoreStatus_Success: 643 switch (result.GetStatus())
642 LOG(INFO) << "New instance stored"; 644 {
643 break; 645 case StoreStatus_Success:
644 646 LOG(INFO) << "New instance stored";
645 case StoreStatus_AlreadyStored: 647 break;
646 LOG(INFO) << "Already stored"; 648
647 break; 649 case StoreStatus_AlreadyStored:
648 650 LOG(INFO) << "Already stored";
649 case StoreStatus_Failure: 651 break;
650 LOG(ERROR) << "Store failure"; 652
651 break; 653 case StoreStatus_Failure:
652 654 LOG(ERROR) << "Store failure";
653 default: 655 break;
654 // This should never happen 656
655 break; 657 default:
656 } 658 // This should never happen
657 659 break;
658 if (result.GetStatus() == StoreStatus_Success || 660 }
659 result.GetStatus() == StoreStatus_AlreadyStored) 661 }
660 { 662
661 boost::shared_lock<boost::shared_mutex> lock(listenersMutex_); 663 if (!isReconstruct) // skip all signals if this is a reconstruction
662 664 {
663 for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it) 665 if (result.GetStatus() == StoreStatus_Success ||
664 { 666 result.GetStatus() == StoreStatus_AlreadyStored)
665 try 667 {
668 boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);
669
670 for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
666 { 671 {
667 it->GetListener().SignalStoredInstance(resultPublicId, dicom, simplifiedTags); 672 try
668 } 673 {
669 catch (OrthancException& e) 674 it->GetListener().SignalStoredInstance(resultPublicId, dicom, simplifiedTags);
670 { 675 }
671 LOG(ERROR) << "Error in the " << it->GetDescription() 676 catch (OrthancException& e)
672 << " callback while receiving an instance: " << e.What() 677 {
673 << " (code " << e.GetErrorCode() << ")"; 678 LOG(ERROR) << "Error in the " << it->GetDescription()
679 << " callback while receiving an instance: " << e.What()
680 << " (code " << e.GetErrorCode() << ")";
681 }
674 } 682 }
675 } 683 }
676 } 684 }
677 685
678 return result; 686 return result;
741 throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback has returned an invalid value"); 749 throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback has returned an invalid value");
742 } 750 }
743 } 751 }
744 #endif 752 #endif
745 753
754 return TranscodeAndStore(resultPublicId, dicom, mode);
755 }
756
757 ServerContext::StoreResult ServerContext::TranscodeAndStore(std::string& resultPublicId,
758 DicomInstanceToStore* dicom,
759 StoreInstanceMode mode,
760 bool isReconstruct)
761 {
762
746 if (!isIngestTranscoding_) 763 if (!isIngestTranscoding_)
747 { 764 {
748 // No automated transcoding. This was the only path in Orthanc <= 1.6.1. 765 // No automated transcoding. This was the only path in Orthanc <= 1.6.1.
749 return StoreAfterTranscoding(resultPublicId, *dicom, mode); 766 return StoreAfterTranscoding(resultPublicId, *dicom, mode, isReconstruct);
750 } 767 }
751 else 768 else
752 { 769 {
753 // Automated transcoding of incoming DICOM instance 770 // Automated transcoding of incoming DICOM instance
754 771
780 } 797 }
781 798
782 if (!transcode) 799 if (!transcode)
783 { 800 {
784 // No transcoding 801 // No transcoding
785 return StoreAfterTranscoding(resultPublicId, *dicom, mode); 802 return StoreAfterTranscoding(resultPublicId, *dicom, mode, isReconstruct);
786 } 803 }
787 else 804 else
788 { 805 {
789 // Trancoding 806 // Trancoding
790 std::set<DicomTransferSyntax> syntaxes; 807 std::set<DicomTransferSyntax> syntaxes;
799 std::unique_ptr<ParsedDicomFile> tmp(transcoded.ReleaseAsParsedDicomFile()); 816 std::unique_ptr<ParsedDicomFile> tmp(transcoded.ReleaseAsParsedDicomFile());
800 817
801 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(*tmp)); 818 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(*tmp));
802 toStore->SetOrigin(dicom->GetOrigin()); 819 toStore->SetOrigin(dicom->GetOrigin());
803 820
804 StoreResult result = StoreAfterTranscoding(resultPublicId, *toStore, mode); 821 if (isReconstruct) // the initial instance to store already has its own metadata
822 {
823 toStore->CopyMetadata(dicom->GetMetadata());
824 }
825
826 StoreResult result = StoreAfterTranscoding(resultPublicId, *toStore, mode, isReconstruct);
805 assert(resultPublicId == tmp->GetHasher().HashInstance()); 827 assert(resultPublicId == tmp->GetHasher().HashInstance());
806 828
807 return result; 829 return result;
808 } 830 }
809 else 831 else
810 { 832 {
811 // Cannot transcode => store the original file 833 // Cannot transcode => store the original file
812 return StoreAfterTranscoding(resultPublicId, *dicom, mode); 834 return StoreAfterTranscoding(resultPublicId, *dicom, mode, isReconstruct);
813 } 835 }
814 } 836 }
815 } 837 }
816 } 838 }
817 839