1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

improved mapping module to support node name prefixes

This commit is contained in:
Steffen Vogel 2017-08-28 12:48:15 +02:00
parent f994e996a0
commit 50b3529c90
4 changed files with 147 additions and 71 deletions

View file

@ -36,7 +36,7 @@ struct sample;
struct list;
struct mapping_entry {
struct node *source; /**< Unused for now. */
struct node *node;
int length;
enum {
@ -71,7 +71,8 @@ struct mapping_entry {
struct {
enum timestamp_type {
MAPPING_TIMESTAMP_ORIGIN,
MAPPING_TIMESTAMP_RECEIVED
MAPPING_TIMESTAMP_RECEIVED,
MAPPING_TIMESTAMP_SENT
} id;
} timestamp;
};
@ -87,7 +88,7 @@ struct mapping {
int mapping_init(struct mapping *m);
int mapping_parse(struct mapping *m, json_t *cfg);
int mapping_parse(struct mapping *m, json_t *cfg, struct list *nodes);
int mapping_check(struct mapping *m);
@ -95,6 +96,6 @@ int mapping_destroy(struct mapping *m);
int mapping_remap(struct mapping *m, struct sample *orig, struct sample *remapped, struct stats *s);
int mapping_entry_parse(struct mapping_entry *e, json_t *cfg);
int mapping_entry_parse(struct mapping_entry *e, json_t *cfg, struct list *nodes);
int mapping_entry_parse_str(struct mapping_entry *e, const char *str);
int mapping_entry_parse_str(struct mapping_entry *e, const char *str, struct list *nodes);

View file

@ -64,7 +64,7 @@ static int map_parse(struct hook *h, json_t *cfg)
if (ret)
jerror(&err, "Failed to parse configuration of hook '%s'", plugin_name(h->_vt));
ret = mapping_parse(&p->mapping, cfg_mapping);
ret = mapping_parse(&p->mapping, cfg_mapping, NULL);
if (ret)
return ret;

View file

@ -28,18 +28,35 @@
#include "list.h"
#include "utils.h"
int mapping_entry_parse_str(struct mapping_entry *e, const char *str)
int mapping_entry_parse_str(struct mapping_entry *e, const char *str, struct list *nodes)
{
int id;
char *cpy, *type, *field, *subfield, *end;
char *cpy, *node, *type, *field, *subfield, *end;
cpy = strdup(str);
if (!cpy)
return -1;
type = strtok(cpy, ".[");
if (!type)
goto invalid_format;
if (nodes) {
node = strtok(cpy, ".");
if (!node)
goto invalid_format;
e->node = list_lookup(nodes, node);
if (!e->node)
goto invalid_format;
type = strtok(NULL, ".[");
if (!type)
type = "data";
}
else {
e->node = NULL;
type = strtok(cpy, ".[");
if (!type)
goto invalid_format;
}
if (!strcmp(type, "stats")) {
e->type = MAPPING_TYPE_STATS;
@ -53,10 +70,6 @@ int mapping_entry_parse_str(struct mapping_entry *e, const char *str)
if (!subfield)
goto invalid_format;
end = strtok(NULL, ".");
if (end)
goto invalid_format;
id = stats_lookup_id(field);
if (id < 0)
goto invalid_format;
@ -88,10 +101,6 @@ int mapping_entry_parse_str(struct mapping_entry *e, const char *str)
if (!field)
goto invalid_format;
end = strtok(NULL, ".");
if (end)
goto invalid_format;
if (!strcmp(field, "sequence"))
e->header.id = MAPPING_HEADER_SEQUENCE;
else if (!strcmp(field, "length"))
@ -107,70 +116,75 @@ int mapping_entry_parse_str(struct mapping_entry *e, const char *str)
if (!field)
goto invalid_format;
end = strtok(NULL, ".");
if (end)
goto invalid_format;
if (!strcmp(field, "origin"))
e->timestamp.id = MAPPING_TIMESTAMP_ORIGIN;
else if (!strcmp(field, "received"))
e->timestamp.id = MAPPING_TIMESTAMP_RECEIVED;
else if (!strcmp(field, "sent"))
e->timestamp.id = MAPPING_TIMESTAMP_SENT;
else
goto invalid_format;
}
else if (!strcmp(type, "data")) {
char *first_str, *last_str, *endptr;
int first, last;
e->type = MAPPING_TYPE_DATA;
first_str = strtok(NULL, "-]");
if (!first_str)
goto invalid_format;
if (first_str) {
int first, last;
last_str = strtok(NULL, "]");
if (!last_str)
last_str = first_str; /* single element: data[5] => data[5-5] */
last_str = strtok(NULL, "]");
if (!last_str)
last_str = first_str; /* single element: data[5] => data[5-5] */
end = strtok(NULL, ".");
if (end)
goto invalid_format;
first = strtoul(first_str, &endptr, 10);
if (endptr != first_str + strlen(first_str))
goto invalid_format;
first = strtoul(first_str, &endptr, 10);
if (endptr != first_str + strlen(first_str))
goto invalid_format;
last = strtoul(last_str, &endptr, 10);
if (endptr != last_str + strlen(last_str))
goto invalid_format;
last = strtoul(last_str, &endptr, 10);
if (endptr != last_str + strlen(last_str))
goto invalid_format;
if (last < first)
goto invalid_format;
if (last < first)
goto invalid_format;
e->data.offset = first;
e->length = last - first + 1;
e->data.offset = first;
e->length = last - first + 1;
}
else {
e->data.offset = 0;
e->length = 0; /* Length in unkown.. we will take all values */
}
}
else
goto invalid_format;
/* Check that there is no garbage at the end */
end = strtok(NULL, "");
if (end)
goto invalid_format;
free(cpy);
return 0;
invalid_format:
free(cpy);
return -1;
}
int mapping_entry_parse(struct mapping_entry *e, json_t *cfg)
int mapping_entry_parse(struct mapping_entry *e, json_t *j, struct list *nodes)
{
const char *str;
str = json_string_value(cfg);
str = json_string_value(j);
if (!str)
return -1;
return mapping_entry_parse_str(e, str);
return mapping_entry_parse_str(e, str, nodes);
}
int mapping_init(struct mapping *m)
@ -195,23 +209,29 @@ int mapping_destroy(struct mapping *m)
return 0;
}
int mapping_parse(struct mapping *m, json_t *cfg)
int mapping_parse(struct mapping *m, json_t *j, struct list *nodes)
{
int ret;
assert(m->state == STATE_INITIALIZED);
if (!json_is_array(cfg))
json_t *json_entry;
json_t *json_mapping;
if (json_is_string(j)) {
json_mapping = json_array();
json_array_append(json_mapping, j);
}
else if (!json_is_array(j))
return -1;
m->real_length = 0;
size_t index;
json_t *cfg_entry;
json_array_foreach(cfg, index, cfg_entry) {
json_array_foreach(j, index, json_entry) {
struct mapping_entry *e = alloc(sizeof(struct mapping_entry));
ret = mapping_entry_parse(e, cfg_entry);
ret = mapping_entry_parse(e, json_entry, nodes);
if (ret)
return ret;

View file

@ -23,74 +23,129 @@
#include <criterion/criterion.h>
#include "mapping.h"
#include "node.h"
#include "list.h"
Test(mapping, parse_nodes)
{
int ret;
struct mapping_entry m;
struct list n;
struct node n1 = { .name = "apple" };
struct node n2 = { .name = "cherry" };
struct node n3 = { .name = "carrot" };
list_init(&n);
list_push(&n, &n1);
list_push(&n, &n2);
list_push(&n, &n3);
ret = mapping_entry_parse_str(&m, "apple.ts.origin", &n);
cr_assert_eq(ret, 0);
cr_assert_eq(m.node, &n1);
cr_assert_eq(m.type, MAPPING_TYPE_TIMESTAMP);
cr_assert_eq(m.timestamp.id, MAPPING_TIMESTAMP_ORIGIN);
ret = mapping_entry_parse_str(&m, "cherry.stats.owd.mean", &n);
cr_assert_eq(ret, 0);
cr_assert_eq(m.node, &n2);
cr_assert_eq(m.type, MAPPING_TYPE_STATS);
cr_assert_eq(m.stats.id, STATS_OWD);
cr_assert_eq(m.stats.type, MAPPING_STATS_TYPE_MEAN);
ret = mapping_entry_parse_str(&m, "carrot.data[1-2]", &n);
cr_assert_eq(ret, 0);
cr_assert_eq(m.node, &n3);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 1);
cr_assert_eq(m.length, 2);
ret = mapping_entry_parse_str(&m, "carrot", &n);
cr_assert_eq(ret, 0);
cr_assert_eq(m.node, &n3);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 0);
cr_assert_eq(m.length, 0);
ret = list_destroy(&n, NULL, false);
cr_assert_eq(ret, 0);
}
Test(mapping, parse)
{
int ret;
struct mapping_entry m;
ret = mapping_entry_parse_str(&m, "ts.origin");
ret = mapping_entry_parse_str(&m, "ts.origin", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_TIMESTAMP);
cr_assert_eq(m.timestamp.id, MAPPING_TIMESTAMP_ORIGIN);
ret = mapping_entry_parse_str(&m, "hdr.sequence");
ret = mapping_entry_parse_str(&m, "hdr.sequence", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_HEADER);
cr_assert_eq(m.header.id, MAPPING_HEADER_SEQUENCE);
ret = mapping_entry_parse_str(&m, "stats.owd.mean");
ret = mapping_entry_parse_str(&m, "stats.owd.mean", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_STATS);
cr_assert_eq(m.stats.id, STATS_OWD);
cr_assert_eq(m.stats.type, MAPPING_STATS_TYPE_MEAN);
ret = mapping_entry_parse_str(&m, "data[1-2]");
ret = mapping_entry_parse_str(&m, "data[1-2]", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 1);
cr_assert_eq(m.length, 2);
ret = mapping_entry_parse_str(&m, "data[5-5]");
ret = mapping_entry_parse_str(&m, "data[5-5]", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 5);
cr_assert_eq(m.length, 1);
ret = mapping_entry_parse_str(&m, "data[22]");
ret = mapping_entry_parse_str(&m, "data[22]", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 22);
cr_assert_eq(m.length, 1);
ret = mapping_entry_parse_str(&m, "data", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 0);
cr_assert_eq(m.length, 0);
ret = mapping_entry_parse_str(&m, "data[]", NULL);
cr_assert_eq(ret, 0);
cr_assert_eq(m.type, MAPPING_TYPE_DATA);
cr_assert_eq(m.data.offset, 0);
cr_assert_eq(m.length, 0);
ret = mapping_entry_parse_str(&m, "data[]");
cr_assert_neq(ret, 0);
ret = mapping_entry_parse_str(&m, "data[1.1-2f]");
ret = mapping_entry_parse_str(&m, "data[1.1-2f]", NULL);
cr_assert_neq(ret, 0);
/* Missing parts */
ret = mapping_entry_parse_str(&m, "stats.owd");
cr_assert_neq(ret, 0);
ret = mapping_entry_parse_str(&m, "data");
ret = mapping_entry_parse_str(&m, "stats.owd", NULL);
cr_assert_neq(ret, 0);
/* This a type */
ret = mapping_entry_parse_str(&m, "hdr.sequences");
ret = mapping_entry_parse_str(&m, "hdr.sequences", NULL);
cr_assert_neq(ret, 0);
/* Check for superfluous chars at the end */
ret = mapping_entry_parse_str(&m, "stats.ts.origin.bla");
ret = mapping_entry_parse_str(&m, "stats.ts.origin.bla", NULL);
cr_assert_neq(ret, 0);
ret = mapping_entry_parse_str(&m, "stats.ts.origin.");
ret = mapping_entry_parse_str(&m, "stats.ts.origin.", NULL);
cr_assert_neq(ret, 0);
ret = mapping_entry_parse_str(&m, "data[1-2]bla");
ret = mapping_entry_parse_str(&m, "data[1-2]bla", NULL);
cr_assert_neq(ret, 0);
/* Negative length of chunk */
ret = mapping_entry_parse_str(&m, "data[5-3]");
ret = mapping_entry_parse_str(&m, "data[5-3]", NULL);
cr_assert_eq(ret, -1);
}