예제 #1
0
SessionStore::Session* SessionStore::JsonSerializerDeserializer::
deserialize_session(const std::string& data)
{
    TRC_DEBUG("Deserialize JSON document: %s", data.c_str());

    rapidjson::Document doc;
    doc.Parse<0>(data.c_str());

    if (doc.HasParseError())
    {
        TRC_DEBUG("Failed to parse document");
        return NULL;
    }

    Session* session = new Session();

    try
    {
        JSON_GET_STRING_MEMBER(doc, JSON_SESSION_ID, session->session_id);

        JSON_ASSERT_CONTAINS(doc, JSON_CCFS);
        JSON_ASSERT_ARRAY(doc[JSON_CCFS]);

        for (rapidjson::Value::ConstValueIterator ccfs_it = doc[JSON_CCFS].Begin();
                ccfs_it != doc[JSON_CCFS].End();
                ++ccfs_it)
        {
            JSON_ASSERT_STRING(*ccfs_it);
            session->ccf.push_back(ccfs_it->GetString());
        }

        JSON_GET_INT_MEMBER(doc, JSON_ACCT_RECORD_NUM, session->acct_record_number);
        JSON_GET_STRING_MEMBER(doc, JSON_TIMER_ID, session->timer_id);
        JSON_GET_INT_MEMBER(doc, JSON_REFRESH_TIME, session->session_refresh_time);
        JSON_GET_INT_MEMBER(doc, JSON_INTERIM_INTERVAL, session->interim_interval);
    }
    catch(JsonFormatError err)
    {
        TRC_INFO("Failed to deserialize JSON document (hit error at %s:%d)",
                 err._file, err._line);
        delete session;
        session = NULL;
    }

    return session;
}
예제 #2
0
AuthStore::Digest* AuthStore::JsonSerializerDeserializer::
  deserialize_digest(const std::string& digest_s)
{
  TRC_DEBUG("Deserialize JSON document: %s", digest_s.c_str());

  rapidjson::Document doc;
  doc.Parse<0>(digest_s.c_str());

  if (doc.HasParseError())
  {
    TRC_DEBUG("Failed to parse document");
    return NULL;
  }

  Digest* digest = new Digest();

  try
  {
    JSON_ASSERT_OBJECT(doc);
    JSON_ASSERT_CONTAINS(doc, JSON_DIGEST);
    JSON_ASSERT_OBJECT(doc[JSON_DIGEST]);
    const rapidjson::Value& digest_block = doc[JSON_DIGEST];
    {
      JSON_GET_STRING_MEMBER(digest_block, JSON_HA1, digest->_ha1);
      // The QoP is assumed to always be 'auth'.
      JSON_GET_STRING_MEMBER(digest_block, JSON_REALM, digest->_realm);
    }

    JSON_GET_STRING_MEMBER(doc, JSON_OPAQUE, digest->_opaque);
    JSON_GET_STRING_MEMBER(doc, JSON_IMPU, digest->_impu);
    JSON_GET_INT_MEMBER(doc, JSON_NC, digest->_nonce_count);
  }
  catch(JsonFormatError err)
  {
    TRC_INFO("Failed to deserialize JSON document (hit error at %s:%d)",
             err._file, err._line);
    delete digest; digest = NULL;
  }

  return digest;
}
예제 #3
0
JSONEnumService::JSONEnumService(std::string configuration)
{
  // Check whether the file exists.
  struct stat s;
  if ((stat(configuration.c_str(), &s) != 0) &&
      (errno == ENOENT))
  {
    TRC_STATUS("No ENUM configuration (file %s does not exist)",
               configuration.c_str());
    CL_SPROUT_ENUM_FILE_MISSING.log(configuration.c_str());
    return;
  }

  TRC_STATUS("Loading ENUM configuration from %s", configuration.c_str());

  // Read from the file
  std::ifstream fs(configuration.c_str());
  std::string enum_str((std::istreambuf_iterator<char>(fs)),
                        std::istreambuf_iterator<char>());

  if (enum_str == "")
  {
    // LCOV_EXCL_START
    TRC_ERROR("Failed to read ENUM configuration data from %s",
              configuration.c_str());
    CL_SPROUT_ENUM_FILE_EMPTY.log(configuration.c_str());
    return;
    // LCOV_EXCL_STOP
  }

  // Now parse the document
  rapidjson::Document doc;
  doc.Parse<0>(enum_str.c_str());

  if (doc.HasParseError())
  {
    TRC_ERROR("Failed to read ENUM configuration data: %s\nError: %s",
              enum_str.c_str(),
              rapidjson::GetParseError_En(doc.GetParseError()));
    CL_SPROUT_ENUM_FILE_INVALID.log(configuration.c_str());
    return;
  }

  try
  {
    JSON_ASSERT_CONTAINS(doc, "number_blocks");
    JSON_ASSERT_ARRAY(doc["number_blocks"]);
    const rapidjson::Value& nb_arr = doc["number_blocks"];

    for (rapidjson::Value::ConstValueIterator nb_it = nb_arr.Begin();
         nb_it != nb_arr.End();
         ++nb_it)
    {
      try
      {
        std::string prefix; 
        JSON_GET_STRING_MEMBER(*nb_it, "prefix", prefix);
        std::string regex;
        JSON_GET_STRING_MEMBER(*nb_it, "regex", regex);

        // Entry is well-formed, so add it.
        TRC_DEBUG("Found valid number prefix block %s", prefix.c_str());
        NumberPrefix *pfix = new NumberPrefix;
        pfix->prefix = prefix;

        if (parse_regex_replace(regex, pfix->match, pfix->replace))
        {
          _number_prefixes.push_back(pfix);
          TRC_STATUS("  Adding number prefix %s, regex=%s",
                     pfix->prefix.c_str(), regex.c_str());
        }
        else
        {
          TRC_WARNING("Badly formed regular expression in ENUM number block %s",
                      regex.c_str());
          delete pfix;
        }
      }
      catch (JsonFormatError err)
      {
        // Badly formed number block.
        TRC_WARNING("Badly formed ENUM number block (hit error at %s:%d)",
                    err._file, err._line);
        CL_SPROUT_ENUM_FILE_INVALID.log(configuration.c_str());
      }
    }
  }
  catch (JsonFormatError err)
  {
    TRC_ERROR("Badly formed ENUM configuration data - missing number_blocks object");
    CL_SPROUT_ENUM_FILE_INVALID.log(configuration.c_str());
  }
}
예제 #4
0
파일: timer.cpp 프로젝트: AiprNick/chronos
Timer* Timer::from_json_obj(TimerID id,
                            uint64_t replica_hash,
                            std::string& error,
                            bool& replicated,
                            rapidjson::Value& doc)
{
  Timer* timer = NULL;

  try
  {
    JSON_ASSERT_CONTAINS(doc, "timing");
    JSON_ASSERT_CONTAINS(doc, "callback");

    // Parse out the timing block
    rapidjson::Value& timing = doc["timing"];
    JSON_ASSERT_OBJECT(timing);

    JSON_ASSERT_CONTAINS(timing, "interval");
    rapidjson::Value& interval = timing["interval"];
    JSON_ASSERT_INT(interval);

    // Extract the repeat-for parameter, if it's absent, set it to the interval
    // instead.
    int repeat_for_int;
    if (timing.HasMember("repeat-for"))
    {
      JSON_GET_INT_MEMBER(timing, "repeat-for", repeat_for_int);
    }
    else
    {
      repeat_for_int = interval.GetInt();
    }

    if ((interval.GetInt() == 0) && (repeat_for_int != 0))
    {
      // If the interval time is 0 and the repeat_for_int isn't then reject the timer.
      error = "Can't have a zero interval time with a non-zero (%s) repeat-for time",
              std::to_string(repeat_for_int);
      return NULL;
    }

    timer = new Timer(id, (interval.GetInt() * 1000), (repeat_for_int * 1000));

    if (timing.HasMember("start-time-delta"))
    {
      // Timer JSON specified a time offset, use that to determine the true
      // start time.
      uint64_t start_time_delta;
      JSON_GET_INT_64_MEMBER(timing, "start-time-delta", start_time_delta);

      // This cast is safe as this sum is deliberately designed to wrap over UINT_MAX.
      timer->start_time_mono_ms = (uint32_t)(clock_gettime_ms(CLOCK_MONOTONIC) + start_time_delta);
    }
    else if (timing.HasMember("start-time"))
    {
      // Timer JSON specifies a start-time, use that instead of now.
      uint64_t real_start_time;
      JSON_GET_INT_64_MEMBER(timing, "start-time", real_start_time);
      uint64_t real_time = clock_gettime_ms(CLOCK_REALTIME);
      uint64_t mono_time = clock_gettime_ms(CLOCK_MONOTONIC);

      // This cast is safe as this sum is deliberately designed to wrap over UINT_MAX.
      timer->start_time_mono_ms = (uint32_t)(mono_time + real_start_time - real_time);
    }

    if (timing.HasMember("sequence-number"))
    {
      JSON_GET_INT_MEMBER(timing, "sequence-number", timer->sequence_number);
    }

    // Parse out the 'callback' block
    rapidjson::Value& callback = doc["callback"];
    JSON_ASSERT_OBJECT(callback);

    JSON_ASSERT_CONTAINS(callback, "http");
    rapidjson::Value& http = callback["http"];
    JSON_ASSERT_OBJECT(http);

    JSON_GET_STRING_MEMBER(http, "uri", timer->callback_url);
    JSON_GET_STRING_MEMBER(http, "opaque", timer->callback_body);

    if (doc.HasMember("reliability"))
    {
      // Parse out the 'reliability' block
      rapidjson::Value& reliability = doc["reliability"];
      JSON_ASSERT_OBJECT(reliability);

      if (reliability.HasMember("cluster-view-id"))
      {
        JSON_GET_STRING_MEMBER(reliability,
                               "cluster-view-id",
                               timer->cluster_view_id);
      }

      if (reliability.HasMember("replicas"))
      {
        rapidjson::Value& replicas = reliability["replicas"];
        JSON_ASSERT_ARRAY(replicas);

        if (replicas.Size() == 0)
        {
          error = "If replicas is specified it must be non-empty";
          delete timer; timer = NULL;
          return NULL;
        }

        timer->_replication_factor = replicas.Size();

        for (rapidjson::Value::ConstValueIterator it = replicas.Begin();
                                                  it != replicas.End();
                                                  ++it)
        {
          JSON_ASSERT_STRING(*it);
          timer->replicas.push_back(std::string(it->GetString(), it->GetStringLength()));
        }
      }
      else
      {
        if (reliability.HasMember("replication-factor"))
        {
          JSON_GET_INT_MEMBER(reliability,
                              "replication-factor",
                              timer->_replication_factor);
        }
        else
        {
          // Default replication factor is 2.
          timer->_replication_factor = 2;
        }
      }
    }
    else
    {
      // Default to 2 replicas
      timer->_replication_factor = 2;
    }

    timer->_replica_tracker = pow(2, timer->_replication_factor) - 1;

    if (timer->replicas.empty())
    {
      // Replicas not determined above, determine them now.  Note that this implies
      // the request is from a client, not another replica.
      replicated = false;
      timer->calculate_replicas(replica_hash);
    }
    else
    {
      // Replicas were specified in the request, must be a replication message
      // from another cluster node.
      replicated = true;
    }
  }
  catch (JsonFormatError err)
  {
    error = "Badly formed Timer entry - hit error on line " + std::to_string(err._line);
    delete timer; timer = NULL;
    return NULL;
  }

  return timer;
}
예제 #5
0
void JSONEnumService::update_enum()
{
  // Check whether the file exists.
  struct stat s;
  if ((stat(_configuration.c_str(), &s) != 0) &&
      (errno == ENOENT))
  {
    TRC_STATUS("No ENUM configuration (file %s does not exist)",
               _configuration.c_str());
    CL_SPROUT_ENUM_FILE_MISSING.log(_configuration.c_str());
    return;
  }

  TRC_STATUS("Loading ENUM configuration from %s", _configuration.c_str());

  // Read from the file
  std::ifstream fs(_configuration.c_str());
  std::string enum_str((std::istreambuf_iterator<char>(fs)),
                        std::istreambuf_iterator<char>());

  if (enum_str == "")
  {
    // LCOV_EXCL_START
    TRC_ERROR("Failed to read ENUM configuration data from %s",
              _configuration.c_str());
    CL_SPROUT_ENUM_FILE_EMPTY.log(_configuration.c_str());
    return;
    // LCOV_EXCL_STOP
  }

  // Now parse the document
  rapidjson::Document doc;
  doc.Parse<0>(enum_str.c_str());

  if (doc.HasParseError())
  {
    TRC_ERROR("Failed to read ENUM configuration data: %s\nError: %s",
              enum_str.c_str(),
              rapidjson::GetParseError_En(doc.GetParseError()));
    CL_SPROUT_ENUM_FILE_INVALID.log(_configuration.c_str());
    return;
  }

  try
  {
    std::vector<NumberPrefix> new_number_prefixes;
    std::map<std::string, NumberPrefix> new_prefix_regex_map;

    JSON_ASSERT_CONTAINS(doc, "number_blocks");
    JSON_ASSERT_ARRAY(doc["number_blocks"]);
    const rapidjson::Value& nb_arr = doc["number_blocks"];

    for (rapidjson::Value::ConstValueIterator nb_it = nb_arr.Begin();
         nb_it != nb_arr.End();
         ++nb_it)
    {
      try
      {
        std::string prefix;
        JSON_GET_STRING_MEMBER(*nb_it, "prefix", prefix);
        std::string regex;
        JSON_GET_STRING_MEMBER(*nb_it, "regex", regex);

        // Entry is well-formed, so strip off visual separators and add it.
        TRC_DEBUG("Found valid number prefix block %s", prefix.c_str());
        NumberPrefix pfix;
        prefix = PJUtils::remove_visual_separators(prefix);
        pfix.prefix = prefix;

        if (parse_regex_replace(regex, pfix.match, pfix.replace))
        {
          // Create an array in order of entries in json file, and a map
          // (automatically sorted in order of key length) so we can later
          // match numbers to the most specific prefixes
          new_number_prefixes.push_back(pfix);
          new_prefix_regex_map.insert(std::make_pair(prefix, pfix));
          TRC_STATUS("  Adding number prefix %s, regex=%s",
                     pfix.prefix.c_str(), regex.c_str());
        }
        else
        {
          TRC_WARNING("Badly formed regular expression in ENUM number block %s",
                      regex.c_str());
        }
      }
      catch (JsonFormatError err)
      {
        // Badly formed number block.
        TRC_WARNING("Badly formed ENUM number block (hit error at %s:%d)",
                    err._file, err._line);
        CL_SPROUT_ENUM_FILE_INVALID.log(_configuration.c_str());
      }
    }

    // Take a write lock on the mutex in RAII style
    boost::lock_guard<boost::shared_mutex> write_lock(_number_prefixes_rw_lock);
    _number_prefixes = new_number_prefixes;
    _prefix_regex_map = new_prefix_regex_map;
  }
  catch (JsonFormatError err)
  {
    TRC_ERROR("Badly formed ENUM configuration data - missing number_blocks object");
    CL_SPROUT_ENUM_FILE_INVALID.log(_configuration.c_str());
  }
}
예제 #6
0
void SCSCFSelector::update_scscf()
{
  // Check whether the file exists.
  struct stat s;
  if ((stat(_configuration.c_str(), &s) != 0) &&
      (errno == ENOENT))
  {
    TRC_STATUS("No S-CSCF configuration data (file %s does not exist)",
               _configuration.c_str());
    CL_SPROUT_SCSCF_FILE_MISSING.log();
    return;
  }

  TRC_STATUS("Loading S-CSCF configuration from %s", _configuration.c_str());

  // Read from the file
  std::ifstream fs(_configuration.c_str());
  std::string scscf_str((std::istreambuf_iterator<char>(fs)),
                         std::istreambuf_iterator<char>());

  if (scscf_str == "")
  {
    // LCOV_EXCL_START
    TRC_ERROR("Failed to read S-CSCF configuration data from %s",
              _configuration.c_str());
    CL_SPROUT_SCSCF_FILE_EMPTY.log();
    return;
    // LCOV_EXCL_STOP
  }

  // Now parse the document
  rapidjson::Document doc;
  doc.Parse<0>(scscf_str.c_str());

  if (doc.HasParseError())
  {
    TRC_ERROR("Failed to read S-CSCF configuration data: %s\nError: %s",
              scscf_str.c_str(),
              rapidjson::GetParseError_En(doc.GetParseError()));
    CL_SPROUT_SCSCF_FILE_INVALID.log();
    return;
  }

  try
  {
    std::vector<scscf_t> new_scscfs;

    JSON_ASSERT_CONTAINS(doc, "s-cscfs");
    JSON_ASSERT_ARRAY(doc["s-cscfs"]);
    const rapidjson::Value& scscfs_arr = doc["s-cscfs"];

    for (rapidjson::Value::ConstValueIterator scscfs_it = scscfs_arr.Begin();
         scscfs_it != scscfs_arr.End();
         ++scscfs_it)
    {
      try
      {
        scscf_t new_scscf;
        JSON_GET_STRING_MEMBER(*scscfs_it, "server", new_scscf.server);
        JSON_GET_INT_MEMBER(*scscfs_it, "priority", new_scscf.priority);
        JSON_GET_INT_MEMBER(*scscfs_it, "weight", new_scscf.weight);

        JSON_ASSERT_CONTAINS(*scscfs_it, "capabilities");
        JSON_ASSERT_ARRAY((*scscfs_it)["capabilities"]);
        const rapidjson::Value& cap_arr = (*scscfs_it)["capabilities"];
        std::vector<int> capabilities_vec;

        for (rapidjson::Value::ConstValueIterator cap_it = cap_arr.Begin();
             cap_it != cap_arr.End();
             ++cap_it)
        {
          capabilities_vec.push_back((*cap_it).GetInt());
        }

        // Sort the capabilities and remove duplicates
        std::sort(capabilities_vec.begin(), capabilities_vec.end());
        capabilities_vec.erase(unique(capabilities_vec.begin(),
                                      capabilities_vec.end()),
                               capabilities_vec.end() );
        new_scscf.capabilities = capabilities_vec;
        new_scscfs.push_back(new_scscf);
        capabilities_vec.clear();
      }
      catch (JsonFormatError err)
      {
        // Badly formed number block.
        TRC_WARNING("Badly formed S-CSCF entry (hit error at %s:%d)",
                    err._file, err._line);
        CL_SPROUT_SCSCF_FILE_INVALID.log();
      }
    }

    // Take a write lock on the mutex in RAII style
    boost::lock_guard<boost::shared_mutex> write_lock(_scscfs_rw_lock);
    _scscfs = new_scscfs;
  }
  catch (JsonFormatError err)
  {
    TRC_ERROR("Badly formed S-CSCF configuration file - missing s-cscfs object");
    CL_SPROUT_SCSCF_FILE_INVALID.log();
  }
}