예제 #1
0
  StoreStatus ServerContext::Store(std::string& resultPublicId,
                                   DicomInstanceToStore& dicom)
  {
    try
    {
      StorageAccessor accessor(area_);

      DicomInstanceHasher hasher(dicom.GetSummary());
      resultPublicId = hasher.HashInstance();

      Json::Value simplifiedTags;
      Toolbox::SimplifyTags(simplifiedTags, dicom.GetJson(), DicomToJsonFormat_Human);

      // Test if the instance must be filtered out
      bool accepted = true;

      {
        boost::recursive_mutex::scoped_lock lock(listenersMutex_);

        for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
        {
          try
          {
            if (!it->GetListener().FilterIncomingInstance(dicom, simplifiedTags))
            {
              accepted = false;
              break;
            }
          }
          catch (OrthancException& e)
          {
            LOG(ERROR) << "Error in the " << it->GetDescription() 
                       << " callback while receiving an instance: " << e.What();
            throw;
          }
        }
      }

      if (!accepted)
      {
        LOG(INFO) << "An incoming instance has been discarded by the filter";
        return StoreStatus_FilteredOut;
      }

      // TODO Should we use "gzip" instead?
      CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);

      FileInfo dicomInfo = accessor.Write(dicom.GetBufferData(), dicom.GetBufferSize(), 
                                          FileContentType_Dicom, compression, storeMD5_);
      FileInfo jsonInfo = accessor.Write(dicom.GetJson().toStyledString(), 
                                         FileContentType_DicomAsJson, compression, storeMD5_);

      ServerIndex::Attachments attachments;
      attachments.push_back(dicomInfo);
      attachments.push_back(jsonInfo);

      typedef std::map<MetadataType, std::string>  InstanceMetadata;
      InstanceMetadata  instanceMetadata;
      StoreStatus status = index_.Store(instanceMetadata, dicom, attachments);

      // Only keep the metadata for the "instance" level
      dicom.GetMetadata().clear();

      for (InstanceMetadata::const_iterator it = instanceMetadata.begin();
           it != instanceMetadata.end(); ++it)
      {
        dicom.GetMetadata().insert(std::make_pair(std::make_pair(ResourceType_Instance, it->first),
                                                  it->second));
      }
            
      if (status != StoreStatus_Success)
      {
        accessor.Remove(dicomInfo);
        accessor.Remove(jsonInfo);
      }

      switch (status)
      {
        case StoreStatus_Success:
          LOG(INFO) << "New instance stored";
          break;

        case StoreStatus_AlreadyStored:
          LOG(INFO) << "Already stored";
          break;

        case StoreStatus_Failure:
          LOG(ERROR) << "Store failure";
          break;

        default:
          // This should never happen
          break;
      }

      if (status == StoreStatus_Success ||
          status == StoreStatus_AlreadyStored)
      {
        boost::recursive_mutex::scoped_lock lock(listenersMutex_);

        for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
        {
          try
          {
            it->GetListener().SignalStoredInstance(resultPublicId, dicom, simplifiedTags);
          }
          catch (OrthancException& e)
          {
            LOG(ERROR) << "Error in the " << it->GetDescription() 
                       << " callback while receiving an instance: " << e.What();
          }
        }
      }

      return status;
    }
    catch (OrthancException& e)
    {
      if (e.GetErrorCode() == ErrorCode_InexistentTag)
      {
        Toolbox::LogMissingRequiredTag(dicom.GetSummary());
      }

      throw;
    }
  }
예제 #2
0
  StoreStatus ServerContext::Store(const char* dicomInstance,
                                   size_t dicomSize,
                                   const DicomMap& dicomSummary,
                                   const Json::Value& dicomJson,
                                   const std::string& remoteAet)
  {
    // Test if the instance must be filtered out
    if (lua_.IsExistingFunction(RECEIVED_INSTANCE_FILTER))
    {
      Json::Value simplified;
      SimplifyTags(simplified, dicomJson);

      LuaFunctionCall call(lua_, RECEIVED_INSTANCE_FILTER);
      call.PushJSON(simplified);
      call.PushString(remoteAet);

      if (!call.ExecutePredicate())
      {
        LOG(INFO) << "An incoming instance has been discarded by the filter";
        return StoreStatus_FilteredOut;
      }
    }

    if (compressionEnabled_)
    {
      accessor_.SetCompressionForNextOperations(CompressionType_Zlib);
    }
    else
    {
      accessor_.SetCompressionForNextOperations(CompressionType_None);
    }      

    FileInfo dicomInfo = accessor_.Write(dicomInstance, dicomSize, FileContentType_Dicom);
    FileInfo jsonInfo = accessor_.Write(dicomJson.toStyledString(), FileContentType_Json);

    ServerIndex::Attachments attachments;
    attachments.push_back(dicomInfo);
    attachments.push_back(jsonInfo);

    StoreStatus status = index_.Store(dicomSummary, attachments, remoteAet);

    if (status != StoreStatus_Success)
    {
      storage_.Remove(dicomInfo.GetUuid());
      storage_.Remove(jsonInfo.GetUuid());
    }

    switch (status)
    {
      case StoreStatus_Success:
        LOG(INFO) << "New instance stored";
        break;

      case StoreStatus_AlreadyStored:
        LOG(INFO) << "Already stored";
        break;

      case StoreStatus_Failure:
        LOG(ERROR) << "Store failure";
        break;

      default:
        // This should never happen
        break;
    }

    return status;
  }