From e7f4d1b59ff96432826873208346a78e028fa8cd Mon Sep 17 00:00:00 2001 From: Amin Ben Romdhane Date: Mon, 23 Oct 2023 10:00:05 +0200 Subject: [PATCH] Docs: unique key and linker update --- README.md | 1 + docs/guide/linker_design.md | 213 ++++++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 docs/guide/linker_design.md diff --git a/README.md b/README.md index c0625e06..c2de276f 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ All supported tools are presented in this file[BBFDM Tools](./docs/guide/tools.m * [How to Configure MACVLAN](./docs/guide/macvlan_interface.md) * [Explain Policy Based Routing Management](./docs/guide/policy_based_routing.md) * [TR181 DNS datamodel](./docs/guide/device_dns.md) +* [Linker design](./docs/guide/linker_design.md) ## External dependencies for datamodel objects diff --git a/docs/guide/linker_design.md b/docs/guide/linker_design.md new file mode 100644 index 00000000..f3c8208c --- /dev/null +++ b/docs/guide/linker_design.md @@ -0,0 +1,213 @@ +# Datamodel Linker + +Aim of this document is to explain how to migrate the linker functionality to the new linker design. + +As per the definition in TR-181, each multi-instance object should have at least one unique key to identify each instance that's why in the current implementation we have defined two arguments in `DMOBJ` structure to support that: + - `get_linker` function pointer to specify the linker value + - `unique_keys` array to list the unique key parameters + +```bash +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */ +{"Interface", &DMWRITE, addObjIPInterface, delObjIPInterface, NULL, browseIPInterfaceInst, NULL, NULL, tIPInterfaceObj, tIPInterfaceParams, get_linker_ip_interface, BBFDM_BOTH, LIST_KEY{"Alias", "Name", NULL}}, +``` + +However, this implementation caused us many issues, such as: + +- The unique key list can include parameters that are not yet supported. +- A parameter can map to another multi-instance object that doesn't have a linker function. + +To improve this requirement, we introduce a new argument `dm_flags` in `DMLEAF` structure which can play the role of defining all required information above. + +The new `dm_flags` argument can only support for now 3 enumerations: + + * `DM_FLAG_REFERENCE`: parameter value should be an object reference available in the tree + * `DM_FLAG_UNIQUE`: parameter value should be used to identify each instance + * `DM_FLAG_LINKER`: parameter value can be used to identify each instance when calling a set method since each multi-instance object can have many unique keys + +> Note: + +- `DM_FLAG_LINKER` **must** be defined only once for each multi-instance object. +- Each object can have multiple unique keys. +- Regarding JSON plugin, we also introduce a new array option to support the same functionality. `"flags": [ "Reference", "Unique", "Linker" ]`. + +Now with the new design datamodel gives more flexibility to define any parameter as a unique key, linker and reference at the same time, and all linker functions was removed and all related APIs are deprecated. + +Below the list of APIs that have been deprecated: +- dm_entry_validate_allowed_objects +- adm_entry_get_linker_param +- adm_entry_get_linker_value + +Below the list of new APIs that we introduced: +- dm_validate_allowed_objects +- adm_entry_get_reference_param +- bbf_get_reference_param +- bbf_get_reference_args + + +Actually bbfdm supports two methods to expose datamodel tree: + +- datamodel exposed via bbfdm, which includes the main tree defined in bbfdm package and datamodel registred via JSON or DotSo plugins. +- datamodel exposed through micro-services. + +In the next item, we will explain how to migrate to the new linker design based on the datamodel registration. + +## Migrate to the new linker design + +1. Update `dm_falgs` argument of `DMLEAF` structure + +- Parameter exposed via main tree, DotSo plugin or micro-service: add `DM_FLAG_REFERENCE` to all parameters that have a path reference as a value. + +```bash +DMLEAF tIPInterfaceParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/ +... +"LowerLayers", &DMWRITE, DMT_STRING, get_IPInterface_LowerLayers, set_IPInterface_LowerLayers, BBFDM_BOTH, DM_FLAG_REFERENCE}, +... +} +``` + +- Parameter exposed via JSON plugin: add `Reference` value to the `flags` option for all parameters that have a path reference as a value + +```bash +"Profile": { + "type": "string", + "read": true, + ... + "flags": [ + "Reference" + ], + ... +} +``` + +2. Update Get method based on the new API + +Before updating the get method, it is important to know which unique key parameter is used to identify the path reference then update the get method accordingly. + +- Parameter exposed via main tree or DotSo plugin: use `adm_entry_get_reference_param` API to get the path reference + +```bash +static int get_MQTTBroker_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *iface = NULL; + + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "interface", &iface); + adm_entry_get_reference_param(ctx, "Device.IP.Interface.*.Name", iface, value); + return 0; +} +``` + +- Parameter exposed via micro-service: use `bbf_get_reference_param` API to get the path reference + +```bash +static int get_client_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *iface = NULL; + + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "interface", &iface); + + return bbf_get_reference_param("Device.IP.Interface.", "Name", iface, value); + +} +``` + +- Parameter exposed via JSON plugin: update the `linker_obj` option with the full parameter path to obtain the path reference + +```bash +"Profile": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "flags": [ + "Reference" + ], + "mapping": [ + { + "type": "uci", + "uci": { + "file": "urlfilter", + "section": { + "type": "filter" + }, + "option": { + "name": "profile" + } + }, + "linker_obj": "Device.{BBF_VENDOR_PREFIX}URLFilter.Profile.*.Name" + } + ] +} +``` + +> Note: + +- All instances should be replaced with the instance wildcard '*'. + +3. Update Set method based on the new API + +- Parameter exposed via main tree, DotSo plugin or micro-service: first, add `DM_FLAG_LINKER` to mark that the parameter is being used as a linker for that object. + +```bash +DMLEAF tIPInterfaceParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/ +... +{"Name", &DMREAD, DMT_STRING, get_IPInterface_Name, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE|DM_FLAG_LINKER}, +... +} +``` + +Then, use `bbf_get_reference_args` to get the reference path and value in the set method. + +```bash +static int set_client_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *allowed_objects[] = {"Device.IP.Interface.", NULL}; + struct dm_reference reference = {0}; + + bbf_get_reference_args(value, &reference); + + switch (action) { + case VALUECHECK: + if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) + return FAULT_9007; + + break; + case VALUESET: + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "interface", reference.value); + break; + } + return 0; +} +``` + +- Parameter exposed via JSON plugin: add `Linker` value to the `flags` array to mark that the parameter is being used as a linker for that object. + +```bash +"Name": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "flags": [ + "Unique", + "Linker" + ], + ... +} +``` + +The following links provide more examples of how the linker was implemented. + +- https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/libbbfdm/dmtree/tr181/ip.c#L2242 +- https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/libbbfdm/dmtree/tr181/ip.c#L1273 +- https://dev.iopsys.eu/bbf/timemngr/-/blob/devel/src/times.c#L456 +- https://dev.iopsys.eu/iopsys/hostmngr/-/blob/devel/src/bbf_plugin/hosts.c#L404 +- https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/test/files/etc/bbfdm/plugins/urlfilter.json#L135 +- https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/test/files/etc/bbfdm/plugins/urlfilter.json#L293