Status ParseJsonConfig()

in tensorflow_recommenders_addons/dynamic_embedding/core/kernels/redis_impl/redis_table_op_util.hpp [155:364]


Status ParseJsonConfig(const std::string *const redis_config_abs_dir,
                       Redis_Connection_Params *redis_connection_params) {
  const char *filename = redis_config_abs_dir->c_str();
  FILE *fp;
  struct stat filestatus;
  size_t file_size;
  char *file_contents;
  json_char *config_json;
  json_value *config_value;

  if (stat(filename, &filestatus) != 0) {
    LOG(ERROR) << "File " << filename << " not found";
    return errors::NotFound("File ", filename, " not found");
  }
  file_size = filestatus.st_size;
  file_contents = (char *)malloc(file_size);
  if (file_contents == NULL) {
    LOG(ERROR) << "Memory error: unable to allocate "
               << std::to_string(file_size) << " bytes";
    return errors::ResourceExhausted("Memory error: unable to allocate ",
                                     std::to_string(file_size), " bytes");
  }
  fp = fopen(filename, "rt");
  if (fp == NULL) {
    fclose(fp);
    free(file_contents);
    LOG(ERROR) << "Unable to open " << redis_config_abs_dir;
    return errors::PermissionDenied("Unable to open ", redis_config_abs_dir);
  }
  if (fread(file_contents, file_size, 1, fp) != 1) {
    fclose(fp);
    free(file_contents);
    LOG(ERROR) << "Unable t read content of " << redis_config_abs_dir;
    return errors::Unavailable("Unable t read content of ",
                               redis_config_abs_dir);
  }
  fclose(fp);

  config_json = (json_char *)file_contents;
  config_value = json_parse(config_json, file_size);
  if (config_value->type != json_object) {
    free(file_contents);
    LOG(ERROR) << "Unable to parse the json data";
    return errors::Unknown("Unable to parse the json data from ",
                           redis_config_abs_dir);
  }

  std::unordered_map<std::string, json_value *> json_hangar;
  std::unordered_map<std::string, json_value *>::iterator json_hangar_it;
  json_object_entry value_depth0_entry;
  json_value *value_depth1;
  for (unsigned i = 0; i < config_value->u.object.length; ++i) {
    value_depth0_entry = config_value->u.object.values[i];
    json_hangar[value_depth0_entry.name] = value_depth0_entry.value;
  }

#define ReadOneJsonToParams(json_key_name, json_val_type)                \
  {                                                                      \
    json_hangar_it = json_hangar.find(#json_key_name);                   \
    if (json_hangar_it != json_hangar.end()) {                           \
      if (json_hangar_it->second->type == json_##json_val_type) {        \
        redis_connection_params->json_key_name =                         \
            json_hangar_it->second->u.json_val_type;                     \
      } else {                                                           \
        LOG(ERROR) << #json_key_name " should be json " #json_val_type;  \
        return Status(error::INVALID_ARGUMENT,                           \
                      #json_key_name " should be json " #json_val_type); \
      }                                                                  \
    }                                                                    \
  }

#define ReadStringOneJsonToParams(json_key_name)                  \
  {                                                               \
    json_hangar_it = json_hangar.find(#json_key_name);            \
    if (json_hangar_it != json_hangar.end()) {                    \
      if (json_hangar_it->second->type == json_string) {          \
        redis_connection_params->json_key_name =                  \
            std::string(json_hangar_it->second->u.string.ptr,     \
                        json_hangar_it->second->u.string.length); \
      } else {                                                    \
        LOG(ERROR) << #json_key_name " should be json string";    \
        return Status(error::INVALID_ARGUMENT,                    \
                      #json_key_name " should be json string");   \
      }                                                           \
    }                                                             \
  }

#define ReadArrayJsonToParams(json_key_name, json_val_type)                \
  {                                                                        \
    json_hangar_it = json_hangar.find(#json_key_name);                     \
    if (json_hangar_it != json_hangar.end()) {                             \
      if (json_hangar_it->second->type == json_array) {                    \
        redis_connection_params->json_key_name.clear();                    \
        for (unsigned i = 0; i < json_hangar_it->second->u.array.length;   \
             ++i) {                                                        \
          value_depth1 = json_hangar_it->second->u.array.values[i];        \
          if (value_depth1->type == json_##json_val_type) {                \
            redis_connection_params->redis_host_port.push_back(            \
                value_depth1->u.json_val_type);                            \
          } else {                                                         \
            LOG(ERROR) << #json_key_name " should be json " #json_val_type \
                                         " array";                         \
            return Status(error::INVALID_ARGUMENT, #json_key_name          \
                          " should be json " #json_val_type " array");     \
          }                                                                \
        }                                                                  \
      } else {                                                             \
        LOG(ERROR) << #json_key_name " should be json " #json_val_type     \
                                     " array";                             \
        return Status(error::INVALID_ARGUMENT, #json_key_name              \
                      " should be json " #json_val_type " array");         \
      }                                                                    \
    }                                                                      \
  }

#define ReadStringArrayJsonToParams(json_key_name)                           \
  {                                                                          \
    json_hangar_it = json_hangar.find(#json_key_name);                       \
    if (json_hangar_it != json_hangar.end()) {                               \
      if (json_hangar_it->second->type == json_array) {                      \
        redis_connection_params->json_key_name.clear();                      \
        for (unsigned i = 0; i < json_hangar_it->second->u.array.length;     \
             ++i) {                                                          \
          value_depth1 = json_hangar_it->second->u.array.values[i];          \
          if (value_depth1->type == json_string) {                           \
            redis_connection_params->json_key_name.push_back(std::string(    \
                value_depth1->u.string.ptr, value_depth1->u.string.length)); \
          } else {                                                           \
            LOG(ERROR) << #json_key_name " should be json string array";     \
            return Status(error::INVALID_ARGUMENT,                           \
                          #json_key_name " should be json string array");    \
          }                                                                  \
        }                                                                    \
      } else {                                                               \
        LOG(ERROR) << #json_key_name " should be json string array";         \
        return Status(error::INVALID_ARGUMENT,                               \
                      #json_key_name " should be json string array");        \
      }                                                                      \
    }                                                                        \
  }

  ReadOneJsonToParams(redis_connection_mode, integer);

  ReadStringOneJsonToParams(redis_master_name);

  ReadStringArrayJsonToParams(redis_host_ip);

  ReadArrayJsonToParams(redis_host_port, integer);

  ReadStringOneJsonToParams(redis_user);

  ReadStringOneJsonToParams(redis_password);

  ReadOneJsonToParams(redis_db, integer);

  ReadOneJsonToParams(redis_read_access_slave, boolean);

  ReadOneJsonToParams(redis_connect_keep_alive, boolean);

  ReadOneJsonToParams(redis_connect_timeout, integer);

  ReadOneJsonToParams(redis_socket_timeout, integer);

  ReadOneJsonToParams(redis_conn_pool_size, integer);

  ReadOneJsonToParams(redis_wait_timeout, integer);

  ReadOneJsonToParams(redis_connection_lifetime, integer);

  ReadOneJsonToParams(redis_sentinel_connect_timeout, integer);

  ReadOneJsonToParams(redis_sentinel_socket_timeout, integer);

  ReadOneJsonToParams(storage_slice_import, integer);

  ReadOneJsonToParams(storage_slice, integer);

  redis_connection_params->storage_slice_import =
      redis_connection_params->storage_slice_import > 0
          ? redis_connection_params->storage_slice_import
          : redis_connection_params->storage_slice;

  ReadOneJsonToParams(keys_sending_size, integer);

  ReadOneJsonToParams(using_md5_prefix_name, boolean);

  ReadStringOneJsonToParams(model_tag_import);

  ReadStringArrayJsonToParams(redis_hash_tags_import);

  ReadStringOneJsonToParams(model_tag_runtime);

  ReadStringArrayJsonToParams(redis_hash_tags_runtime);

  ReadOneJsonToParams(expire_model_tag_in_seconds, integer);

  ReadOneJsonToParams(table_store_mode, integer);

  ReadStringOneJsonToParams(model_lib_abs_dir);

#undef ReadOneJsonToParams
#undef ReadStringOneJsonToParams
#undef ReadArrayJsonToParams
#undef ReadStringArrayJsonToParams

  json_value_free(config_value);
  free(file_contents);

  return Status::OK();
}