mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
microservice: add support to register multiple objects
This commit is contained in:
parent
205e65e40d
commit
3d83590251
4 changed files with 103 additions and 32 deletions
|
|
@ -950,6 +950,7 @@ enum {
|
||||||
BBF_SERVICE_NAME,
|
BBF_SERVICE_NAME,
|
||||||
BBF_SERVICE_PARENT_DM,
|
BBF_SERVICE_PARENT_DM,
|
||||||
BBF_SERVICE_OBJECT,
|
BBF_SERVICE_OBJECT,
|
||||||
|
BBF_SERVICE_MULTI_OBJECTS,
|
||||||
__BBF_SERVICE_MAX,
|
__BBF_SERVICE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -958,6 +959,7 @@ static const struct blobmsg_policy service_policy[] = {
|
||||||
[BBF_SERVICE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
|
[BBF_SERVICE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
|
||||||
[BBF_SERVICE_PARENT_DM] = { .name = "parent_dm", .type = BLOBMSG_TYPE_STRING },
|
[BBF_SERVICE_PARENT_DM] = { .name = "parent_dm", .type = BLOBMSG_TYPE_STRING },
|
||||||
[BBF_SERVICE_OBJECT] = { .name = "object", .type = BLOBMSG_TYPE_STRING },
|
[BBF_SERVICE_OBJECT] = { .name = "object", .type = BLOBMSG_TYPE_STRING },
|
||||||
|
[BBF_SERVICE_MULTI_OBJECTS] = { .name = "multiple_objects", .type = BLOBMSG_TYPE_ARRAY },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void service_list(struct blob_buf *bb)
|
static void service_list(struct blob_buf *bb)
|
||||||
|
|
@ -1026,16 +1028,31 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tb[BBF_SERVICE_OBJECT]) {
|
if (!tb[BBF_SERVICE_OBJECT] && !tb[BBF_SERVICE_MULTI_OBJECTS]) {
|
||||||
blobmsg_add_string(&bb, "error", "service object should be defined!!");
|
blobmsg_add_string(&bb, "error", "service object/multiple_objects should be defined!!");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *srv_name = blobmsg_get_string(tb[BBF_SERVICE_NAME]);
|
char *srv_name = blobmsg_get_string(tb[BBF_SERVICE_NAME]);
|
||||||
char *srv_parent_dm = blobmsg_get_string(tb[BBF_SERVICE_PARENT_DM]);
|
char *srv_parent_dm = blobmsg_get_string(tb[BBF_SERVICE_PARENT_DM]);
|
||||||
char *srv_obj = blobmsg_get_string(tb[BBF_SERVICE_OBJECT]);
|
char *srv_obj = NULL;
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
bool res = load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj);
|
if (tb[BBF_SERVICE_MULTI_OBJECTS]) {
|
||||||
|
struct blob_attr *objs = tb[BBF_SERVICE_MULTI_OBJECTS];
|
||||||
|
struct blob_attr *obj = NULL;
|
||||||
|
size_t rem;
|
||||||
|
|
||||||
|
blobmsg_for_each_attr(obj, objs, rem) {
|
||||||
|
srv_obj = blobmsg_get_string(obj);
|
||||||
|
res |= load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj);
|
||||||
|
}
|
||||||
|
} else if (tb[BBF_SERVICE_OBJECT]) {
|
||||||
|
srv_obj = blobmsg_get_string(tb[BBF_SERVICE_OBJECT]);
|
||||||
|
res = load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj);
|
||||||
|
} else {
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
|
|
||||||
blobmsg_add_u8(&bb, "status", res);
|
blobmsg_add_u8(&bb, "status", res);
|
||||||
run_schema_updater(u);
|
run_schema_updater(u);
|
||||||
|
|
@ -1345,7 +1362,7 @@ static void periodic_instance_updater(struct uloop_timeout *t)
|
||||||
|
|
||||||
static bool register_service(struct ubus_context *ctx)
|
static bool register_service(struct ubus_context *ctx)
|
||||||
{
|
{
|
||||||
struct blob_buf bb;
|
struct blob_buf bb = {0};
|
||||||
uint32_t ubus_id;
|
uint32_t ubus_id;
|
||||||
struct bbfdm_context *u;
|
struct bbfdm_context *u;
|
||||||
|
|
||||||
|
|
@ -1365,7 +1382,15 @@ static bool register_service(struct ubus_context *ctx)
|
||||||
blobmsg_add_string(&bb, "cmd", "register");
|
blobmsg_add_string(&bb, "cmd", "register");
|
||||||
blobmsg_add_string(&bb, "name", u->config.out_name);
|
blobmsg_add_string(&bb, "name", u->config.out_name);
|
||||||
blobmsg_add_string(&bb, "parent_dm", u->config.out_parent_dm);
|
blobmsg_add_string(&bb, "parent_dm", u->config.out_parent_dm);
|
||||||
blobmsg_add_string(&bb, "object", u->config.out_object);
|
|
||||||
|
if (DM_STRLEN(u->config.multi_object[0]) != 0) {
|
||||||
|
void *arr = blobmsg_open_array(&bb, "multiple_objects");
|
||||||
|
for (int i = 0; i < MAX_MULTI_OBJS && DM_STRLEN(u->config.multi_object[i]) != 0; i++)
|
||||||
|
blobmsg_add_string(&bb, NULL, u->config.multi_object[i]);
|
||||||
|
blobmsg_close_array(&bb, arr);
|
||||||
|
} else {
|
||||||
|
blobmsg_add_string(&bb, "object", u->config.out_object);
|
||||||
|
}
|
||||||
|
|
||||||
ubus_invoke(ctx, ubus_id, "service", bb.head, NULL, NULL, 5000);
|
ubus_invoke(ctx, ubus_id, "service", bb.head, NULL, NULL, 5000);
|
||||||
blob_buf_free(&bb);
|
blob_buf_free(&bb);
|
||||||
|
|
@ -1435,6 +1460,19 @@ static int bbfdm_load_deamon_config(bbfdm_config_t *config, const char *json_pat
|
||||||
replace_str(opt_val, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->out_object, sizeof(config->out_object));
|
replace_str(opt_val, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->out_object, sizeof(config->out_object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_object *arr_obj = NULL;
|
||||||
|
char *mem_obj = NULL;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
dmjson_foreach_value_in_array(deamon_obj, arr_obj, mem_obj, i, 2, "output", "multiple_objects") {
|
||||||
|
if (i < MAX_MULTI_OBJS) {
|
||||||
|
replace_str(mem_obj, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->multi_object[i], sizeof(config->multi_object[i]));
|
||||||
|
} else {
|
||||||
|
WARNING("More multiple_object defined, can handle only %d ...", MAX_MULTI_OBJS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
opt_val = dmjson_get_value(deamon_obj, 2, "output", "root_obj");
|
opt_val = dmjson_get_value(deamon_obj, 2, "output", "root_obj");
|
||||||
if (DM_STRLEN(opt_val)) {
|
if (DM_STRLEN(opt_val)) {
|
||||||
strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj));
|
strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj));
|
||||||
|
|
@ -1637,10 +1675,12 @@ int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
|
||||||
ERR("output parent dm not defined");
|
ERR("output parent dm not defined");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (DM_STRLEN(daemon_ctx->config.out_object) == 0) {
|
|
||||||
ERR("output object not defined");
|
if (DM_STRLEN(daemon_ctx->config.out_object) == 0 && DM_STRLEN(daemon_ctx->config.multi_object[0]) == 0) {
|
||||||
|
ERR("output object and multiple_objects both are not defined");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DM_STRLEN(daemon_ctx->config.out_root_obj) == 0) {
|
if (DM_STRLEN(daemon_ctx->config.out_root_obj) == 0) {
|
||||||
ERR("output root obj not defined");
|
ERR("output root obj not defined");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "dmbbf.h"
|
#include "dmbbf.h"
|
||||||
|
|
||||||
|
#define MAX_MULTI_OBJS 5
|
||||||
|
|
||||||
struct bbfdm_async_req {
|
struct bbfdm_async_req {
|
||||||
struct ubus_context *ctx;
|
struct ubus_context *ctx;
|
||||||
struct ubus_request_data req;
|
struct ubus_request_data req;
|
||||||
|
|
@ -28,6 +30,7 @@ typedef struct bbfdm_config {
|
||||||
char out_name[32];
|
char out_name[32];
|
||||||
char out_parent_dm[32];
|
char out_parent_dm[32];
|
||||||
char out_object[32];
|
char out_object[32];
|
||||||
|
char multi_object[MAX_MULTI_OBJS][32];
|
||||||
char out_root_obj[32];
|
char out_root_obj[32];
|
||||||
char cli_in_type[32];
|
char cli_in_type[32];
|
||||||
char cli_in_name[128];
|
char cli_in_name[128];
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,20 @@
|
||||||
|
|
||||||
extern struct list_head global_memhead;
|
extern struct list_head global_memhead;
|
||||||
|
|
||||||
|
static uint8_t find_number_of_objects(DM_MAP_OBJ *dynamic_obj)
|
||||||
|
{
|
||||||
|
if (!dynamic_obj)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t len = 0;
|
||||||
|
|
||||||
|
while (dynamic_obj[len].path)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry)
|
int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry)
|
||||||
{
|
{
|
||||||
if (!lib_handle || !file_path || !strlen(file_path) || !main_entry)
|
if (!lib_handle || !file_path || !strlen(file_path) || !main_entry)
|
||||||
|
|
@ -35,27 +49,35 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_ent
|
||||||
DM_MAP_OBJ *dynamic_obj = NULL;
|
DM_MAP_OBJ *dynamic_obj = NULL;
|
||||||
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
|
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
|
||||||
if (dynamic_obj) {
|
if (dynamic_obj) {
|
||||||
char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[0].path);
|
uint8_t obj_num = find_number_of_objects(dynamic_obj);
|
||||||
unsigned int len = strlen(node_obj);
|
if (obj_num == 0) {
|
||||||
|
ERR("No Object defined in the required DotSo Plugin\n");
|
||||||
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
|
|
||||||
ERR("Object (%s) not valid\n", node_obj);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&global_memhead, 2, sizeof(DMOBJ));
|
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&global_memhead, obj_num + 1, sizeof(DMOBJ));
|
||||||
if (dm_entryobj == NULL) {
|
if (dm_entryobj == NULL) {
|
||||||
ERR("No Memory exists\n");
|
ERR("No Memory exists\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_obj[len-1] = 0;
|
for (int i = 0; dynamic_obj[i].path; i++) {
|
||||||
|
char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[i].path);
|
||||||
|
unsigned int len = strlen(node_obj);
|
||||||
|
|
||||||
dm_entryobj[0].obj = node_obj;
|
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
|
||||||
dm_entryobj[0].permission = &DMREAD;
|
ERR("Object (%s) not valid\n", node_obj);
|
||||||
dm_entryobj[0].nextobj = dynamic_obj[0].root_obj;
|
return -1;
|
||||||
dm_entryobj[0].leaf = dynamic_obj[0].root_leaf;
|
}
|
||||||
dm_entryobj[0].bbfdm_type = BBFDM_BOTH;
|
|
||||||
|
node_obj[len-1] = 0;
|
||||||
|
|
||||||
|
dm_entryobj[i].obj = node_obj;
|
||||||
|
dm_entryobj[i].permission = &DMREAD;
|
||||||
|
dm_entryobj[i].nextobj = dynamic_obj[i].root_obj;
|
||||||
|
dm_entryobj[i].leaf = dynamic_obj[i].root_leaf;
|
||||||
|
dm_entryobj[i].bbfdm_type = BBFDM_BOTH;
|
||||||
|
}
|
||||||
|
|
||||||
*main_entry = dm_entryobj;
|
*main_entry = dm_entryobj;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -76,7 +98,9 @@ int free_dotso_plugin(void *lib_handle)
|
||||||
|
|
||||||
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry)
|
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry)
|
||||||
{
|
{
|
||||||
|
DMOBJ *dm_entryobj = NULL;
|
||||||
int json_plugin_version = JSON_VERSION_0;
|
int json_plugin_version = JSON_VERSION_0;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
|
||||||
if (!file_path || !strlen(file_path) || !main_entry)
|
if (!file_path || !strlen(file_path) || !main_entry)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -119,24 +143,26 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
|
||||||
if (obj_prefix[obj_prefix_len - 1] == '.')
|
if (obj_prefix[obj_prefix_len - 1] == '.')
|
||||||
obj_prefix[obj_prefix_len - 1] = 0;
|
obj_prefix[obj_prefix_len - 1] = 0;
|
||||||
|
|
||||||
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ));
|
dm_entryobj = (DMOBJ *)dm_dynamic_realloc(json_memhead, dm_entryobj, (idx + 2) * sizeof(DMOBJ));
|
||||||
if (dm_entryobj == NULL) {
|
if (dm_entryobj == NULL) {
|
||||||
ERR("ERROR: No Memory exists\n");
|
ERR("ERROR: No Memory exists\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*main_entry = dm_entryobj;
|
memset(&dm_entryobj[idx + 1], 0, sizeof(DMOBJ));
|
||||||
|
|
||||||
dm_entryobj[0].obj = dm_dynamic_strdup(json_memhead, obj_prefix);
|
dm_entryobj[idx].obj = dm_dynamic_strdup(json_memhead, obj_prefix);
|
||||||
dm_entryobj[0].permission = &DMREAD;
|
dm_entryobj[idx].permission = &DMREAD;
|
||||||
dm_entryobj[0].nextobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ));
|
dm_entryobj[idx].nextobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ));
|
||||||
dm_entryobj[0].leaf = NULL;
|
dm_entryobj[idx].leaf = NULL;
|
||||||
dm_entryobj[0].bbfdm_type = BBFDM_BOTH;
|
dm_entryobj[idx].bbfdm_type = BBFDM_BOTH;
|
||||||
|
|
||||||
parse_obj(node_obj, jobj, dm_entryobj[0].nextobj, 0, json_plugin_version, json_list);
|
parse_obj(node_obj, jobj, dm_entryobj[idx].nextobj, 0, json_plugin_version, json_list);
|
||||||
break;
|
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*main_entry = dm_entryobj;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,14 @@ static bool add_service_to_main_tree(DMOBJ *main_dm, char *srv_name, char *srv_p
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_service_registered(struct list_head *srvlist, char *srv_name)
|
static bool is_service_registered(struct list_head *srvlist, char *srv_name, char *srv_parent_dm, char *srv_obj)
|
||||||
{
|
{
|
||||||
struct service *srv = NULL;
|
struct service *srv = NULL;
|
||||||
|
|
||||||
list_for_each_entry(srv, srvlist, list) {
|
list_for_each_entry(srv, srvlist, list) {
|
||||||
if (DM_STRCMP(srv->name, srv_name) == 0)
|
if (DM_STRCMP(srv->name, srv_name) == 0 &&
|
||||||
|
DM_STRCMP(srv->parent_dm, srv_parent_dm) == 0 &&
|
||||||
|
DM_STRCMP(srv->object, srv_obj) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +104,7 @@ bool load_service(DMOBJ *main_dm, struct list_head *srv_list, char *srv_name, ch
|
||||||
if (!main_dm || !srv_list || !srv_name || !srv_parent_dm || !srv_obj)
|
if (!main_dm || !srv_list || !srv_name || !srv_parent_dm || !srv_obj)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (is_service_registered(srv_list, srv_name))
|
if (is_service_registered(srv_list, srv_name, srv_parent_dm, srv_obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!add_service_to_main_tree(main_dm, srv_name, srv_parent_dm, srv_obj))
|
if (!add_service_to_main_tree(main_dm, srv_name, srv_parent_dm, srv_obj))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue