예제 #1
0
    void SimplifyTags(Json::Value& target,
                      const Json::Value& source,
                      DicomToJsonFormat format)
    {
      assert(source.isObject());

      target = Json::objectValue;
      Json::Value::Members members = source.getMemberNames();

      for (size_t i = 0; i < members.size(); i++)
      {
        const Json::Value& v = source[members[i]];
        const std::string& type = v["Type"].asString();

        std::string name;
        switch (format)
        {
          case DicomToJsonFormat_Human:
            name = v["Name"].asString();
            break;

          case DicomToJsonFormat_Short:
            name = members[i];
            break;

          default:
            throw OrthancException(ErrorCode_ParameterOutOfRange);
        }

        if (type == "String")
        {
          target[name] = v["Value"].asString();
        }
        else if (type == "TooLong" ||
                 type == "Null")
        {
          target[name] = Json::nullValue;
        }
        else if (type == "Sequence")
        {
          const Json::Value& array = v["Value"];
          assert(array.isArray());

          Json::Value children = Json::arrayValue;
          for (Json::Value::ArrayIndex i = 0; i < array.size(); i++)
          {
            Json::Value c;
            SimplifyTags(c, array[i], format);
            children.append(c);
          }

          target[name] = children;
        }
        else
        {
          assert(0);
        }
      }
    }
예제 #2
0
  void SimplifyTags(Json::Value& target,
                    const Json::Value& source)
  {
    assert(source.isObject());

    target = Json::objectValue;
    Json::Value::Members members = source.getMemberNames();

    for (size_t i = 0; i < members.size(); i++)
    {
      const Json::Value& v = source[members[i]];
      const std::string& name = v["Name"].asString();
      const std::string& type = v["Type"].asString();

      if (type == "String")
      {
        target[name] = v["Value"].asString();
      }
      else if (type == "TooLong" ||
               type == "Null")
      {
        target[name] = Json::nullValue;
      }
      else if (type == "Sequence")
      {
        const Json::Value& array = v["Value"];
        assert(array.isArray());

        Json::Value children = Json::arrayValue;
        for (Json::Value::ArrayIndex i = 0; i < array.size(); i++)
        {
          Json::Value c;
          SimplifyTags(c, array[i]);
          children.append(c);
        }

        target[name] = children;
      }
      else
      {
        assert(0);
      }
    }
  }
예제 #3
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;
  }
예제 #4
0
  StoreStatus ServerContext::Store(std::string& resultPublicId,
                                   DicomInstanceToStore& dicom)
  {
    try
    {
      DicomInstanceHasher hasher(dicom.GetSummary());
      resultPublicId = hasher.HashInstance();

      Json::Value simplified;
      SimplifyTags(simplified, dicom.GetJson());

      // 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(simplified, dicom.GetRemoteAet()))
            {
              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;
      }

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

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

      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.GetSummary(), attachments, 
                                        dicom.GetRemoteAet(), dicom.GetMetadata());

      // 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.GetUuid(), FileContentType_Dicom);
        accessor_.Remove(jsonInfo.GetUuid(), FileContentType_DicomAsJson);
      }

      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, simplified);
          }
          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)
      {
        LogMissingRequiredTag(dicom.GetSummary());
      }

      throw;
    }
  }