Skip to content

Commit

Permalink
flb_config_map: add flb_config_map_set_kvlist for processors which no…
Browse files Browse the repository at this point in the history
…w use kvlists for properties.

Signed-off-by: Phillip Whelan <[email protected]>
  • Loading branch information
pwhelan committed Mar 22, 2024
1 parent be92941 commit 0475108
Showing 1 changed file with 305 additions and 0 deletions.
305 changes: 305 additions & 0 deletions src/flb_config_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,311 @@ int flb_config_map_set(struct mk_list *properties, struct mk_list *map, void *co
m_list = (struct mk_list **) (base + m->offset);
*m_list = m->value.val.list;
}
else {
flb_error("[config map#2] unknown type: %d", m->type);
return -1;
}
}
}

return 0;
}

/*
* Function used by plugins that needs to populate their context structure with the
* configuration properties already mapped.
*/
int flb_config_map_set_from_kvlist(struct cfl_kvlist *properties, struct mk_list *map, void *context)
{
int ret;
int len;
char *base;
char *m_bool;
int *m_i_num;
double *m_d_num;
size_t *m_s_num;
flb_sds_t *m_str;
struct mk_list *head;
struct mk_list *m_head;
struct mk_list **m_list;
struct mk_list *list;
struct cfl_array **m_array;
struct cfl_kvlist **m_kvlist;
struct flb_config_map *m = NULL;
struct flb_config_map_val *entry = NULL;
struct cfl_list *chead = NULL;
struct cfl_kvpair *pair = NULL;

base = context;

/* Link 'already processed default values' into the caller context */
mk_list_foreach(m_head, map) {
m = mk_list_entry(m_head, struct flb_config_map, _head);

/*
* If the map type allows multiple entries, the user context is a pointer
* for a linked list. We just point their structure to our pre-processed
* list of entries.
*/
if (m->flags & FLB_CONFIG_MAP_MULT && m->set_property == FLB_TRUE) {
m_list = (struct mk_list **) (base + m->offset);
*m_list = m->value.mult;
continue;
}

/*
* If no default value exists or the map will not write to the user
* context.. skip it.
*/
if (!m->def_value || m->set_property == FLB_FALSE) {
continue;
}

/*
* If a property set by the user will override the default value, just
* do not put the default value into the context since it will be replaced
* later.
*/
// ret = properties_override_default(properties, m->name);
// if (ret == FLB_TRUE) {
// continue;
// }

/* All the following steps are direct writes to the user context */
if (m->type == FLB_CONFIG_MAP_STR) {
m_str = (char **) (base + m->offset);
*m_str = m->value.val.str;
}
else if (m->type == FLB_CONFIG_MAP_INT) {
m_i_num = (int *) (base + m->offset);
*m_i_num = m->value.val.i_num;
}
else if (m->type == FLB_CONFIG_MAP_DOUBLE) {
m_d_num = (double *) (base + m->offset);
*m_d_num = m->value.val.d_num;
}
else if (m->type == FLB_CONFIG_MAP_SIZE) {
m_s_num = (size_t *) (base + m->offset);
*m_s_num = m->value.val.s_num;
}
else if (m->type == FLB_CONFIG_MAP_TIME) {
m_i_num = (int *) (base + m->offset);
*m_i_num = m->value.val.s_num;
}
else if (m->type == FLB_CONFIG_MAP_BOOL) {
m_bool = (char *) (base + m->offset);
*m_bool = m->value.val.boolean;
}
else if (m->type >= FLB_CONFIG_MAP_CLIST ||
m->type <= FLB_CONFIG_MAP_SLIST_4) {
m_list = (struct mk_list **) (base + m->offset);
*m_list = m->value.val.list;
}
else {
flb_error("[config map#0] unknown type: %d", m->type);
return -1;
}
}

/*
* Iterate all properties coming from the configuration reader. If a property overrides
* a default value already set in the previous step, just link to the new value.
*/
cfl_list_foreach(chead, &properties->list) {
pair = cfl_list_entry(chead, struct cfl_kvpair, _head);

if (pair == NULL || pair->key == NULL || pair->val == NULL) {
continue;
}

mk_list_foreach(m_head, map) {
m = mk_list_entry(m_head, struct flb_config_map, _head);
if (flb_sds_len(pair->key) != flb_sds_len(m->name)) {
m = NULL;
continue;
}

if (strncasecmp(pair->key, m->name, flb_sds_len(m->name)) == 0) {
break;
}
m = NULL;
continue;
}

if (!m || m->set_property == FLB_FALSE) {
continue;
}

/* Check if the map allows multiple entries */
if (m->flags & FLB_CONFIG_MAP_MULT) {
/* Create node */
entry = flb_calloc(1, sizeof(struct flb_config_map_val));
if (!entry) {
flb_errno();
return -1;
}

entry->type = m->type;

/* Populate value */
if (m->type == FLB_CONFIG_MAP_STR) {
if (pair->val->type != CFL_VARIANT_STRING) {
flb_error("[config map] non-matching type: %s", pair->key);
return -1;
}
entry->val.str = flb_sds_create(pair->val->data.as_string);
}
else if (m->type == FLB_CONFIG_MAP_INT) {
switch (pair->val->type) {
case CFL_VARIANT_STRING:
entry->val.i_num = atoi(pair->val->data.as_string);
break;
case CFL_VARIANT_INT:
entry->val.i_num = pair->val->data.as_int64;
break;
default:
flb_error("[config map] non-matching type: %s", pair->key);
return -1;
}
}
else if (m->type == FLB_CONFIG_MAP_DOUBLE) {
switch (pair->val->type) {
case CFL_VARIANT_STRING:
entry->val.i_num = atoi(pair->val->data.as_string);
break;
case CFL_VARIANT_INT:
entry->val.d_num = (double)pair->val->data.as_int64;
break;
case CFL_VARIANT_DOUBLE:
entry->val.d_num = pair->val->data.as_double;
break;
default:
flb_error("[config map] non-matching type: %s", pair->key);
return -1;
}
}
else if (m->type == FLB_CONFIG_MAP_SIZE) {
entry->val.s_num = flb_utils_size_to_bytes(pair->val->data.as_string);
}
else if (m->type == FLB_CONFIG_MAP_TIME) {
entry->val.i_num = flb_utils_time_to_seconds(pair->val->data.as_string);
}
else if (m->type == FLB_CONFIG_MAP_BOOL) {
ret = flb_utils_bool(pair->val->data.as_string);
if (ret == -1) {
flb_free(entry);
flb_error("[config map] invalid value for boolean property '%s=%s'",
m->name, pair->val->data.as_string);
return -1;
}
entry->val.boolean = ret;
}
else if (m->type >= FLB_CONFIG_MAP_CLIST &&
m->type <= FLB_CONFIG_MAP_SLIST_4) {

list = parse_string_map_to_list(m, pair->val->data.as_string);
if (!list) {
flb_error("[config map] cannot parse list of values '%s'",
pair->val->data.as_string);
flb_free(entry);
return -1;
}
entry->val.list = list;

/* Validate the number of entries are the minimum expected */
len = mk_list_size(list);
ret = check_list_size(list, m->type);
if (ret == -1) {
flb_error("[config map] property '%s' expects %i values "
"(only %i were found)",
pair->val->data.as_string,
flb_config_map_expected_values(m->type), len);
/*
* Register the entry anyways, so on exit the resources will
* be released
*/
mk_list_add(&entry->_head, m->value.mult);
return -1;
}
}
else {
flb_error("[config map#1] unknown type: %d", m->type);
return -1;
}

/* Add entry to the map 'mult' list tail */
mk_list_add(&entry->_head, m->value.mult);

/* Override user context */
m_list = (struct mk_list **) (base + m->offset);
*m_list = m->value.mult;
}
else if (map != NULL) {
/* Direct write to user context */
if (m->type == FLB_CONFIG_MAP_STR) {
if (pair->val->type != CFL_VARIANT_STRING) {
flb_error("[config map] unmatched type: %s", pair->key);
return -1;
}
m_str = (char **) (base + m->offset);
*m_str = pair->val->data.as_string;
}
else if (m->type == FLB_CONFIG_MAP_INT) {
m_i_num = (int *) (base + m->offset);
*m_i_num = atoi(pair->val->data.as_string);
}
else if (m->type == FLB_CONFIG_MAP_DOUBLE) {
m_d_num = (double *) (base + m->offset);
*m_d_num = atof(pair->val->data.as_string);
}
else if (m->type == FLB_CONFIG_MAP_BOOL) {
m_bool = (char *) (base + m->offset);
ret = flb_utils_bool(pair->val->data.as_string);
if (ret == -1) {
flb_error("[config map] invalid value for boolean property '%s=%s'",
m->name, pair->val->data.as_string);
return -1;
}
*m_bool = ret;
}
else if (m->type == FLB_CONFIG_MAP_SIZE) {
m_s_num = (size_t *) (base + m->offset);
*m_s_num = flb_utils_size_to_bytes(pair->val->data.as_string);
}
else if (m->type == FLB_CONFIG_MAP_TIME) {
m_i_num = (int *) (base + m->offset);
*m_i_num = flb_utils_time_to_seconds(pair->val->data.as_string);
}
else if (m->type >= FLB_CONFIG_MAP_CLIST &&
m->type <= FLB_CONFIG_MAP_SLIST_4) {
list = parse_string_map_to_list(m, pair->val->data.as_string);
if (!list) {
flb_error("[config map] cannot parse list of values '%s'", pair->val->data.as_string);
flb_free(entry);
return -1;
}

if (m->value.val.list) {
destroy_map_val(m->type, &m->value);
}

m->value.val.list = list;
m_list = (struct mk_list **) (base + m->offset);
*m_list = m->value.val.list;
}
else if (m->type == FLB_CONFIG_MAP_KVLIST) {
m_kvlist = (struct cfl_kvlist **) (base + m->offset);
*m_kvlist = m->value.val.kvlist;
}
else if (m->type == FLB_CONFIG_MAP_ARRAY) {
m->value.val.array = pair->val->data.as_array;
m_array = (struct cfl_array **) (base + m->offset);
*m_array = m->value.val.array;
}
else {
flb_error("[config map#2] unknown type: %d", m->type);
return -1;
}
}
}

Expand Down

0 comments on commit 0475108

Please sign in to comment.