Skip to content

Commit

Permalink
Merge pull request #35 from giubacc/response-save-and-access-from-yaml
Browse files Browse the repository at this point in the history
add inline scripting feature for accessing out yaml tree
  • Loading branch information
Giuseppe Baccini committed Oct 19, 2023
2 parents 2c31b9e + 4208bfc commit e292ccc
Show file tree
Hide file tree
Showing 14 changed files with 675 additions and 52 deletions.
4 changes: 2 additions & 2 deletions src/.astylerc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
--indent-switches
--indent-col1-comments
--min-conditional-indent=2
--max-instatement-indent=100
--add-brackets
--max-continuation-indent=100
--add-braces
--lineend=linux
--convert-tabs
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ project(chatterbox_binary VERSION 0.0.0)

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wall -std=c++17)
# add_compile_options(-g -Wall -std=c++17)
endif()

add_definitions(-DV8_COMPRESS_POINTERS
Expand Down
128 changes: 116 additions & 12 deletions src/conversation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ void conversation::statistics::incr_categorization(const std::string &key)

conversation::conversation(scenario &parent) :
parent_(parent),
scen_out_p_resolv_(parent_.scen_out_p_resolv_),
scen_p_evaluator_(parent_.scen_p_evaluator_),
js_env_(parent.js_env_),
stats_(*this),
event_log_(parent.event_log_)
Expand Down Expand Up @@ -71,56 +73,158 @@ int conversation::process(ryml::NodeRef conversation_in,

if(scope.enabled_) {
parent_.stats_.incr_conversation_count();

auto raw_host = js_env_.eval_as<std::string>(conversation_out, key_host);
bool further_eval = false;
auto raw_host = js_env_.eval_as<std::string>(conversation_out,
key_host,
std::nullopt,
true,
nullptr,
PROP_EVAL_RGX,
&further_eval);
if(!raw_host) {
event_log_->error(ERR_FAIL_READ_HOST);
return 1;
} else {
conversation_out.remove_child(key_host);
conversation_out[key_host] << *raw_host;
if(further_eval) {
raw_host = scen_p_evaluator_.eval_as<std::string>(conversation_out,
key_host,
scen_out_p_resolv_);
}
if(!raw_host) {
event_log_->error(ERR_FAIL_READ_HOST);
utils::clear_map_node_put_key_val(conversation_out, key_error, ERR_FAIL_READ_HOST);
return 1;
}
}

conversation_out.remove_child(key_host);
conversation_out[key_host] << *raw_host;

raw_host_ = *raw_host;
auto host = raw_host_;
utils::find_and_replace(host, "http://", "");
utils::find_and_replace(host, "https://", "");
host = host.substr(0, (host.find(':') == std::string::npos ? host.length() : host.find(':')));

//auth
further_eval = false;
if(conversation_out.has_child(key_auth)) {
ryml::NodeRef auth_node = conversation_out[key_auth];
auto service = js_env_.eval_as<std::string>(auth_node, key_service, "s3");
auto service = js_env_.eval_as<std::string>(auth_node,
key_service,
"s3",
true,
nullptr,
PROP_EVAL_RGX,
&further_eval);

if(further_eval) {
service = scen_p_evaluator_.eval_as<std::string>(conversation_out,
key_service,
scen_out_p_resolv_);
if(!service) {
event_log_->error(ERR_FAIL_EVAL);
utils::clear_map_node_put_key_val(conversation_out, key_error, ERR_FAIL_EVAL);
return 1;
}
}
if(service) {
if(auth_node.has_child(key_service)) {
auth_node.remove_child(key_service);
}
auth_node[key_service] << *service;
}

auto access_key = js_env_.eval_as<std::string>(auth_node, key_access_key);
//access_key
further_eval = false;
auto access_key = js_env_.eval_as<std::string>(auth_node,
key_access_key,
std::nullopt,
true,
nullptr,
PROP_EVAL_RGX,
&further_eval);
if(further_eval) {
access_key = scen_p_evaluator_.eval_as<std::string>(conversation_out,
key_access_key,
scen_out_p_resolv_);
if(!access_key) {
event_log_->error(ERR_FAIL_EVAL);
utils::clear_map_node_put_key_val(conversation_out, key_error, ERR_FAIL_EVAL);
return 1;
}
}
if(access_key) {
auth_node.remove_child(key_access_key);
auth_node[key_access_key] << *access_key;
}

auto secret_key = js_env_.eval_as<std::string>(auth_node, key_secret_key);
//secret_key
further_eval = false;
auto secret_key = js_env_.eval_as<std::string>(auth_node,
key_secret_key,
std::nullopt,
true,
nullptr,
PROP_EVAL_RGX,
&further_eval);
if(further_eval) {
secret_key = scen_p_evaluator_.eval_as<std::string>(conversation_out,
key_secret_key,
scen_out_p_resolv_);
if(!secret_key) {
event_log_->error(ERR_FAIL_EVAL);
utils::clear_map_node_put_key_val(conversation_out, key_error, ERR_FAIL_EVAL);
return 1;
}
}
if(secret_key) {
auth_node.remove_child(key_secret_key);
auth_node[key_secret_key] << *secret_key;
}

//signed_headers
further_eval = false;
auto signed_headers = js_env_.eval_as<std::string>(auth_node,
key_signed_headers,
AUTH_AWS_DEF_SIGN_HDRS);
AUTH_AWS_DEF_SIGN_HDRS,
true,
nullptr,
PROP_EVAL_RGX,
&further_eval);
if(further_eval) {
signed_headers = scen_p_evaluator_.eval_as<std::string>(conversation_out,
key_signed_headers,
scen_out_p_resolv_);
if(!signed_headers) {
event_log_->error(ERR_FAIL_EVAL);
utils::clear_map_node_put_key_val(conversation_out, key_error, ERR_FAIL_EVAL);
return 1;
}
}
if(signed_headers) {
if(auth_node.has_child(key_signed_headers)) {
auth_node.remove_child(key_signed_headers);
}
auth_node[key_signed_headers] << *signed_headers;
}

auto region = js_env_.eval_as<std::string>(auth_node, key_region, "US");
//region
auto region = js_env_.eval_as<std::string>(auth_node,
key_region,
"US",
true,
nullptr,
PROP_EVAL_RGX,
&further_eval);

if(further_eval) {
region = scen_p_evaluator_.eval_as<std::string>(conversation_out,
key_region,
scen_out_p_resolv_);
if(!region) {
event_log_->error(ERR_FAIL_EVAL);
utils::clear_map_node_put_key_val(conversation_out, key_error, ERR_FAIL_EVAL);
return 1;
}
}
if(region) {
if(auth_node.has_child(key_region)) {
auth_node.remove_child(key_region);
Expand Down
6 changes: 6 additions & 0 deletions src/conversation.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ struct conversation {
//parent
scenario &parent_;

//scenario property resolver
scenario_property_resolver &scen_out_p_resolv_;

//scenario property evaluator
scenario_property_evaluator &scen_p_evaluator_;

//js environment
js::js_env &js_env_;

Expand Down
1 change: 0 additions & 1 deletion src/jsenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ int js_env::reset()
v8::NewStringType::kNormal).ToLocalChecked(),
v8::FunctionTemplate::New(isolate_, cbk_log));


//bind cbk_load.
global->Set(v8::String::NewFromUtf8(isolate_,
"load",
Expand Down
30 changes: 18 additions & 12 deletions src/jsenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ struct converter<bool> {
if(!val.is_keyval() && !val.is_val()) {
return false;
}
bool bval;
val >> bval;
//@todo
return true;
}
static bool isType(const v8::Local<v8::Value> &val) {
Expand All @@ -44,8 +43,7 @@ struct converter<int32_t> {
if(!val.is_keyval() && !val.is_val()) {
return false;
}
int32_t ival;
val >> ival;
//@todo
return true;
}
static bool isType(const v8::Local<v8::Value> &val) {
Expand All @@ -70,8 +68,7 @@ struct converter<uint32_t> {
if(!val.is_keyval() && !val.is_val()) {
return false;
}
uint32_t uival;
val >> uival;
//@todo
return true;
}
static bool isType(const v8::Local<v8::Value> &val) {
Expand All @@ -96,8 +93,7 @@ struct converter<double> {
if(!val.is_keyval() && !val.is_val()) {
return false;
}
double dval;
val >> dval;
//@todo
return true;
}
static bool isType(const v8::Local<v8::Value> &val) {
Expand All @@ -122,8 +118,7 @@ struct converter<std::string> {
if(!val.is_keyval() && !val.is_val()) {
return false;
}
std::string sval;
val >> sval;
//@todo
return true;
}
static bool isType(const v8::Local<v8::Value> &val) {
Expand Down Expand Up @@ -219,19 +214,30 @@ struct js_env {
static void cbk_assert(const v8::FunctionCallbackInfo<v8::Value> &args);

// ----------------------------
// --- Json Field Evaluator ---
// --- Yaml Field Evaluator ---
// ----------------------------

template <typename T>
std::optional<T> eval_as(ryml::NodeRef from,
const char *key,
const std::optional<T> default_value = std::nullopt,
bool log_errors = true,
bool *is_error = nullptr) {
bool *is_error = nullptr,
const char *check_regex = nullptr,
bool *further_eval = nullptr) {
if(!from.has_child(ryml::to_csubstr(key))) {
return default_value;
}
ryml::NodeRef val = from[ryml::to_csubstr(key)];

if(check_regex && (val.is_keyval() || val.is_val())) {
auto str_val = utils::converter<std::string>::asType(val);
if(std::regex_search(utils::converter<std::string>::asType(val), std::regex(check_regex))) {
*further_eval = true;
return std::nullopt;
}
}

if(utils::converter<T>::isType(val)) {
//eval as primitive value
return utils::converter<T>::asType(val);
Expand Down
Loading

0 comments on commit e292ccc

Please sign in to comment.