microservice: add support to register multiple objects

This commit is contained in:
Vivek Kumar Dutta 2024-03-06 04:17:26 +00:00
parent 205e65e40d
commit 3d83590251
4 changed files with 103 additions and 32 deletions

View file

@ -950,6 +950,7 @@ enum {
BBF_SERVICE_NAME,
BBF_SERVICE_PARENT_DM,
BBF_SERVICE_OBJECT,
BBF_SERVICE_MULTI_OBJECTS,
__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_PARENT_DM] = { .name = "parent_dm", .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)
@ -1026,16 +1028,31 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o
goto end;
}
if (!tb[BBF_SERVICE_OBJECT]) {
blobmsg_add_string(&bb, "error", "service object should be defined!!");
if (!tb[BBF_SERVICE_OBJECT] && !tb[BBF_SERVICE_MULTI_OBJECTS]) {
blobmsg_add_string(&bb, "error", "service object/multiple_objects should be defined!!");
goto end;
}
char *srv_name = blobmsg_get_string(tb[BBF_SERVICE_NAME]);
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);
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)
{
struct blob_buf bb;
struct blob_buf bb = {0};
uint32_t ubus_id;
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, "name", u->config.out_name);
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);
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));
}
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");
if (DM_STRLEN(opt_val)) {
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");
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;
}
if (DM_STRLEN(daemon_ctx->config.out_root_obj) == 0) {
ERR("output root obj not defined");
return -1;

View file

@ -7,6 +7,8 @@
#include "dmbbf.h"
#define MAX_MULTI_OBJS 5
struct bbfdm_async_req {
struct ubus_context *ctx;
struct ubus_request_data req;
@ -28,6 +30,7 @@ typedef struct bbfdm_config {
char out_name[32];
char out_parent_dm[32];
char out_object[32];
char multi_object[MAX_MULTI_OBJS][32];
char out_root_obj[32];
char cli_in_type[32];
char cli_in_name[128];

View file

@ -18,6 +18,20 @@
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)
{
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;
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
if (dynamic_obj) {
char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[0].path);
unsigned int len = strlen(node_obj);
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
ERR("Object (%s) not valid\n", node_obj);
uint8_t obj_num = find_number_of_objects(dynamic_obj);
if (obj_num == 0) {
ERR("No Object defined in the required DotSo Plugin\n");
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) {
ERR("No Memory exists\n");
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;
dm_entryobj[0].permission = &DMREAD;
dm_entryobj[0].nextobj = dynamic_obj[0].root_obj;
dm_entryobj[0].leaf = dynamic_obj[0].root_leaf;
dm_entryobj[0].bbfdm_type = BBFDM_BOTH;
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
ERR("Object (%s) not valid\n", node_obj);
return -1;
}
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;
} 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)
{
DMOBJ *dm_entryobj = NULL;
int json_plugin_version = JSON_VERSION_0;
uint8_t idx = 0;
if (!file_path || !strlen(file_path) || !main_entry)
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] == '.')
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) {
ERR("ERROR: No Memory exists\n");
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[0].permission = &DMREAD;
dm_entryobj[0].nextobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ));
dm_entryobj[0].leaf = NULL;
dm_entryobj[0].bbfdm_type = BBFDM_BOTH;
dm_entryobj[idx].obj = dm_dynamic_strdup(json_memhead, obj_prefix);
dm_entryobj[idx].permission = &DMREAD;
dm_entryobj[idx].nextobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ));
dm_entryobj[idx].leaf = NULL;
dm_entryobj[idx].bbfdm_type = BBFDM_BOTH;
parse_obj(node_obj, jobj, dm_entryobj[0].nextobj, 0, json_plugin_version, json_list);
break;
parse_obj(node_obj, jobj, dm_entryobj[idx].nextobj, 0, json_plugin_version, json_list);
idx++;
}
*main_entry = dm_entryobj;
return 0;
}

View file

@ -59,12 +59,14 @@ static bool add_service_to_main_tree(DMOBJ *main_dm, char *srv_name, char *srv_p
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;
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;
}
@ -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)
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;
if (!add_service_to_main_tree(main_dm, srv_name, srv_parent_dm, srv_obj))