Skip to content

Commit 820efe8

Browse files
committed
parser data UPDATE parsing RESTCONF messages directly
1 parent 1bdfab6 commit 820efe8

File tree

9 files changed

+584
-117
lines changed

9 files changed

+584
-117
lines changed

src/common.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct lysc_node;
5959
#define GETMACRO4(_1, _2, _3, _4, NAME, ...) NAME
6060
#define GETMACRO5(_1, _2, _3, _4, _5, NAME, ...) NAME
6161
#define GETMACRO6(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
62+
#define GETMACRO7(_1, _2, _3, _4, _5, _6, _7, NAME, ...) NAME
6263

6364
/******************************************************************************
6465
* Logger
@@ -220,8 +221,10 @@ void ly_log_dbg(uint32_t group, const char *format, ...);
220221
LY_CHECK_ARG_RET1(CTX, ARG4, RETVAL)
221222
#define LY_CHECK_ARG_RET5(CTX, ARG1, ARG2, ARG3, ARG4, ARG5, RETVAL) LY_CHECK_ARG_RET4(CTX, ARG1, ARG2, ARG3, ARG4, RETVAL);\
222223
LY_CHECK_ARG_RET1(CTX, ARG5, RETVAL)
223-
#define LY_CHECK_ARG_RET(CTX, ...) GETMACRO6(__VA_ARGS__, LY_CHECK_ARG_RET5, LY_CHECK_ARG_RET4, LY_CHECK_ARG_RET3, \
224-
LY_CHECK_ARG_RET2, LY_CHECK_ARG_RET1, DUMMY) (CTX, __VA_ARGS__)
224+
#define LY_CHECK_ARG_RET6(CTX, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, RETVAL) LY_CHECK_ARG_RET5(CTX, ARG1, ARG2, ARG3, ARG4, ARG5, RETVAL);\
225+
LY_CHECK_ARG_RET1(CTX, ARG6, RETVAL)
226+
#define LY_CHECK_ARG_RET(CTX, ...) GETMACRO7(__VA_ARGS__, LY_CHECK_ARG_RET6, LY_CHECK_ARG_RET5, LY_CHECK_ARG_RET4, \
227+
LY_CHECK_ARG_RET3, LY_CHECK_ARG_RET2, LY_CHECK_ARG_RET1, DUMMY) (CTX, __VA_ARGS__)
225228

226229
#define LY_CHECK_CTX_EQUAL_RET2(CTX1, CTX2, RETVAL) if ((CTX1) && (CTX2) && ((CTX1) != (CTX2))) \
227230
{LOGERR(CTX1, LY_EINVAL, "Different contexts mixed in a single function call."); return RETVAL;}

src/parser_common.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "parser_data.h"
4747
#include "path.h"
4848
#include "plugins_exts/metadata.h"
49+
#include "schema_compile_node.h"
4950
#include "schema_features.h"
5051
#include "set.h"
5152
#include "tree.h"
@@ -64,6 +65,50 @@ lyd_ctx_free(struct lyd_ctx *lydctx)
6465
ly_set_erase(&lydctx->ext_val, free);
6566
}
6667

68+
LY_ERR
69+
lyd_parser_notif_eventtime_validate(const struct lyd_node *node)
70+
{
71+
LY_ERR rc = LY_SUCCESS;
72+
struct ly_ctx *ctx = (struct ly_ctx *)LYD_CTX(node);
73+
struct lysc_ctx cctx;
74+
const struct lys_module *mod;
75+
LY_ARRAY_COUNT_TYPE u;
76+
struct ly_err_item *err = NULL;
77+
struct lysp_type *type_p = NULL;
78+
struct lysc_pattern **patterns = NULL;
79+
const char *value;
80+
81+
LYSC_CTX_INIT_CTX(cctx, ctx);
82+
83+
/* get date-and-time parsed type */
84+
mod = ly_ctx_get_module_latest(ctx, "ietf-yang-types");
85+
assert(mod);
86+
LY_ARRAY_FOR(mod->parsed->typedefs, u) {
87+
if (!strcmp(mod->parsed->typedefs[u].name, "date-and-time")) {
88+
type_p = &mod->parsed->typedefs[u].type;
89+
break;
90+
}
91+
}
92+
assert(type_p);
93+
94+
/* compile patterns */
95+
assert(type_p->patterns);
96+
LY_CHECK_GOTO(rc = lys_compile_type_patterns(&cctx, type_p->patterns, NULL, &patterns), cleanup);
97+
98+
/* validate */
99+
value = lyd_get_value(node);
100+
rc = lyplg_type_validate_patterns(patterns, value, strlen(value), &err);
101+
102+
cleanup:
103+
FREE_ARRAY(&cctx.free_ctx, patterns, lysc_pattern_free);
104+
if (rc && err) {
105+
LOGVAL_ERRITEM(ctx, err);
106+
ly_err_free(err);
107+
LOGVAL(ctx, LYVE_DATA, "Invalid \"eventTime\" in the notification.");
108+
}
109+
return rc;
110+
}
111+
67112
LY_ERR
68113
lyd_parser_find_operation(const struct lyd_node *parent, uint32_t int_opts, struct lyd_node **op)
69114
{

src/parser_data.h

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,29 @@ LIBYANG_API_DECL LY_ERR lyd_parse_ext_data(const struct lysc_ext_instance *ext,
310310
* @{
311311
*/
312312
enum lyd_type {
313-
LYD_TYPE_DATA_YANG = 0, /* generic YANG instance data */
314-
LYD_TYPE_RPC_YANG, /* instance of a YANG RPC/action request with only "input" data children,
315-
including all parents in case of an action */
316-
LYD_TYPE_NOTIF_YANG, /* instance of a YANG notification, including all parents in case of a nested one */
317-
LYD_TYPE_REPLY_YANG, /* instance of a YANG RPC/action reply with only "output" data children,
318-
including all parents in case of an action */
313+
LYD_TYPE_DATA_YANG = 0, /* generic YANG instance data */
314+
LYD_TYPE_RPC_YANG, /* instance of a YANG RPC/action request with only "input" data children,
315+
including all parents in case of an action */
316+
LYD_TYPE_NOTIF_YANG, /* instance of a YANG notification, including all parents in case of a nested one */
317+
LYD_TYPE_REPLY_YANG, /* instance of a YANG RPC/action reply with only "output" data children,
318+
including all parents in case of an action */
319319

320-
LYD_TYPE_RPC_NETCONF, /* complete NETCONF RPC invocation as defined for
321-
[RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
322-
[action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
323-
LYD_TYPE_NOTIF_NETCONF, /* complete NETCONF notification message as defined for
324-
[notification](https://tools.ietf.org/html/rfc7950#section-7.16.2) */
325-
LYD_TYPE_REPLY_NETCONF /* complete NETCONF RPC reply as defined for
326-
[RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
327-
[action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
320+
LYD_TYPE_RPC_NETCONF, /* complete NETCONF RPC invocation as defined for
321+
[RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
322+
[action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
323+
LYD_TYPE_NOTIF_NETCONF, /* complete NETCONF notification message as defined for
324+
[notification](https://tools.ietf.org/html/rfc7950#section-7.16.2) */
325+
LYD_TYPE_REPLY_NETCONF, /* complete NETCONF RPC reply as defined for
326+
[RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
327+
[action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
328+
329+
LYD_TYPE_RPC_RESTCONF, /* message-body of a RESTCONF operation input parameters
330+
([ref](https://www.rfc-editor.org/rfc/rfc8040.html#section-3.6.1)) */
331+
LYD_TYPE_NOTIF_RESTCONF, /* RESTCONF JSON notification data
332+
([ref](https://www.rfc-editor.org/rfc/rfc8040.html#section-6.4)), to parse
333+
a notification in XML, use ::LYD_TYPE_NOTIF_NETCONF */
334+
LYD_TYPE_REPLY_RESTCONF /* message-body of a RESTCONF operation output parameters
335+
([ref](https://www.rfc-editor.org/rfc/rfc8040.html#section-3.6.2)) */
328336
};
329337
/** @} datatype */
330338

@@ -357,6 +365,28 @@ enum lyd_type {
357365
* - @p op - must be NULL, the reply is appended to the RPC;
358366
* Note that there are 3 kinds of NETCONF replies - ok, error, and data. Only data reply appends any nodes to the RPC.
359367
*
368+
* - ::LYD_TYPE_RPC_RESTCONF:
369+
* - @p parent - must be set, pointing to the invoked RPC operation (RPC or action) node;
370+
* - @p format - can be both ::LYD_JSON and ::LYD_XML;
371+
* - @p tree - must be provided, all the RESTCONF-specific JSON objects will be returned here as
372+
* a separate opaque data tree, even if the function fails, this may be returned;
373+
* - @p op - must be NULL, @p parent points to the operation;
374+
*
375+
* - ::LYD_TYPE_NOTIF_RESTCONF:
376+
* - @p parent - must be NULL, the whole notification is expected;
377+
* - @p format - must be ::LYD_JSON, XML-formatted notifications are parsed using ::LYD_TYPE_NOTIF_NETCONF;
378+
* - @p tree - must be provided, all the RESTCONF-specific JSON objects will be returned here as
379+
* a separate opaque data tree, even if the function fails, this may be returned;
380+
* - @p op - must be provided, the notification data tree itself will be returned here, pointing to the operation;
381+
*
382+
* - ::LYD_TYPE_REPLY_RESTCONF:
383+
* - @p parent - must be set, pointing to the invoked RPC operation (RPC or action) node;
384+
* - @p format - can be both ::LYD_JSON and ::LYD_XML;
385+
* - @p tree - must be provided, all the RESTCONF-specific JSON objects will be returned here as
386+
* a separate opaque data tree, even if the function fails, this may be returned;
387+
* - @p op - must be NULL, @p parent points to the operation;
388+
* Note that error reply should be parsed as 'yang-data' extension data.
389+
*
360390
* @param[in] ctx libyang context.
361391
* @param[in] parent Optional parent to connect the parsed nodes to.
362392
* @param[in] in Input handle to read the input from.

src/parser_internal.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,27 @@ LY_ERR lyd_parse_json(const struct ly_ctx *ctx, const struct lysc_ext_instance *
297297
struct lyd_node **first_p, struct ly_in *in, uint32_t parse_opts, uint32_t val_opts, uint32_t int_opts,
298298
struct ly_set *parsed, ly_bool *subtree_sibling, struct lyd_ctx **lydctx_p);
299299

300+
/**
301+
* @brief Parse JSON string as a RESTCONF message.
302+
*
303+
* @param[in] ctx libyang context.
304+
* @param[in] ext Optional extension instance to parse data following the schema tree specified in the extension instance
305+
* @param[in] parent Parent to connect the parsed nodes to, if any.
306+
* @param[in,out] first_p Pointer to the first top-level parsed node, used only if @p parent is NULL.
307+
* @param[in] in Input structure.
308+
* @param[in] parse_opts Options for parser, see @ref dataparseroptions.
309+
* @param[in] val_opts Options for the validation phase, see @ref datavalidationoptions.
310+
* @param[in] data_type Expected RESTCONF data type of the data.
311+
* @param[out] envp Individual parsed envelopes tree, may be returned possibly even on an error.
312+
* @param[out] parsed Set to add all the parsed siblings into.
313+
* @param[out] subtree_sibling Set if ::LYD_PARSE_SUBTREE is used and another subtree is following in @p in.
314+
* @param[out] lydctx_p Data parser context to finish validation.
315+
* @return LY_ERR value.
316+
*/
317+
LY_ERR lyd_parse_json_restconf(const struct ly_ctx *ctx, const struct lysc_ext_instance *ext, struct lyd_node *parent,
318+
struct lyd_node **first_p, struct ly_in *in, uint32_t parse_opts, uint32_t val_opts, enum lyd_type data_type,
319+
struct lyd_node **envp, struct ly_set *parsed, struct lyd_ctx **lydctx_p);
320+
300321
/**
301322
* @brief Parse binary LYB data as a YANG data tree.
302323
*
@@ -317,6 +338,15 @@ LY_ERR lyd_parse_lyb(const struct ly_ctx *ctx, const struct lysc_ext_instance *e
317338
struct lyd_node **first_p, struct ly_in *in, uint32_t parse_opts, uint32_t val_opts, uint32_t int_opts,
318339
struct ly_set *parsed, ly_bool *subtree_sibling, struct lyd_ctx **lydctx_p);
319340

341+
/**
342+
* @brief Validate eventTime date-and-time value.
343+
*
344+
* @param[in] node Opaque eventTime node.
345+
* @return LY_SUCCESS on success.
346+
* @return LY_ERR value on error.
347+
*/
348+
LY_ERR lyd_parser_notif_eventtime_validate(const struct lyd_node *node);
349+
320350
/**
321351
* @brief Search all the parents for an operation node, check validity based on internal parser flags.
322352
*

0 commit comments

Comments
 (0)