Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

feat: add validation for value updating through http api #714

Merged
merged 5 commits into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/dsn/utility/flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ struct hash<flag_tag>
// The program corrupts if the validation failed.
#define DSN_DEFINE_validator(name, validator) \
static auto FLAGS_VALIDATOR_FN_##name = validator; \
static const dsn::flag_validator FLAGS_VALIDATOR_##name(#name, []() { \
dassert(FLAGS_VALIDATOR_FN_##name(FLAGS_##name), "validation failed: %s", #name); \
})
static const dsn::flag_validator FLAGS_VALIDATOR_##name( \
#name, []() { return FLAGS_VALIDATOR_FN_##name(FLAGS_##name); })
levy5307 marked this conversation as resolved.
Show resolved Hide resolved

#define DSN_TAG_VARIABLE(name, tag) \
COMPILE_ASSERT(sizeof(decltype(FLAGS_##name)), exist_##name##_##tag); \
Expand All @@ -89,10 +88,11 @@ class flag_registerer
};

// An utility class that registers a validator upon initialization.
using validator_fn = std::function<bool()>;
class flag_validator
{
public:
flag_validator(const char *name, std::function<void()>);
flag_validator(const char *name, validator_fn);
};

class flag_tagger
Expand Down
18 changes: 10 additions & 8 deletions src/utils/flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <dsn/utility/string_conv.h>
#include <dsn/c/api_utilities.h>
#include <boost/optional/optional.hpp>
#include <fmt/format.h>
#include <dsn/dist/fmt_logging.h>

#include <map>

Expand All @@ -27,27 +27,29 @@ enum value_type
FV_MAX_INDEX = 6,
};

using validator_fn = std::function<void()>;

class flag_data
{
public:
#define FLAG_DATA_LOAD_CASE(type, type_enum, suffix) \
case type_enum: \
value<type>() = dsn_config_get_value_##suffix(_section, _name, value<type>(), _desc); \
if (_validator) { \
_validator(); \
dassert_f(_validator(), "validation failed: {}", _name); \
} \
break

#define FLAG_DATA_UPDATE_CASE(type, type_enum, suffix) \
case type_enum: \
type tmpval_##type_enum; \
case type_enum: { \
type old_val = value<type>(), tmpval_##type_enum; \
if (!dsn::buf2##suffix(val, tmpval_##type_enum)) { \
return error_s::make(ERR_INVALID_PARAMETERS, fmt::format("{} in invalid", val)); \
return error_s::make(ERR_INVALID_PARAMETERS, fmt::format("{} is invalid", val)); \
} \
value<type>() = tmpval_##type_enum; \
break
if (!_validator()) { \
value<type>() = old_val; \
return error_s::make(ERR_INVALID_PARAMETERS, "value validation failed"); \
} \
} break

#define FLAG_DATA_UPDATE_STRING() \
case FV_STRING: \
Expand Down