diff --git a/src/main.c b/src/main.c index c5db4a5..31c0167 100644 --- a/src/main.c +++ b/src/main.c @@ -860,8 +860,12 @@ server_data_subscribe(void) SR_CONFIG_SUBSCR(mod_name, "/ietf-subscribed-notifications:subscriptions/receiver-instances/receiver-instance", np2srv_config_receivers_cb); - SR_CONFIG_SUBSCR(mod_name, "/ietf-subscribed-notifications:subscriptions/subscription", - np2srv_config_subscriptions_cb); + rc = sr_module_change_subscribe(np2srv.sr_sess, mod_name, "/ietf-subscribed-notifications:subscriptions/subscription", + np2srv_config_subscriptions_cb, NULL, 0, SR_SUBSCR_ENABLED, &np2srv.sr_data_sub); + if (rc != SR_ERR_OK) { + ERR("Subscribing for \"%s\" data changes failed (%s).", mod_name, sr_strerror(rc)); + goto error; + } SR_CONFIG_SUBSCR(mod_name, "/ietf-subscribed-notifications:subscriptions/subscription/receivers/receiver", np2srv_config_subscriptions_receivers_cb); diff --git a/src/netconf_subscribed_notifications.c b/src/netconf_subscribed_notifications.c index 90f5d2d..9546306 100644 --- a/src/netconf_subscribed_notifications.c +++ b/src/netconf_subscribed_notifications.c @@ -458,8 +458,8 @@ np2srv_sub_ntf_destroy(void) } static int -np2srv_establish_sub_cb(sr_session_ctx_t *session, const struct lyd_node *input, - struct lyd_node *output, struct nc_session *ncs) +np2srv_establish_sub(sr_session_ctx_t *session, const struct lyd_node *input, struct lyd_node *output, + struct nc_session *ncs) { struct lyd_node *node; struct np2srv_sub_ntf sub = {0}, *sub_p; @@ -628,8 +628,44 @@ csn_receiver_get_by_name(struct csn_receiver_info *recv_info, const char *name) return NULL; } -int -csn_config_sub_receivers_prepare(const struct lyd_node *node_receiver, +/** + * @brief Destroy content of receiver in a subscription + * + * @param[in] receiver in the subscription in the receiver_info. + */ +static void +csn_receiver_destroy(struct csn_receiver *receiver, int keep_ref) +{ + if (!receiver) { + return; + } + + if (!keep_ref) { + free(receiver->name); + receiver->name = NULL; + + free(receiver->instance_ref); + receiver->instance_ref = NULL; + } + + free_sender_socket(receiver->udp.sender); + receiver->udp.sender = NULL; + + free(receiver->udp.options.address); + receiver->udp.options.address = NULL; + + free(receiver->udp.options.port); + receiver->udp.options.port = NULL; + + free(receiver->udp.options.interface); + receiver->udp.options.interface = NULL; + + free(receiver->udp.options.local_address); + receiver->udp.options.local_address = NULL; +} + +static int +csn_add_sub_receivers_prepare(const struct lyd_node *node_receiver, struct csn_receiver_info *recv_info, uint32_t nc_sub_id) { struct csn_receiver_config *recv_config = NULL; @@ -698,7 +734,7 @@ cleanup: return rc; } -int +static int csn_modify_sub_receiver(const struct lyd_node *node_receiver) { const struct lyd_node *input = lyd_parent(lyd_parent(node_receiver)); @@ -787,8 +823,8 @@ cleanup: return rc; } -int -csn_config_sub_receiver(const struct lyd_node *node_receiver) +static int +csn_add_sub_receiver(const struct lyd_node *node_receiver) { const struct lyd_node *input = lyd_parent(lyd_parent(node_receiver)); struct csn_receiver_info *recv_info = NULL; @@ -823,44 +859,13 @@ csn_config_sub_receiver(const struct lyd_node *node_receiver) goto error; } - rc = csn_config_sub_receivers_prepare(node_receiver, recv_info, nc_sub_id); + rc = csn_add_sub_receivers_prepare(node_receiver, recv_info, nc_sub_id); error: return rc; } -void -csn_receiver_destroy(struct csn_receiver *receiver, int keep_ref) -{ - if (!receiver) { - return; - } - - if (!keep_ref) { - free(receiver->name); - receiver->name = NULL; - - free(receiver->instance_ref); - receiver->instance_ref = NULL; - } - - free_sender_socket(receiver->udp.sender); - receiver->udp.sender = NULL; - - free(receiver->udp.options.address); - receiver->udp.options.address = NULL; - - free(receiver->udp.options.port); - receiver->udp.options.port = NULL; - - free(receiver->udp.options.interface); - receiver->udp.options.interface = NULL; - - free(receiver->udp.options.local_address); - receiver->udp.options.local_address = NULL; -} - -int +static int csn_receiver_remove_by_name(struct csn_receiver_info *recv_info, const char *name, uint32_t nc_sub_id) { uint32_t r; @@ -890,7 +895,7 @@ csn_receiver_remove_by_name(struct csn_receiver_info *recv_info, const char *nam return SR_ERR_INTERNAL; } -int +static int csn_delete_sub_receiver(const struct lyd_node *node_receiver) { const struct lyd_node *input = lyd_parent(lyd_parent(node_receiver)); @@ -957,14 +962,10 @@ np2srv_rpc_establish_sub_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), /* find this NETCONF session */ if ((rc = np_find_user_sess(session, __func__, &ncs, NULL))) { - goto error; + return rc; } - return np2srv_establish_sub_cb(session, input, output, ncs); - -error: - - return rc; + return np2srv_establish_sub(session, input, output, ncs); } static struct lyd_node * @@ -984,10 +985,10 @@ get_sr_config_sub_ntf(sr_session_ctx_t *session, uint32_t nc_sub_id) return NULL; } -int -csn_config_sub(sr_session_ctx_t *session, const struct lyd_node *input) +static int +csn_add_sub(sr_session_ctx_t *session, const struct lyd_node *input) { - return np2srv_establish_sub_cb(session, input, NULL, NULL); + return np2srv_establish_sub(session, input, NULL, NULL); } static int @@ -1709,7 +1710,7 @@ cleanup_unlock: return rc; } -int +static int csn_delete_sub(sr_session_ctx_t *session, const struct lyd_node *input) { struct np2srv_sub_ntf *sub; @@ -1936,9 +1937,8 @@ cleanup: } int -np2srv_config_subscriptions_cb(sr_session_ctx_t *session, - uint32_t UNUSED(sub_id), const char *UNUSED(module_name), const char *UNUSED(path), - sr_event_t UNUSED(event), uint32_t UNUSED(request_id), void *UNUSED(private_data)) +np2srv_config_subscriptions_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), const char *UNUSED(module_name), + const char *UNUSED(path), sr_event_t event, uint32_t UNUSED(request_id), void *UNUSED(private_data)) { sr_change_iter_t *iter = NULL; const struct lyd_node *node; @@ -1946,6 +1946,10 @@ np2srv_config_subscriptions_cb(sr_session_ctx_t *session, int r, rc = SR_ERR_OK; sr_change_oper_t op; + if (event != SR_EV_CHANGE) { + return SR_ERR_OK; + } + /* subscribed-notifications */ rc = sr_get_changes_iter(session, "/ietf-subscribed-notifications:subscriptions/subscription", &iter); if (rc != SR_ERR_OK) { @@ -1954,9 +1958,8 @@ np2srv_config_subscriptions_cb(sr_session_ctx_t *session, } while ((r = sr_get_change_tree_next(session, iter, &op, &node, NULL, NULL, NULL)) == SR_ERR_OK) { - if (op == SR_OP_CREATED) { - rc = csn_config_sub(session, node); + rc = csn_add_sub(session, node); if (rc != SR_ERR_OK) { goto cleanup; } @@ -1967,7 +1970,6 @@ np2srv_config_subscriptions_cb(sr_session_ctx_t *session, } } } - if (r != SR_ERR_NOT_FOUND) { rc = r; ERR("Getting next change failed (%s).", sr_strerror(rc)); @@ -2006,22 +2008,21 @@ np2srv_config_subscriptions_cb(sr_session_ctx_t *session, /* restart subscription with actual config */ config = get_sr_config_sub_ntf(session, nc_sub_id); if (!config) { - VRB("Could not find sub config %lu", nc_sub_id); + ERR("Could not find sub config %" PRIu32, nc_sub_id); rc = SR_ERR_INTERNAL; goto cleanup; } /* delete and create the subscriptions */ - rc = csn_delete_sub(session, lyd_parent(node)); - if (rc != SR_ERR_OK) { - VRB("Could not delete subscription"); + if ((rc = csn_delete_sub(session, lyd_parent(node)))) { + goto cleanup; + } + if ((rc = csn_add_sub(session, config))) { goto cleanup; } - - csn_config_sub(session, config); if (!lyd_find_path(config, "receivers", 0, &node_receivers)) { LY_LIST_FOR(lyd_child(node_receivers), node_receiver) { - csn_config_sub_receiver(node_receiver); + csn_add_sub_receiver(node_receiver); } } @@ -2036,7 +2037,6 @@ np2srv_config_subscriptions_cb(sr_session_ctx_t *session, } cleanup: - sr_free_change_iter(iter); return rc; } @@ -2059,7 +2059,7 @@ np2srv_config_subscriptions_receivers_cb(sr_session_ctx_t *session, while ((r = sr_get_change_tree_next(session, iter, &op, &node, NULL, NULL, NULL)) == SR_ERR_OK) { if (op == SR_OP_CREATED) { - csn_config_sub_receiver(node); + csn_add_sub_receiver(node); } else if (op == SR_OP_DELETED) { csn_delete_sub_receiver(node); } diff --git a/src/netconf_subscribed_notifications.h b/src/netconf_subscribed_notifications.h index f947f88..5c905e9 100644 --- a/src/netconf_subscribed_notifications.h +++ b/src/netconf_subscribed_notifications.h @@ -232,13 +232,6 @@ int csn_send_notif(struct csn_receiver_info *recv_info, uint32_t nc_sub_id, */ void csn_receiver_info_destroy(struct csn_receiver_info *recv_info); -/** - * @brief Destroy content of receiver in a subscription - * - * @param[in] receiver in the subscription in the receiver_info. - */ -void csn_receiver_destroy(struct csn_receiver *receiver, int keep_ref); - /** * @brief start a receiver * diff --git a/src/yang_push.c b/src/yang_push.c index 9ad2ecb..fe8be94 100644 --- a/src/yang_push.c +++ b/src/yang_push.c @@ -879,14 +879,17 @@ yang_push_notif_update_send(struct nc_session *ncs, sr_session_ctx_t *sr_sess, s const struct ly_ctx *ly_ctx; sr_data_t *data = NULL; char buf[11]; - int rc = SR_ERR_OK; + int rc = SR_ERR_OK, r; /* switch to the datastore */ sr_session_switch_ds(sr_sess, yp_data->datastore); /* get the data from sysrepo */ - rc = sr_get_data(sr_sess, yp_data->xpath ? yp_data->xpath : "/*", 0, np2srv.sr_timeout, 0, &data); - if (rc != SR_ERR_OK) { + r = sr_get_data(sr_sess, yp_data->xpath ? yp_data->xpath : "/*", 0, np2srv.sr_timeout, 0, &data); + if (r == SR_ERR_NOT_FOUND) { + WRN("XPath \"%s\" does not match any schema or data nodes."); + } else if (r) { + rc = r; goto cleanup; } diff --git a/tests/test_configured_subscriptions.c b/tests/test_configured_subscriptions.c index 1ab2948..51d6ae2 100644 --- a/tests/test_configured_subscriptions.c +++ b/tests/test_configured_subscriptions.c @@ -801,7 +801,7 @@ test_configured_subscriptions_add(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); test_collector_stop_read_threads(); @@ -1125,7 +1125,7 @@ test_configured_subscriptions_modif(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); } @@ -1365,7 +1365,7 @@ test_configured_subscriptions_modif2(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); } @@ -1615,7 +1615,7 @@ test_configured_subscriptions_modif3(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); } @@ -1851,7 +1851,7 @@ test_configured_subscriptions_yang_push(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); } @@ -1906,17 +1906,17 @@ test_configured_subscriptions_yang_push_modif(void **state) assert_non_null(tc_12346.xml_data[2][0] != '\0'); np_assert_strstr(tc_12346.xml_data[2], ""); - pos_array[0] = np_strstr(tc_12346.xml_data[1], "1"); + pos_array[0] = strstr(tc_12346.xml_data[1], "1"); - pos_array[1] = np_strstr(tc_12346.xml_data[2], "1"); + pos_array[1] = strstr(tc_12346.xml_data[2], "1"); - pos_array[2] = np_strstr(tc_12346.xml_data[3], "1"); + pos_array[2] = strstr(tc_12346.xml_data[3], "1"); - pos_array[3] = np_strstr(tc_12346.xml_data[4], "1"); + pos_array[3] = strstr(tc_12346.xml_data[4], "1"); - pos_array[4] = np_strstr(tc_12345.xml_data[2], "1"); + pos_array[4] = strstr(tc_12345.xml_data[2], "1"); - pos_array[5] = np_strstr(tc_12345.xml_data[3], "1"); + pos_array[5] = strstr(tc_12345.xml_data[3], "1"); /* at least one push update event should be received */ assert_non_null(pos_array[0] || pos_array[1] || pos_array[2] || pos_array[3] || pos_array[4] || pos_array[5]); @@ -2112,7 +2112,7 @@ test_configured_subscriptions_yang_push_modif(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); } @@ -2350,7 +2350,7 @@ test_configured_subscriptions_back(void **state) " \n" "\n"; - np_is_string_equal(st->str, expected); + np_assert_string_equal(st->str, expected); FREE_TEST_VARS(st); }