From ab15bb5936d770ba35d39daeb8fbea65ae1ab59d Mon Sep 17 00:00:00 2001 From: Abhi Keshav Date: Fri, 6 Jan 2017 15:34:12 -0800 Subject: [PATCH] Remove unused code and fix validation service to use libyang validation * Fix netconf service issues --- sdk/cpp/core/CMakeLists.txt | 1 - .../docsgen/api/services/netconf_service.rst | 94 ++-- sdk/cpp/core/docsgen/api/services/service.rst | 1 + sdk/cpp/core/src/errors.cpp | 2 +- sdk/cpp/core/src/errors.hpp | 8 + sdk/cpp/core/src/netconf_service.cpp | 508 +++++------------- sdk/cpp/core/src/netconf_service.hpp | 35 +- sdk/cpp/core/src/path/path.cpp | 431 +-------------- sdk/cpp/core/src/path/path_private.hpp | 8 - sdk/cpp/core/src/path/root_schema_node.cpp | 7 - sdk/cpp/core/src/path/schema_node.cpp | 15 +- sdk/cpp/core/src/path/schema_value_type.cpp | 407 -------------- sdk/cpp/core/src/path_api.hpp | 388 +------------ sdk/cpp/core/src/validation_service.cpp | 133 +---- sdk/cpp/core/src/validation_service.hpp | 34 +- sdk/cpp/core/tests/core/bgptest.cpp | 2 +- sdk/cpp/tests/testsanityvalidationtest.cpp | 94 ++-- 17 files changed, 304 insertions(+), 1864 deletions(-) delete mode 100644 sdk/cpp/core/src/path/schema_value_type.cpp diff --git a/sdk/cpp/core/CMakeLists.txt b/sdk/cpp/core/CMakeLists.txt index af828334e..42ebb3b40 100644 --- a/sdk/cpp/core/CMakeLists.txt +++ b/sdk/cpp/core/CMakeLists.txt @@ -72,7 +72,6 @@ set(libydk_src src/path/root_schema_node.cpp src/path/rpc.cpp src/path/schema_node.cpp - src/path/schema_value_type.cpp src/path/statement.cpp) set(libydk_install_headers diff --git a/sdk/cpp/core/docsgen/api/services/netconf_service.rst b/sdk/cpp/core/docsgen/api/services/netconf_service.rst index f4db20eea..766595869 100644 --- a/sdk/cpp/core/docsgen/api/services/netconf_service.rst +++ b/sdk/cpp/core/docsgen/api/services/netconf_service.rst @@ -1,15 +1,19 @@ NetconfService ============== +.. toctree:: + :maxdepth: 2 + .. cpp:namespace:: ydk .. cpp:enum-class:: Datastore - :param candidate: Enum representing candidate datastore - :param running: Enum representing running datastore - :param startup: Enum representing startup datastore - :param url: Enum representing url datastore - :param config: Enum representing config datastore +Type of datastore to perform operation on + + .. cpp:enumerator:: candidate + .. cpp:enumerator:: running + .. cpp:enumerator:: startup + .. cpp:enumerator:: url .. cpp:class:: NetconfService : public Service @@ -25,16 +29,16 @@ Netconf Service class for supporting encoding and decoding C++ model API objects :param provider: An instance of :cpp:class:`NetconfServiceProvider` :param persist_id: Cancels a persistent confirmed commit. - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool close_session(NetconfServiceProvider & provider) Request graceful termination of a NETCONF session :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool commit(NetconfServiceProvider & provider, std::string confirmed = "", std::string confirm_timeout = "", std::string persist = "", std::string persist_id = "") @@ -45,68 +49,68 @@ Netconf Service class for supporting encoding and decoding C++ model API objects :param confirm_timeout: An optional argument :param persist: An optional argument :param persist_id: An optional argument - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool copy_config(NetconfServiceProvider & provider, DataStore target, DataStore source) Create or replace an entire configuration datastore with the contents of another complete configuration datastore. If the target datastore exists, it is overwritten. Otherwise, a new one is created, if allowed. :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param target: The configuration being used as the destination of type :cpp:enum-class:`Datastore` - :param source: The configuration being used as the source of type :cpp:enum-class:`Datastore` - :return: The result of the operation as bool - :raises: + :param target: The configuration being used as the destination of type :cpp:class:`Datastore` + :param source: The configuration being used as the source of type :cpp:class:`Datastore` + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool copy_config(NetconfServiceProvider & provider, DataStore target, Entity& source) Create or replace an entire configuration datastore with the contents of another complete configuration datastore. If the target datastore exists, it is overwritten. Otherwise, a new one is created, if allowed. :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param target: The configuration being used as the destination of type :cpp:enum-class:`Datastore` + :param target: The configuration being used as the destination of type :cpp:class:`Datastore` :param source: The configuration being used as the source of type :cpp:class:`Entity` - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool delete_config(NetconfServiceProvider & provider, DataStore target, std::string url = "") Delete a configuration datastore. The RUNNING configuration datastore cannot be deleted. :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param target: The configuration of type :cpp:enum-class:`Datastore` to be deleted - :param url: Required only when target is set to :cpp:enum-class:`Datastore`.:cpp:enum:`url` - :return: The result of the operation as bool - :raises: + :param target: The configuration of type :cpp:class:`Datastore` to be deleted + :param url: Required only when target is set to :cpp:enumerator:`url` + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool discard_changes(NetconfServiceProvider & provider) Used to revert the candidate configuration to the current running configuration :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool edit_config(NetconfServiceProvider & provider, DataStore target, Entity& config, std::string default_operation = "", std::string test_option = "", std::string error_option = "") Loads all or part of a specified configuration to the specified target configuration datastore. Allows the new configuration to be expressed using a local file, a remote file, or inline. If the target configuration datastore does not exist, it will be created. :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param target: The configuration being edited of type :cpp:enum-class:`Datastore` + :param target: The configuration being edited of type :cpp:class:`Datastore` :param config: An instance of :cpp:class:`Entity` that is a hierarchy configuration of data as defined by one of the device's data models :param default_operation: Selects the default operation (merge, replace, or none). The default value for this parameter is "merge". :param test_option: Optionally set to "test-then-set", "set", or "test-only" if the device advertises the :validate:1.1 capability :param error_option: Optionally set to "stop-on-error", "continue-on-error", or "rollback-on-error" - :return: The result of the operation as bool. - :raises: + :return: true if the operation succeeds, else false. + :raises YCPPError: If an error has occurred - .. cpp:function:: std::unique_ptr get_config(NetconfServiceProvider & provider, DataStore source, Entity& filter); + .. cpp:function:: std::unique_ptr get_config(NetconfServiceProvider & provider, DataStore source, Entity& filter) Retrieve all or part of a specified configuration datastore :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param source: The configuration being queried of type :cpp:enum-class:`Datastore` + :param source: The configuration being queried of type :cpp:class:`Datastore` :return: The requested data as :cpp:class:`Entity` - :raises: + :raises YCPPError: If an error has occurred .. cpp:function:: std::unique_ptr get(NetconfServiceProvider & provider, Entity& filter) @@ -115,7 +119,7 @@ Netconf Service class for supporting encoding and decoding C++ model API objects :param provider: An instance of :cpp:class:`NetconfServiceProvider` :param filter: An instance of :cpp:class:`Entity` that specifies the portion of the system configuration and state data to retrieve :return: The requested data as :cpp:class:`Entity` - :raises: + :raises YCPPError: If an error has occurred .. cpp:function:: bool kill_session(NetconfServiceProvider & provider, int session_id) @@ -123,41 +127,41 @@ Netconf Service class for supporting encoding and decoding C++ model API objects :param provider: An instance of :cpp:class:`NetconfServiceProvider` :param session_id: An instance of int that is the session identifier of the NETCONF session to be terminated - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool lock(NetconfServiceProvider & provider, DataStore target) Allows the client to lock the entire configuration datastore system of a device :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param target: The configuration of type :cpp:enum-class:`Datastore` to lock - :return: The result of the operation as bool - :raises: + :param target: The configuration of type :cpp:class:`Datastore` to lock + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool unlock(NetconfServiceProvider & provider, DataStore target) Used to release a configuration lock, previously obtained with the LOCK operation :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param target: The configuration of type DATASTORE to unlock - :return: The result of the operation as bool - :raises: + :param target: The configuration of type :cpp:class:`Datastore` to unlock + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred .. cpp:function:: bool validate(NetconfServiceProvider & provider, DataStore source) Checks a complete configuration for syntactical and semantic errors before applying the configuration to the device :param provider: An instance of :cpp:class:`NetconfServiceProvider` - :param source: An instance of :cpp:enum-class:`Datastore` - :return: The result of the operation as bool - :raises: + :param source: An instance of :cpp:class:`Datastore` + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred - .. cpp:function:: bool validate(NetconfServiceProvider & provider, Entity& source) + .. cpp:function:: bool validate(NetconfServiceProvider & provider, Entity& source_config) Checks a complete configuration for syntactical and semantic errors before applying the configuration to the device :param provider: An instance of :cpp:class:`NetconfServiceProvider` :param source: An instance of :cpp:class:`Entity` - :return: The result of the operation as bool - :raises: + :return: true if the operation succeeds, else false + :raises YCPPError: If an error has occurred diff --git a/sdk/cpp/core/docsgen/api/services/service.rst b/sdk/cpp/core/docsgen/api/services/service.rst index 3931fb01c..ab883c9e6 100644 --- a/sdk/cpp/core/docsgen/api/services/service.rst +++ b/sdk/cpp/core/docsgen/api/services/service.rst @@ -13,6 +13,7 @@ Base class for YDK service :maxdepth: 2 crud_service.rst + netconf_service.rst codec_service.rst validation_service.rst core_codec_service.rst diff --git a/sdk/cpp/core/src/errors.cpp b/sdk/cpp/core/src/errors.cpp index 5623b9e3b..30b6c28d7 100644 --- a/sdk/cpp/core/src/errors.cpp +++ b/sdk/cpp/core/src/errors.cpp @@ -72,7 +72,7 @@ ydk::YCPPOperationNotSupportedError::YCPPOperationNotSupportedError(const std::s ////////////////////////////////////////////////////////////////////////// /// YCPPDataValidationError ////////////////////////////////////////////////////////////////////////// -ydk::path::YCPPDataValidationError::YCPPDataValidationError() : ydk::path::YCPPCoreError{"Data Validation Error"} +ydk::path::YCPPDataValidationError::YCPPDataValidationError() : ydk::path::YCPPCoreError{ly_errmsg()} { } diff --git a/sdk/cpp/core/src/errors.hpp b/sdk/cpp/core/src/errors.hpp index 943229977..cef81421d 100644 --- a/sdk/cpp/core/src/errors.hpp +++ b/sdk/cpp/core/src/errors.hpp @@ -56,6 +56,14 @@ struct YCPPServiceProviderError : public YCPPError } }; +struct YCPPServiceError : public YCPPError +{ + YCPPServiceError(const std::string& msg) : YCPPError{msg} + { + + } +}; + /// /// @brief Illegal State Error. /// diff --git a/sdk/cpp/core/src/netconf_service.cpp b/sdk/cpp/core/src/netconf_service.cpp index 1e0272166..ba384a625 100644 --- a/sdk/cpp/core/src/netconf_service.cpp +++ b/sdk/cpp/core/src/netconf_service.cpp @@ -33,37 +33,34 @@ using namespace std; namespace ydk { -std::string get_data_payload(Entity& entity, path::RootSchemaNode& root_schema); +static std::string get_data_payload(Entity& entity, path::RootSchemaNode& root_schema); static unique_ptr get_top_entity_from_filter(Entity & filter); +static unique_ptr get_rpc_instance(NetconfServiceProvider & provider, string && operation); +static void create_input_leaf(path::DataNode & input_datanode, DataStore datastore, string && datastore_string, string & url); +static void create_input_leaf(path::DataNode & input_datanode, DataStore datastore, string && datastore_string); NetconfService::NetconfService() { - BOOST_LOG_TRIVIAL(debug) << "ydk.services.NetconfService"; +} + +NetconfService::~NetconfService() +{ } //cancel_commit -bool NetconfService::cancel_commit(NetconfServiceProvider & provider, std::string persist_id) +bool NetconfService::cancel_commit(NetconfServiceProvider & provider, int persist_id) { BOOST_LOG_TRIVIAL(debug) << "Executing cancel-commit RPC"; - // Get the operation - auto operation = "ietf-netconf:cancel-commit"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:cancel-commit"); - bool is_pass = true; - if (persist_id.size() > 0) + if (persist_id > -1) { - auto result = ydk_rpc->input()->create("persist-id", persist_id); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("persist-id", std::to_string(persist_id)); } - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -72,133 +69,59 @@ bool NetconfService::close_session(NetconfServiceProvider & provider) { BOOST_LOG_TRIVIAL(debug) << "Executing close-session RPC"; - // Get the operation - auto operation = "ietf-netconf:close-session"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:close-session"); - if (ydk_rpc == nullptr) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } //commit -bool NetconfService::commit(NetconfServiceProvider & provider, std::string confirmed, - std::string confirm_timeout, std::string persist, std::string persist_id) +bool NetconfService::commit(NetconfServiceProvider & provider, bool confirmed, + int confirm_timeout, int persist, int persist_id) { BOOST_LOG_TRIVIAL(debug) << "Executing commit RPC"; - // Get the operation - auto operation = "ietf-netconf:commit"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:commit"); - bool is_pass = true; - - if (confirmed.size() > 0) + if (confirmed) { - auto result = ydk_rpc->input()->create("confirmed", confirmed); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("confirmed"); } - if (confirm_timeout.size() > 0) + if (confirm_timeout > -1) { - auto result = ydk_rpc->input()->create("confirm-timeout", confirm_timeout); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("confirm-timeout", std::to_string(confirm_timeout)); } - if (persist.size() > 0) + if (persist > -1) { - auto result = ydk_rpc->input()->create("persist", persist); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("persist", std::to_string(persist)); } - if (persist_id.size() > 0) + if (persist_id > -1) { - auto result = ydk_rpc->input()->create("persist-id", persist_id); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("persist", std::to_string(persist_id)); } - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } //copy_config -bool NetconfService::copy_config(NetconfServiceProvider & provider, DataStore target, DataStore source) +bool NetconfService::copy_config(NetconfServiceProvider & provider, DataStore target, DataStore source, string url) { BOOST_LOG_TRIVIAL(debug) << "Executing copy-config RPC"; - // Get the operation - auto operation = "ietf-netconf:copy-config"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:copy-config"); // target options: candidate | running | startup | url - if (target == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("target/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::running) - { - auto result = ydk_rpc->input()->create("target/running"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::startup) - { - auto result = ydk_rpc->input()->create("target/startup"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::url) - { - auto result = ydk_rpc->input()->create("target/url"); - is_pass = is_pass and (result != nullptr); - } - - // source options: candidate | running | startup | url | config - if (source == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("source/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::running) - { - auto result = ydk_rpc->input()->create("source/running"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::startup) - { - auto result = ydk_rpc->input()->create("source/startup"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::url) - { - auto result = ydk_rpc->input()->create("source/url"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::config) - { - auto result = ydk_rpc->input()->create("source/config"); - is_pass = is_pass and (result != nullptr); - } - - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); + create_input_leaf(*(rpc->input()), target, "target", url); + create_input_leaf(*(rpc->input()), source, "source", url); - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -206,79 +129,32 @@ bool NetconfService::copy_config(NetconfServiceProvider & provider, DataStore ta { BOOST_LOG_TRIVIAL(debug) << "Executing copy-config RPC"; - // Get the operation - auto operation = "ietf-netconf:copy-config"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:copy-config"); // target options: candidate | running | startup | url - if (target == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("target/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::running) - { - auto result = ydk_rpc->input()->create("target/running"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::startup) - { - auto result = ydk_rpc->input()->create("target/startup"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::url) - { - auto result = ydk_rpc->input()->create("target/url"); - is_pass = is_pass and (result != nullptr); - } + create_input_leaf(*(rpc->input()), target, "target"); // source - std::string entity_string = get_data_payload(source, *root_schema); - auto result = ydk_rpc->input()->create("source/config", entity_string); - is_pass = is_pass and (result != nullptr); + std::string entity_string = get_data_payload(source, *(provider.get_root_schema())); + rpc->input()->create("source/config", entity_string); - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } -//delete_config -- url ?? +//delete_config bool NetconfService::delete_config(NetconfServiceProvider & provider, DataStore target, std::string url) { BOOST_LOG_TRIVIAL(debug) << "Executing delete-config RPC"; - // Get the operation - auto operation = "ietf-netconf:delete-config"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:delete-config"); // target options: startup | url - if (target == DataStore::startup) - { - auto result = ydk_rpc->input()->create("target/startup"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::url) - { - auto result = ydk_rpc->input()->create("target/url", url); - is_pass = is_pass and (result != nullptr); - } - - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); + create_input_leaf(*(rpc->input()), target, "target", url); - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -287,17 +163,10 @@ bool NetconfService::discard_changes(NetconfServiceProvider & provider) { BOOST_LOG_TRIVIAL(debug) << "Executing discard-changes RPC"; - // Get the operation - auto operation = "ietf-netconf:discard-changes"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:discard-changes"); - if (ydk_rpc == nullptr) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -307,128 +176,73 @@ bool NetconfService::edit_config(NetconfServiceProvider & provider, DataStore ta { BOOST_LOG_TRIVIAL(debug) << "Executing edit-config RPC"; - // Get the operation - auto operation = "ietf-netconf:edit-config"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:edit-config"); // target options: candidate | running - if (target == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("target/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::running) - { - auto result = ydk_rpc->input()->create("target/running"); - is_pass = is_pass and (result != nullptr); - } + create_input_leaf(*(rpc->input()), target, "target"); //config - std::string entity_string = get_data_payload(config, *root_schema); - auto result = ydk_rpc->input()->create("config", entity_string); - is_pass = is_pass and (result != nullptr); + std::string entity_string = get_data_payload(config, *(provider.get_root_schema())); + rpc->input()->create("config", entity_string); if (default_operation.size() > 0) { - auto result = ydk_rpc->input()->create("default-operation"); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("default-operation", default_operation); } if (test_option.size() > 0) { - auto result = ydk_rpc->input()->create("test-option"); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("test-option", test_option); } if (error_option.size() > 0) { - auto result = ydk_rpc->input()->create("error-option"); - is_pass = is_pass and (result != nullptr); + rpc->input()->create("error-option", error_option); } - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } -//get_config -- needs to return data +//get_config unique_ptr NetconfService::get_config(NetconfServiceProvider & provider, DataStore source, Entity& filter) { BOOST_LOG_TRIVIAL(debug) << "Executing get-config RPC"; - // Get the operation - auto operation = "ietf-netconf:get-config"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:get-config"); // source options: candidate | running | startup - if (source == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("source/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::running) - { - auto result = ydk_rpc->input()->create("source/running"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::startup) - { - auto result = ydk_rpc->input()->create("source/startup"); - is_pass = is_pass and (result != nullptr); - } + create_input_leaf(*(rpc->input()), source, "source"); // filter - std::string entity_string = get_data_payload(filter, *root_schema); - auto result = ydk_rpc->input()->create("filter", entity_string); - is_pass = is_pass and (result != nullptr); + std::string entity_string = get_data_payload(filter, *(provider.get_root_schema())); + rpc->input()->create("filter", entity_string); - if(!is_pass || (ydk_rpc == nullptr)) - { - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - } - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); if (read_datanode == nullptr) - return {}; + return nullptr; + unique_ptr top_entity = get_top_entity_from_filter(filter); get_entity_from_data_node(read_datanode->children()[0], top_entity.get()); return top_entity; } -//get -- needs to return data +//get unique_ptr NetconfService::get(NetconfServiceProvider & provider, Entity& filter) { BOOST_LOG_TRIVIAL(debug) << "Executing get RPC"; - // Get the operation - auto operation = "ietf-netconf:get"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = ydk_rpc != nullptr; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:get"); // filter - std::string entity_string = get_data_payload(filter, *root_schema); - auto result = ydk_rpc->input()->create("filter", entity_string); - is_pass = is_pass and (result != nullptr); - if(!is_pass || (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); + std::string entity_string = get_data_payload(filter, *(provider.get_root_schema())); + rpc->input()->create("filter", entity_string); - auto result_datanode = (*ydk_rpc)(provider); + auto result_datanode = (*rpc)(provider); if (result_datanode == nullptr) return {}; unique_ptr top_entity = get_top_entity_from_filter(filter); @@ -441,20 +255,13 @@ bool NetconfService::kill_session(NetconfServiceProvider & provider, int session { BOOST_LOG_TRIVIAL(debug) << "Executing kill-session RPC"; - // Get the operation - auto operation = "ietf-netconf:kill-session"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:kill-session"); std::string sid_string = std::to_string(session_id); - auto result = ydk_rpc->input()->create("session-id", sid_string); - - if (result == nullptr or ydk_rpc == nullptr) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); + rpc->input()->create("session-id", sid_string); - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -463,36 +270,13 @@ bool NetconfService::lock(NetconfServiceProvider & provider, DataStore target) { BOOST_LOG_TRIVIAL(debug) << "Executing lock RPC"; - // Get the operation - auto operation = "ietf-netconf:lock"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:lock"); // target options: candidate | running | startup - if (target == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("target/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::running) - { - auto result = ydk_rpc->input()->create("target/running"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::startup) - { - auto result = ydk_rpc->input()->create("target/startup"); - is_pass = is_pass and (result != nullptr); - } + create_input_leaf(*(rpc->input()), target, "target"); - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -501,84 +285,28 @@ bool NetconfService::unlock(NetconfServiceProvider & provider, DataStore target) { BOOST_LOG_TRIVIAL(debug) << "Executing unlock RPC"; - // Get the operation - auto operation = "ietf-netconf:unlock"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:unlock"); // target options: candidate | running | startup - if (target == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("target/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::running) - { - auto result = ydk_rpc->input()->create("target/running"); - is_pass = is_pass and (result != nullptr); - } - else if (target == DataStore::startup) - { - auto result = ydk_rpc->input()->create("target/startup"); - is_pass = is_pass and (result != nullptr); - } - - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); + create_input_leaf(*(rpc->input()), target, "target"); - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } -//validate -- url?? -bool NetconfService::validate(NetconfServiceProvider & provider, DataStore source) +//validate +bool NetconfService::validate(NetconfServiceProvider & provider, DataStore source, string url) { BOOST_LOG_TRIVIAL(debug) << "Executing validate RPC"; - // Get the operation - auto operation = "ietf-netconf:validate"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:validate"); // source options: candidate | running | startup | url - if (source == DataStore::candidate) - { - auto result = ydk_rpc->input()->create("source/candidate"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::running) - { - auto result = ydk_rpc->input()->create("source/running"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::startup) - { - auto result = ydk_rpc->input()->create("source/startup"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::url) - { - auto result = ydk_rpc->input()->create("source/url"); - is_pass = is_pass and (result != nullptr); - } - else if (source == DataStore::config) - { - auto result = ydk_rpc->input()->create("source/config"); - is_pass = is_pass and (result != nullptr); - } - - if (!is_pass or (ydk_rpc == nullptr)) - BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); + create_input_leaf(*(rpc->input()), source, "source", url); - auto read_datanode = (*ydk_rpc)(provider); + auto read_datanode = (*rpc)(provider); return read_datanode == nullptr; } @@ -586,34 +314,34 @@ bool NetconfService::validate(NetconfServiceProvider & provider, Entity& source) { BOOST_LOG_TRIVIAL(debug) << "Executing validate RPC"; - // Get the operation - auto operation = "ietf-netconf:validate"; - // Get the root schema node - path::RootSchemaNode* root_schema = provider.get_root_schema(); - unique_ptr ydk_rpc { root_schema->rpc(operation) }; - - bool is_pass = true; + unique_ptr rpc = get_rpc_instance(provider, "ietf-netconf:validate"); // source - std::string entity_string = get_data_payload(source, *root_schema); - auto result = ydk_rpc->input()->create("source/config", entity_string); - is_pass = is_pass and (result != nullptr); + std::string entity_string = get_data_payload(source, *(provider.get_root_schema())); + rpc->input()->create("source/config", entity_string); - if (!is_pass or (ydk_rpc == nullptr)) + auto read_datanode = (*rpc)(provider); + return read_datanode == nullptr; +} + +static unique_ptr get_rpc_instance(NetconfServiceProvider & provider, string && operation) +{ + path::RootSchemaNode * root_schema = provider.get_root_schema(); + auto rpc = root_schema->rpc(operation); + if (rpc == nullptr) BOOST_THROW_EXCEPTION(YCPPServiceProviderError{"Unable to create rpc"}); - auto read_datanode = (*ydk_rpc)(provider); - return read_datanode == nullptr; + return unique_ptr(rpc); } -std::string get_data_payload(Entity & entity, path::RootSchemaNode & root_schema) +static std::string get_data_payload(Entity & entity, path::RootSchemaNode & root_schema) { - const ydk::path::DataNode* data_node = get_data_node_from_entity(entity, root_schema); + path::DataNode* data_node = get_data_node_from_entity(entity, root_schema); if (data_node==nullptr) return ""; path::CodecService codec{}; - return codec.encode(data_node, ydk::path::CodecService::Format::XML, true); + return codec.encode(data_node, path::CodecService::Format::XML, true); } static unique_ptr get_top_entity_from_filter(Entity & filter) @@ -623,4 +351,52 @@ static unique_ptr get_top_entity_from_filter(Entity & filter) return get_top_entity_from_filter(*(filter.parent)); } + +static void create_input_leaf(path::DataNode & input_datanode, DataStore datastore, string && datastore_string, string & url) +{ + ostringstream os; + os << datastore_string; + + if(datastore == DataStore::url) + { + if(url.size() == 0) + { + BOOST_THROW_EXCEPTION(YCPPServiceError{"URL needs to be specified"}); + } + os << "/url"; + + input_datanode.create(os.str(), url); + } + else + { + create_input_leaf(input_datanode, datastore, move(datastore_string)); + } +} + +static void create_input_leaf(path::DataNode & input_datanode, DataStore datastore, string && datastore_string) +{ + ostringstream os; + os << datastore_string; + + switch(datastore) + { + case DataStore::candidate: + os << "/candidate"; + break; + + case DataStore::running: + os << "/running"; + break; + + case DataStore::startup: + os << "/startup"; + break; + + case DataStore::url: + BOOST_THROW_EXCEPTION(YCPPServiceError{"URL needs to be specified"}); + break; + } + + input_datanode.create(os.str()); +} } diff --git a/sdk/cpp/core/src/netconf_service.hpp b/sdk/cpp/core/src/netconf_service.hpp index 7e4743bfe..fa8f2f011 100644 --- a/sdk/cpp/core/src/netconf_service.hpp +++ b/sdk/cpp/core/src/netconf_service.hpp @@ -50,31 +50,46 @@ enum class DataStore { candidate, running, startup, - url, - config + url }; class NetconfService : public Service { public: NetconfService(); - bool cancel_commit(NetconfServiceProvider & provider, std::string persist_id = ""); + ~NetconfService(); + + bool cancel_commit(NetconfServiceProvider & provider, int persist_id = -1); + bool close_session(NetconfServiceProvider & provider); - bool commit(NetconfServiceProvider & provider, std::string confirmed = "", - std::string confirm_timeout = "", std::string persist = "", std::string persist_id = ""); - bool copy_config(NetconfServiceProvider & provider, DataStore target, DataStore source); - bool copy_config(NetconfServiceProvider & provider, DataStore target, Entity& source); + + bool commit(NetconfServiceProvider & provider, bool confirmed = false, + int confirm_timeout = -1, int persist = -1, int persist_id = -1); + + bool copy_config(NetconfServiceProvider & provider, DataStore target, DataStore source, std::string url = ""); + + bool copy_config(NetconfServiceProvider & provider, DataStore target, Entity& source_config); + bool delete_config(NetconfServiceProvider & provider, DataStore target, std::string url = ""); + bool discard_changes(NetconfServiceProvider & provider); + bool edit_config(NetconfServiceProvider & provider, DataStore target, Entity& config, std::string default_operation = "", std::string test_option = "", std::string error_option = ""); + std::unique_ptr get_config(NetconfServiceProvider & provider, DataStore source, Entity& filter); + std::unique_ptr get(NetconfServiceProvider & provider, Entity& filter); - bool kill_session(NetconfServiceProvider & provider, int session_id); //convert session_id to string + + bool kill_session(NetconfServiceProvider & provider, int session_id); + bool lock(NetconfServiceProvider & provider, DataStore target); + bool unlock(NetconfServiceProvider & provider, DataStore target); - bool validate(NetconfServiceProvider & provider, DataStore source); - bool validate(NetconfServiceProvider & provider, Entity& source); + + bool validate(NetconfServiceProvider & provider, DataStore source, std::string url = ""); + + bool validate(NetconfServiceProvider & provider, Entity& source_config); }; } diff --git a/sdk/cpp/core/src/path/path.cpp b/sdk/cpp/core/src/path/path.cpp index 03a178762..64c4c6fb5 100644 --- a/sdk/cpp/core/src/path/path.cpp +++ b/sdk/cpp/core/src/path/path.cpp @@ -64,429 +64,30 @@ ydk::path::ServiceProvider::~ServiceProvider() } - -///////////////////////////////////////////////////////////////////////// -namespace ydk { - namespace path { - - template - void parse_range_intervals(LengthRangeIntervals& intervals, const char* str_restr) - { - const char* seg_ptr = str_restr; - while(1) { - // min - const char* ptr = seg_ptr; - Range range{intervals.default_range.min, intervals.default_range.max}; - - if(ptr) { - // start processing min - while(isspace(ptr[0])) { - ++ptr; - } - - if (isdigit(ptr[0]) || (ptr[0] == '+') || (ptr[0] == '-')) { - range.min = atoll(ptr); - if((ptr[0] == '+') || (ptr[0] == '-')) { - ++ptr; - } - - while (isdigit(ptr[0])) { - ++ptr; - } - - } else if (!strncmp(ptr, "min", 3)) { - ptr += 3; - } else if(!strncmp(ptr, "max", 3)) { - ptr += 3; - } else { - BOOST_LOG_TRIVIAL(error) << "Error parsing range " << str_restr; - BOOST_THROW_EXCEPTION(YCPPIllegalStateError{"Error parsing range"}); - } - - while (isspace(ptr[0])) { - ptr++; - } - - //no interval or interval - if ((ptr[0] == '|' || !ptr[0])) { - range.max = atoll(ptr); - - } else if( !strncmp(ptr, "..", 2)) { - // skip .. - ptr += 2; - while (isspace(ptr[0])) { - ++ptr; - } - - // max - if (isdigit(ptr[0]) || (ptr[0] == '+') || (ptr[0] == '-')) { - range.max = atoll(ptr); - } else if (!strncmp(ptr, "max", 3)) { - // do nothing since max is already set - - } else { - BOOST_LOG_TRIVIAL(error) << "Error parsing range " << str_restr; - BOOST_THROW_EXCEPTION(YCPPIllegalStateError{"Error parsing range"}); - } - } else { - BOOST_LOG_TRIVIAL(error) << "Error parsing range " << str_restr; - BOOST_THROW_EXCEPTION(YCPPIllegalStateError{"Error parsing range"}); - } - intervals.intervals.push_back(range); - - /* next segment (next OR) */ - seg_ptr = strchr(seg_ptr, '|'); - if (!seg_ptr) { - break; - } - seg_ptr++; - } - } - - } - - - std::unique_ptr create_identity_type(struct ly_set *ident) - { - auto identity_type = std::make_unique(); - if(!ident) return identity_type; - - for(unsigned int i=0;inumber && i<=272;i++) //272 temporary workaround for ietf-interfaces - { - identity_type->module_name = ident->set.s[i]->module->name; - identity_type->name = ident->set.s[i]->name; - struct lys_ident* iden = ((struct lys_ident*)ident->set.s[i]); - - if(iden->der && iden->der->number > 0) - { - identity_type->derived.push_back(create_identity_type(iden->der)); - } - - } - return identity_type; - - } - - - std::unique_ptr create_identity_type(struct lys_ident **ident, int count) - { - - auto identity_type = std::make_unique(); - if(!ident) return identity_type; - - for(int i=0;imodule_name = ident[i]->module->name; - identity_type->name = ident[i]->name; - - if(ident[i]->der && ident[i]->der->number > 0) - { - identity_type->derived.push_back(create_identity_type(ident[i]->der)); - } - - } - return identity_type; - } - - std::unique_ptr create_schema_value_type(struct lys_node_leaf* leaf, - struct lys_type* type) - { - - std::unique_ptr m_type = nullptr; - - LY_DATA_TYPE data_type = type->base; - - switch(data_type){ - case LY_TYPE_BINARY: { - if(type->info.binary.length){ - auto binary = std::make_unique(); - parse_range_intervals(binary->length, type->info.binary.length->expr); - m_type = std::move(binary); - } else if(type->der){ - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique(); - } - - break; - } - case LY_TYPE_BITS: { - std::vector bit_values; - for(int index=0; index < type->info.bits.count; index++) - { - bit_values.push_back( - SchemaValueBitsType::Bit{ - type->info.bits.bit[index].name, - type->info.bits.bit[index].pos - } - ); - } - - m_type = std::make_unique(bit_values); - break; - } - case LY_TYPE_BOOL: { - m_type = std::make_unique(); - break; - } - case LY_TYPE_DEC64: { - m_type = std::make_unique(); - break; - } - case LY_TYPE_EMPTY: { - m_type = std::make_unique(leaf->name); - break; - } - case LY_TYPE_ENUM: { - if(type->info.enums.count > 0) { - auto enum_type = std::make_unique(); - for(int i=0; iinfo.enums.count; i++) - { - SchemaValueEnumerationType::Enum enum_ { - type->info.enums.enm[i].name, type->info.enums.enm[i].value - }; - enum_type->enums.push_back(enum_); - } - m_type = std::move(enum_type); - } else if(type->der){ - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - BOOST_LOG_TRIVIAL(error) << "Unable to determine union's types: " << leaf->name <<", module: "<< leaf->module->name; - BOOST_THROW_EXCEPTION(ydk::YCPPIllegalStateError{"Unable to determine union's types"}); - } - break; - } - case LY_TYPE_IDENT: { - if(type->info.ident.ref) { - m_type = create_identity_type(type->info.ident.ref, type->info.ident.count); - } else if(type->der){ - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - BOOST_LOG_TRIVIAL(error) << "Unable to determine identity type: " << leaf->name <<", module: "<< leaf->module->name; - std::ostringstream os; - os << "Unable to determine identity type: " << leaf->name <<", module: "<< leaf->module->name; - BOOST_THROW_EXCEPTION(ydk::YCPPIllegalStateError{os.str()}); - } - break; - } - case LY_TYPE_INST: { - m_type = std::make_unique(); - break; - } - case LY_TYPE_LEAFREF: { - if(type->info.lref.target) { - m_type = create_schema_value_type(type->info.lref.target, &(type->info.lref.target->type)); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique();//TODO temporary workaround -// BOOST_LOG_TRIVIAL(error) << "Unable to determine leafref type: " << leaf->name <<", module: "<< leaf->module->name; -// std::ostringstream os; -// os << "Unable to determine leafref type: " << leaf->name <<", module: "<< leaf->module->name; -// BOOST_THROW_EXCEPTION(ydk::YCPPIllegalStateError{os.str()}); - } - break; - } - case LY_TYPE_STRING: { - if(type->info.str.length) { - auto stringType = std::make_unique(); - parse_range_intervals(stringType->length, type->info.str.length->expr); - - if(type->info.str.pat_count != 0){ - for(int i =0; i < type->info.str.pat_count; i++) { - stringType->patterns.push_back(type->info.str.patterns[i].expr); - } - } - m_type = std::move(stringType); - - } else if(type->der){ - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - auto stringType = std::make_unique(); - - if(type->info.str.pat_count != 0){ - for(int i=0; i < type->info.str.pat_count; i++) { - stringType->patterns.push_back(type->info.str.patterns[i].expr); - } - } - - m_type = std::move(stringType); - - } - break; - } - case LY_TYPE_UNION: { - - if(type->info.uni.count != 0) { - auto unionType = std::make_unique(); - for(int i=0; i< type->info.uni.count; ++i) { - unionType->types.push_back(create_schema_value_type(leaf,&(type->info.uni.types[i]))); - } - m_type = std::move(unionType); - } else if(type->der){ - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - BOOST_LOG_TRIVIAL(error) << "Unable to determine union's types: " << leaf->name <<", module: "<< leaf->module->name; - std::ostringstream os; - os<<"Unable to determine union's types: " << leaf->name <<", module: "<< leaf->module->name; - BOOST_THROW_EXCEPTION(ydk::YCPPIllegalStateError{os.str()}); - } - - - break; - } - case LY_TYPE_INT8: { - if(type->info.num.range) { - auto int8_type = std::make_unique>( - static_cast(-128), - static_cast(127) - ); - parse_range_intervals(int8_type->range, type->info.num.range->expr); - m_type = std::move(int8_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(-128), - static_cast(127) ); - } - break; - } - case LY_TYPE_UINT8: - { - if(type->info.num.range) { - auto uint8_type = std::make_unique>( static_cast(0),static_cast(255) ); - parse_range_intervals(uint8_type->range, type->info.num.range->expr); - m_type = std::move(uint8_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(0),static_cast(255) ); - } - break; - } - - case LY_TYPE_INT16: - { - if(type->info.num.range) { - auto int16_type = std::make_unique>( static_cast(-32768),static_cast(32767) ); - parse_range_intervals(int16_type->range, type->info.num.range->expr); - m_type = std::move(int16_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(-32768),static_cast(32767) ); - } - break; - } - case LY_TYPE_UINT16: - { - if(type->info.num.range) { - auto uint16_type = std::make_unique>( static_cast(0),static_cast(65535) ); - parse_range_intervals(uint16_type->range, type->info.num.range->expr); - m_type = std::move(uint16_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(0),static_cast(65535) ); - } - break; - } - case LY_TYPE_INT32: - { - if(type->info.num.range) { - auto int32_type = std::make_unique>( static_cast(-2147483648),static_cast(2147483647) ); - parse_range_intervals(int32_type->range, type->info.num.range->expr); - m_type = std::move(int32_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(-2147483648),static_cast(2147483647) ); - } - break; - } - case LY_TYPE_UINT32: - { - if(type->info.num.range) { - auto uint32_type = std::make_unique>( static_cast(0),static_cast(4294967295) ); - parse_range_intervals(uint32_type->range, type->info.num.range->expr); - m_type = std::move(uint32_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(0),static_cast(4294967295) ); - } - break; - } - - case LY_TYPE_INT64: - { - if(type->info.num.range) { - auto int64_type = std::make_unique>( static_cast(-9223372036854775807),static_cast(9223372036854775807) ); - parse_range_intervals(int64_type->range, type->info.num.range->expr); - m_type = std::move(int64_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(-9223372036854775807),static_cast(9223372036854775807) ); - } - break; - } - case LY_TYPE_UINT64: { - if(type->info.num.range) { - auto uint64_type = std::make_unique>( static_cast(0),static_cast(18446744073709551615ULL) ); - parse_range_intervals(uint64_type->range, type->info.num.range->expr); - m_type = std::move(uint64_type); - } else if(type->der) { - m_type = create_schema_value_type(leaf, &(type->der->type)); - } else { - m_type = std::make_unique>( static_cast(0),static_cast(18446744073709551615ULL) ); - } - break; - } - default: - BOOST_LOG_TRIVIAL(error) << "Unknown type to process for schema: " << leaf->name <<", module: "<< leaf->module->name; - std::ostringstream os; - os<<"Unknown type to process for schema: " << leaf->name <<", module: "<< leaf->module->name; - BOOST_THROW_EXCEPTION(YCPPIllegalStateError{os.str()}); - - } - - return m_type; - } - - std::unique_ptr create_schema_value_type(struct lys_node_leaf* leaf) - { - return create_schema_value_type(leaf, &(leaf->type)); - } - - - } -} - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // class ydk::ValidationService ////////////////////////////////////////////////////////////////////////// void -ydk::path::ValidationService::validate(const ydk::path::DataNode* dn, ydk::path::ValidationService::Option option) +ydk::path::ValidationService::validate(const ydk::path::DataNode & dn, ydk::ValidationService::Option option) { std::string option_str = ""; int ly_option = 0; switch(option) { - case ValidationService::Option::DATASTORE: + case ydk::ValidationService::Option::DATASTORE: option_str="DATATSTORE"; ly_option = LYD_OPT_CONFIG; break; - case ValidationService::Option::EDIT_CONFIG: + case ydk::ValidationService::Option::EDIT_CONFIG: option_str="EDIT-CONFIG"; ly_option = LYD_OPT_EDIT; break; - case ValidationService::Option::GET: + case ydk::ValidationService::Option::GET: option_str="GET"; ly_option = LYD_OPT_GET; break; - case ValidationService::Option::GET_CONFIG: + case ydk::ValidationService::Option::GET_CONFIG: option_str="GET-CONFIG"; ly_option = LYD_OPT_GETCONFIG; break; @@ -494,22 +95,16 @@ ydk::path::ValidationService::validate(const ydk::path::DataNode* dn, ydk::path: } ly_option = ly_option | LYD_OPT_NOAUTODEL; - BOOST_LOG_TRIVIAL(debug) << "Validation called on " << dn->path() << " with option " << option_str; + BOOST_LOG_TRIVIAL(debug) << "Validation called on " << dn.path() << " with option " << option_str; //what kind of a DataNode is this - const ydk::path::DataNodeImpl* dn_impl = dynamic_cast(dn); - if(dn_impl){ - struct lyd_node* lynode = dn_impl->m_node; - int rc = lyd_validate(&lynode,ly_option, NULL); - if(rc) { - BOOST_LOG_TRIVIAL(error) << "Data validation failed"; - BOOST_THROW_EXCEPTION(ydk::path::YCPPDataValidationError{}); - } - - } else { - BOOST_LOG_TRIVIAL(error) << "Cast of DataNode to impl failed!!"; - BOOST_THROW_EXCEPTION(YCPPIllegalStateError{"Illegal state"}); - } + const ydk::path::DataNodeImpl & dn_impl = dynamic_cast(dn); + struct lyd_node* lynode = dn_impl.m_node; + int rc = lyd_validate(&lynode,ly_option, NULL); + if(rc) { + BOOST_LOG_TRIVIAL(error) << "Data validation failed"; + BOOST_THROW_EXCEPTION(ydk::path::YCPPDataValidationError{}); + } } diff --git a/sdk/cpp/core/src/path/path_private.hpp b/sdk/cpp/core/src/path/path_private.hpp index 75165c1da..b018c5452 100644 --- a/sdk/cpp/core/src/path/path_private.hpp +++ b/sdk/cpp/core/src/path/path_private.hpp @@ -78,14 +78,10 @@ namespace ydk { std::vector keys() const; - SchemaValueType & type() const; - const SchemaNode* m_parent; struct lys_node* m_node; std::vector> m_children; - std::unique_ptr m_type; - }; @@ -107,7 +103,6 @@ namespace ydk { Rpc* rpc(const std::string& path) const; - SchemaValueType & type() const; struct ly_ctx* m_ctx; @@ -241,9 +236,6 @@ namespace ydk { }; - std::unique_ptr create_schema_value_type(struct lys_node_leaf* leaf, - struct lys_type* type); - std::unique_ptr create_schema_value_type(struct lys_node_leaf* leaf); } diff --git a/sdk/cpp/core/src/path/root_schema_node.cpp b/sdk/cpp/core/src/path/root_schema_node.cpp index 66c873d77..4291d2ab0 100644 --- a/sdk/cpp/core/src/path/root_schema_node.cpp +++ b/sdk/cpp/core/src/path/root_schema_node.cpp @@ -191,10 +191,3 @@ ydk::path::RootSchemaNodeImpl::rpc(const std::string& path) const return new RpcImpl{sn, m_ctx}; } - -ydk::path::SchemaValueType & -ydk::path::RootSchemaNodeImpl::type() const -{ - auto ignored = std::make_unique(); - return *ignored; -} diff --git a/sdk/cpp/core/src/path/schema_node.cpp b/sdk/cpp/core/src/path/schema_node.cpp index 07c992feb..012be4321 100644 --- a/sdk/cpp/core/src/path/schema_node.cpp +++ b/sdk/cpp/core/src/path/schema_node.cpp @@ -38,7 +38,7 @@ ydk::path::SchemaNode::~SchemaNode() ///////////////////////////////////////////////////////////////////// // ydk::SchemaNodeImpl //////////////////////////////////////////////////////////////////// -ydk::path::SchemaNodeImpl::SchemaNodeImpl(const SchemaNode* parent, struct lys_node* node):m_parent{parent}, m_node{node}, m_children{}, m_type{nullptr} +ydk::path::SchemaNodeImpl::SchemaNodeImpl(const SchemaNode* parent, struct lys_node* node):m_parent{parent}, m_node{node}, m_children{} { node->priv = this; if(node->nodetype != LYS_LEAF && node->nodetype != LYS_LEAFLIST) { @@ -49,10 +49,6 @@ ydk::path::SchemaNodeImpl::SchemaNodeImpl(const SchemaNode* parent, struct lys_n m_children.emplace_back(std::make_unique(this,const_cast(q))); last = q; } - } else { - struct lys_node_leaf* node_leaf = reinterpret_cast(m_node); - m_type = ydk::path::create_schema_value_type(node_leaf); - } } @@ -245,12 +241,3 @@ ydk::path::SchemaNodeImpl::keys() const } - -ydk::path::SchemaValueType & -ydk::path::SchemaNodeImpl::type() const -{ - - return *m_type; -} - - diff --git a/sdk/cpp/core/src/path/schema_value_type.cpp b/sdk/cpp/core/src/path/schema_value_type.cpp deleted file mode 100644 index e1d34d1a4..000000000 --- a/sdk/cpp/core/src/path/schema_value_type.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/// YANG Development Kit -// Copyright 2016 Cisco Systems. All rights reserved -// -//////////////////////////////////////////////////////////////// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -// -////////////////////////////////////////////////////////////////// - - -#include "path_private.hpp" -#include - -/////////////////////////////////////////////////////////////////////////////////////////// -/// SchemaValueType -/////////////////////////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueType::~SchemaValueType() -{ - -} - -///////////////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueBinaryType -///////////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueBinaryType::SchemaValueBinaryType(): length{Range{0,18446744073709551615UL}} -{ - -} - - - -ydk::path::SchemaValueBinaryType::~SchemaValueBinaryType() -{ - -} - - -ydk::path::DiagnosticNode -ydk::path::SchemaValueBinaryType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } - return diag; -}; - - - -/////////////////////////////////////////////////////////////////////////////////// -/// ydk::path::SchemaValueBitsType::Bit -////////////////////////////////////////////////////////////////////////////////// -ydk::path::SchemaValueBitsType::Bit::Bit(std::string m_name, uint32_t m_pos) : name{m_name} , -pos{m_pos} { - -} - - -namespace ydk { - namespace path { - static std::vector split(const std::string &s, char delim) { - std::stringstream ss(s); - std::string item; - std::vector tokens; - while (std::getline(ss, item, delim)) { - tokens.push_back(item); - } - return tokens; - } - } -} - - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueBitsType -//////////////////////////////////////////////////////////////////////// -ydk::path::SchemaValueBitsType::SchemaValueBitsType(std::vector bits) : bits(bits) -{ - -} - -ydk::path::SchemaValueBitsType::~SchemaValueBitsType() -{ - -} - -ydk::path::DiagnosticNode -ydk::path::SchemaValueBitsType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()) - { - BOOST_LOG_TRIVIAL(error) << "Empty attribute error for SchemaValueBits"; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } else { - //tokenize and make sure all tokens are accounted for - auto tokens = ydk::path::split(value, ' '); - std::map name_bit_map{}; - for(auto bit : bits){ - name_bit_map.insert(std::make_pair(bit.name,&bit)); - } - for(auto token : tokens) { - if(name_bit_map.find(token) == name_bit_map.end()){ - BOOST_LOG_TRIVIAL(error) << "Invalid bits value " << value; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } - } - - } - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueDec64Type -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueDec64Type::~SchemaValueDec64Type() -{ - -} - - -ydk::path::DiagnosticNode -ydk::path::SchemaValueDec64Type::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "Empty attribute error for SchemaValueDec64Type"; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } - return diag; -} - -////////////////////////////////////////////////////////////////////// -/// ydk::path::SchemaValueEnumerationType::Enum -///////////////////////////////////////////////////////////////////// -ydk::path::SchemaValueEnumerationType::Enum::Enum(std::string m_name, int32_t m_value) : name{m_name}, value{m_value} -{ - -} - - - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueEnumerationType -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueEnumerationType::~SchemaValueEnumerationType() -{ - -} - -ydk::path::DiagnosticNode -ydk::path::SchemaValueEnumerationType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "Empty attribute error for SchemaValueEnumerationType"; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - - } else { - - for(auto e : enums){ - if(e.name == value){ - return diag; - } - } - } - BOOST_LOG_TRIVIAL(error) << "Invalid enum value " << value; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueIdentityType -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueIdentityType::~SchemaValueIdentityType() -{ - -} - -ydk::path::DiagnosticNode -ydk::path::SchemaValueIdentityType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "Empty attribute error for SchemaValueIdentityType"; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - return diag; - } - - auto tokens = ydk::path::split(value, ':'); - if(tokens.size() == 1) { - //no module name just compare the name - if(tokens[0] == name) { - return diag; - } - } else if(tokens[0] == module_name && tokens[1] == name){ - return diag; - } - - for(auto const& ident : derived) { - if(!ident->validate(value).has_errors()){ - return diag; - } - } - - BOOST_LOG_TRIVIAL(error) << "Invalid identity" << value; - diag.errors.push_back(ydk::path::ValidationError::INVALID_IDENTITY); - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueInstanceIdType -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueInstanceIdType::~SchemaValueInstanceIdType() -{ - -} - -ydk::path::DiagnosticNode -ydk::path::SchemaValueInstanceIdType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "Empty attribute error for SchemaValueInstanceIdType"; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } - - - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueStringType -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueStringType::SchemaValueStringType(): length{Range{0,18446744073709551615UL}} -{ - -} - - -ydk::path::SchemaValueStringType::~SchemaValueStringType() -{ - -} - -ydk::path::DiagnosticNode -ydk::path::SchemaValueStringType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "Empty attribute error for SchemaStringType"; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } - - /// first do a length check - auto size = value.length(); - if(length.intervals.empty()){ - if(size < length.default_range.min || size > length.default_range.max) { - BOOST_LOG_TRIVIAL(error) << "Invalid length for string size is " << size; - diag.errors.push_back(ValidationError::INVALID_LENGTH); - - } - } else { - bool constraint_satisfied = false; - for(auto interval : length.intervals) { - if( size >= interval.min && size <= interval.max) { - constraint_satisfied = true; - break; - } - } - - if(!constraint_satisfied){ - BOOST_LOG_TRIVIAL(error) << "Invalid length for string size is " << size; - diag.errors.push_back(ValidationError::INVALID_LENGTH); - } - } - - - /// then a pattern check - /// all patterns have to be matched - for(auto p : patterns) { - std::regex r {p}; - if(!std::regex_match(p, r)){ - BOOST_LOG_TRIVIAL(error) << "String " << value << " failed pattern " << p << " match"; - diag.errors.push_back(ValidationError::INVALID_PATTERN); - } - } - - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueUnionType -//////////////////////////////////////////////////////////////////////// - - -ydk::path::SchemaValueUnionType::~SchemaValueUnionType() -{ - -} - - -ydk::path::DiagnosticNode -ydk::path::SchemaValueUnionType::validate(const std::string& value) const -{ - - for(auto const& type : types){ - auto diag = type->validate(value); - if(!diag.has_errors()){ - return diag; - } - } - - DiagnosticNode diag{}; - BOOST_LOG_TRIVIAL(error) << "Union type validation failed for value " << value; - diag.errors.push_back(ValidationError::INVALATTR); - - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueEmptyType -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueEmptyType::SchemaValueEmptyType(const std::string& mleaf_name) : leaf_name{mleaf_name} -{ - -} - - -ydk::path::SchemaValueEmptyType::~SchemaValueEmptyType() -{ - -} - -ydk::path::DiagnosticNode -ydk::path::SchemaValueEmptyType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "YLeaf is empty for SchemaValueEmptyType" ; - diag.errors.push_back(ydk::path::ValidationError::INVALID_EMPTY_VAL); - } else if(value != leaf_name){ - BOOST_LOG_TRIVIAL(error) << "Mismatch between leaf name " << leaf_name << " and value " << value; - diag.errors.push_back(ydk::path::ValidationError::INVALID_EMPTY_VAL); - } - return diag; -} - -//////////////////////////////////////////////////////////////////// -// ydk::path::SchemaValueBoolType -//////////////////////////////////////////////////////////////////////// - -ydk::path::SchemaValueBoolType::~SchemaValueBoolType() -{ - -} - - -ydk::path::DiagnosticNode -ydk::path::SchemaValueBoolType::validate(const std::string& value) const -{ - DiagnosticNode diag {}; - - if(value.empty()){ - BOOST_LOG_TRIVIAL(error) << "YLeaf is empty for SchemaValueBoolType" ; - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - } else { - - if(value != "true" && value != "false") { - BOOST_LOG_TRIVIAL(error) << "Invalid boolean value " << value; - diag.errors.push_back(ValidationError::INVALID_BOOL_VAL); - } - } - - return diag; -} diff --git a/sdk/cpp/core/src/path_api.hpp b/sdk/cpp/core/src/path_api.hpp index 9d18a5f54..11b4465e5 100644 --- a/sdk/cpp/core/src/path_api.hpp +++ b/sdk/cpp/core/src/path_api.hpp @@ -33,6 +33,7 @@ #include #include "errors.hpp" #include "types.hpp" +#include "validation_service.hpp" #include namespace ydk { @@ -250,19 +251,6 @@ namespace ydk { virtual ~ValidationService() {}; - /// - /// @brief Options for validation. - /// - /// All validation is performed in the context of some operation. - /// These options capture the context of use. - /// - enum class Option { - DATASTORE, /// Datastore validation. Note the DataNode Tree should contain everything for cross reference resolution - GET_CONFIG, // Get config validation. Checks to see if only config nodes are references - GET, // Get validation - EDIT_CONFIG // Edit validation. Checks on the values of leafs etc - }; - /// /// @brief validates dn based on the option /// @@ -271,7 +259,7 @@ namespace ydk { /// @throws YCPPValidationError if validation errors were detected. /// @throws YCPPInvalidArgumentError if the arguments are invalid. /// - virtual void validate(const DataNode* dn, Option option); + virtual void validate(const DataNode & dn, ydk::ValidationService::Option option); }; /// @@ -610,365 +598,6 @@ namespace ydk { }; - - template - struct Range{ - Range(T m_min, T m_max) : min{m_min}, max{m_max} - { - - } - - - T min; - T max; - - }; - - - - - template - struct LengthRangeIntervals { - LengthRangeIntervals(Range m_default_range): default_range(m_default_range) - { - - } - - - Range default_range; - std::vector> intervals; - }; - - /// - /// @brief the type of the leaf or leaf-list - /// - struct SchemaValueType { - - - /// - /// Enumeration representing the yang data types - /// - enum class DataType { - /// UNKNOWN - UNKNOWN, - - /// binary - BINARY, - - /// bits - BITS, - - /// boolean - BOOL, - - /// decimal64 - DEC64, - - /// empty - EMPTY, - - /// enumeration - ENUMERATION, - - /// identity - IDENTITY, - - /// leafref - LEAFREF, - - /// string - STRING, - - /// int8 - INT8, - - /// uint8 - UINT8, - - /// int16 - INT16, - - /// uint16 - UINT16, - - /// int32 - INT32, - - /// uint32 - UINT32, - - /// int64 - INT64, - - /// uint64 - UINT64, - - /// union - UNION - - }; - - - virtual ~SchemaValueType(); - - /// - /// @brief validate the value and return a DiagnosticNode - /// - /// If the value is valid the - virtual DiagnosticNode validate(const std::string& value) const = 0; - - /// - /// module name of the type referenced - std::string module_name; - - /// data type - DataType type; - - - - }; - - - /// - /// binary type - /// - struct SchemaValueBinaryType : public SchemaValueType { - - SchemaValueBinaryType(); - - ~SchemaValueBinaryType(); - - DiagnosticNode validate(const std::string& value) const; - - - - LengthRangeIntervals length; - - - }; - - /// - /// Bits type - /// - struct SchemaValueBitsType : public SchemaValueType { - - /// - /// Single bit value specification - /// - struct Bit { - - Bit(std::string m_name, uint32_t m_pos); - - /// - /// bit name - /// - std::string name; - - /// - /// position - /// - uint32_t pos; - - }; - - SchemaValueBitsType(std::vector bits); - ~SchemaValueBitsType(); - - DiagnosticNode validate(const std::string& value) const; - - /// - /// bit definitions - /// - std::vector bits; - }; - - /// - /// Decimal64 type - /// - struct SchemaValueDec64Type : public SchemaValueType { - - - - /// fraction digits - uint8_t fraction_digits; - - ~SchemaValueDec64Type(); - - DiagnosticNode validate(const std::string& value) const; - }; - - /// - /// enumeration value specification - /// - struct SchemaValueEnumerationType : public SchemaValueType { - - struct Enum { - - Enum(std::string m_name, int32_t m_value); - - /// enum's name (mandatory) - std::string name; - - - /// enum's value (mandatory) - int32_t value; - - - }; - - ~SchemaValueEnumerationType(); - - DiagnosticNode validate(const std::string& value) const; - - /// enum literals - std::vector enums; - - }; - - /// - /// Identity Schema value type - /// - struct SchemaValueIdentityType : public SchemaValueType { - - ~SchemaValueIdentityType(); - - DiagnosticNode validate(const std::string& value) const; - - /// identity name - std::string name; - - /// name of the module - std::string module_name; - - - /// derived identities - std::vector> derived; - - }; - - /// - /// Instance identifier value type - /// - struct SchemaValueInstanceIdType : public SchemaValueType { - - ~SchemaValueInstanceIdType(); - - - DiagnosticNode validate(const std::string& value) const; - - /// require - bool require_identifier = false; - - }; - - /// - /// Number types - /// - template - struct SchemaValueNumberType: public SchemaValueType { - - SchemaValueNumberType(T min, T max) : SchemaValueType{} , range{Range{min, max}} - { - - } - - ~SchemaValueNumberType() - { - - } - - DiagnosticNode validate(const std::string& value) const - { - DiagnosticNode diag{}; - - if(value.empty()){ - diag.errors.push_back(ydk::path::ValidationError::INVALATTR); - return diag; - } - - T number = static_cast(std::atoll(value.c_str())); - if(range.intervals.empty()){ - //use the default - if(number < range.default_range.min || number > range.default_range.max) { - diag.errors.push_back(ydk::path::ValidationError::RANGE_VIOLATION); - return diag; - } - } else { - for(auto r : range.intervals) { - /* if it complies with any one here then it is ok */ - if(number >= r.min && number <= r.max) { - return diag; - } - } - - diag.errors.push_back(ydk::path::ValidationError::RANGE_VIOLATION); - } - - return diag; - - } - - LengthRangeIntervals range; - - }; - - /// - /// string types - /// - struct SchemaValueStringType : public SchemaValueType { - - SchemaValueStringType(); - - ~SchemaValueStringType(); - - DiagnosticNode validate(const std::string& value) const; - - /// length restriction - LengthRangeIntervals length; - - /// pattern restrictions - std::vector patterns; - }; - - /// - /// Union type - /// - struct SchemaValueUnionType : public SchemaValueType { - - ~SchemaValueUnionType(); - - DiagnosticNode validate(const std::string& value) const; - - /// types defined - std::vector> types; - }; - - /// - /// Empty type - /// - struct SchemaValueEmptyType : public SchemaValueType { - - SchemaValueEmptyType(const std::string& mleaf_name); - ~SchemaValueEmptyType(); - - DiagnosticNode validate(const std::string& value) const; - - std::string leaf_name; - }; - - /// - /// Bool type - /// - struct SchemaValueBoolType : public SchemaValueType { - - ~SchemaValueBoolType(); - - - DiagnosticNode validate(const std::string& value) const; - }; - - - /// /// @brief Represents a Node in the SchemaTree. /// @@ -1043,19 +672,6 @@ namespace ydk { /// virtual std::vector keys() const = 0; - - /// - /// @brief return the pointer to the type associated with this - /// schema node. - /// - /// Note this method will only work for SchemaNodes that represent a leaf - /// or leaf-list. Otherwise a nullptr will be returned. - /// - /// @return ptr to SchemaValueType or nullptr. User should not free this pointer - /// it is contained within the SchemaNode so destroying the SchemaNode. - /// - virtual SchemaValueType & type() const = 0; - }; /// diff --git a/sdk/cpp/core/src/validation_service.cpp b/sdk/cpp/core/src/validation_service.cpp index 4c08db39a..08c53deab 100644 --- a/sdk/cpp/core/src/validation_service.cpp +++ b/sdk/cpp/core/src/validation_service.cpp @@ -21,6 +21,8 @@ // ////////////////////////////////////////////////////////////////// +#include "entity_data_node_walker.hpp" +#include "path_api.hpp" #include "service.hpp" #include "validation_service.hpp" #include @@ -30,136 +32,15 @@ using namespace std; namespace ydk { -static void -validate_missing_keys(const EntityPath& entity_path, - const ydk::path::SchemaNode& schema_node, - EntityDiagnostic& diagnostic) -{ - auto keys = schema_node.keys(); - //create a map of the keys - std::map name_value_map{}; - for(auto value_path : entity_path.value_paths) { - name_value_map.insert(value_path); - } - - //we need a key - for(auto key : keys) { - //check if the value list has the value's - if(name_value_map.find(key.arg) == name_value_map.end()) { - ydk::path::DiagnosticNode attr{}; - attr.source = key.arg; - attr.errors.push_back(ydk::path::ValidationError::MISSELEM); - diagnostic.attrs.push_back(std::move(attr)); - } - } - -} - -static void -validate_attributes(const EntityPath& entity_path, const ydk::path::SchemaNode& schema_node, - EntityDiagnostic& diagnostic) -{ - //now validate the values in the value_path that have some values in them - for(auto value_path : entity_path.value_paths) { - if(value_path.second.value.empty()) - continue; - auto leaf_schema_node_list = schema_node.find(value_path.first); - if(leaf_schema_node_list.empty()) - { - //the leaf is invalid or not present in the schema - ydk::path::DiagnosticNode attr{}; - attr.source = value_path.first; - attr.errors.push_back(ydk::path::ValidationError::SCHEMA_NOT_FOUND); - diagnostic.attrs.push_back(std::move(attr)); - } - else - { - ydk::path::SchemaNode* leaf_schema_node = leaf_schema_node_list[0]; - //now test to see if the value is correct - ydk::path::SchemaValueType & type = leaf_schema_node->type(); - auto attr = type.validate(value_path.second.value); - if(attr.has_errors()) - { - attr.source = value_path.first; - diagnostic.attrs.push_back(std::move(attr)); - } - } - } - -} - -static bool -keyword_is_leaf(std::string & keyword) -{ - if(keyword == "leaf" || keyword == "leaf-list" || keyword == "anyxml") - return true; - - return false; -} - -static EntityDiagnostic -validate(const ydk::path::ServiceProvider& sp, ydk::Entity& entity, ydk::Entity* parent, - ydk::ValidationService::Option option) -{ - - EntityPath entity_path = entity.get_entity_path(parent); - - //validation checking - //first check if the schema node that represents this path - //actually exists and then throw an error - - auto root_schema_node = sp.get_root_schema(); - auto schema_node_list = root_schema_node->find(entity_path.path); - - EntityDiagnostic diagnostic{}; - diagnostic.source = &entity; - - if(schema_node_list.empty()) { - diagnostic.errors.push_back(ydk::path::ValidationError::SCHEMA_NOT_FOUND); - //no point processing children - return diagnostic; - - } - - //schema node cannot be leaf, leaf-list or anyxml - ydk::path::SchemaNode* schema_node = schema_node_list[0]; - auto stmt = schema_node->statement(); - if(keyword_is_leaf(stmt.keyword)) { - diagnostic.errors.push_back(ydk::path::ValidationError::INVALID_USE_OF_SCHEMA); - - } else { - // there is no error with the schema for this node - // first check if is a list - - if(option == ValidationService::Option::EDIT_CONFIG || option == ValidationService::Option::DATASTORE) { - - if(stmt.keyword == "list") { - auto keys = schema_node->keys(); - if(!keys.empty()) { - validate_missing_keys(entity_path, *schema_node, diagnostic); - } - } - ydk::validate_attributes(entity_path, *schema_node, diagnostic); - - } - } - - for(auto const & child_entity : entity.get_children()){ - EntityDiagnostic child_diagnostic = validate(sp, *(child_entity.second), &entity, option); - diagnostic.children.push_back(child_diagnostic); - } - - return diagnostic; - -} - -EntityDiagnostic +void ValidationService::validate(const path::ServiceProvider& sp, Entity& entity, ValidationService::Option option) { + auto root_schema = sp.get_root_schema(); + path::DataNode * datanode = get_data_node_from_entity(entity, *root_schema); - return ydk::validate(sp, entity, entity.parent, option); + path::ValidationService path_validation_service{}; + path_validation_service.validate(*datanode, option); } - } diff --git a/sdk/cpp/core/src/validation_service.hpp b/sdk/cpp/core/src/validation_service.hpp index d8623cbbe..1d414c470 100644 --- a/sdk/cpp/core/src/validation_service.hpp +++ b/sdk/cpp/core/src/validation_service.hpp @@ -30,38 +30,18 @@ #include #include -#include "service.hpp" -#include "path_api.hpp" -#include "types.hpp" -namespace ydk { +namespace ydk { -class EntityDiagnostic : public ydk::path::DiagnosticNode +class Entity; +namespace path { - public: - - std::vector> attrs; - - bool has_errors() - { - if(!errors.empty() || !attrs.empty()){ - return true; - } - - for(auto c : children) { - if(c.has_errors()){ - return true; - } - } - return false; - } -}; - - - +class ServiceProvider; +} class ValidationService { + public: /// @@ -82,7 +62,7 @@ class ValidationService { } ~ValidationService(){} - EntityDiagnostic validate(const ydk::path::ServiceProvider& sp, ydk::Entity& entity, ydk::ValidationService::Option option); + void validate(const ydk::path::ServiceProvider& sp, ydk::Entity& entity, ydk::ValidationService::Option option); }; diff --git a/sdk/cpp/core/tests/core/bgptest.cpp b/sdk/cpp/core/tests/core/bgptest.cpp index 99afeb0c2..5a19f4262 100644 --- a/sdk/cpp/core/tests/core/bgptest.cpp +++ b/sdk/cpp/core/tests/core/bgptest.cpp @@ -388,7 +388,7 @@ BOOST_AUTO_TEST_CASE( bgp_validation ) ydk::path::ValidationService validation_service{}; - validation_service.validate(bgp, ydk::path::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(*bgp, ydk::ValidationService::Option::EDIT_CONFIG); diff --git a/sdk/cpp/tests/testsanityvalidationtest.cpp b/sdk/cpp/tests/testsanityvalidationtest.cpp index 321fd7bfe..f982ed81c 100644 --- a/sdk/cpp/tests/testsanityvalidationtest.cpp +++ b/sdk/cpp/tests/testsanityvalidationtest.cpp @@ -45,9 +45,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_int8 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.number8 = static_cast(0); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -63,9 +63,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_int16 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.number16 = static_cast(126); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -80,9 +80,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_int32 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.number32 = 200000; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -97,9 +97,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_int64 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.number64 = -922337203685477580LL; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -114,10 +114,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_uint8 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.u_number8 = static_cast(0); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } BOOST_AUTO_TEST_CASE( test_sanity_types_uint16 ) @@ -131,10 +131,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_uint16 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.u_number16 = static_cast(65535); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -149,9 +149,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_uint32 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.u_number32 = static_cast(5927); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } BOOST_AUTO_TEST_CASE( test_sanity_types_uint64 ) @@ -166,9 +166,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_uint64 ) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.u_number64 = 18446744073709551615ULL; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -186,8 +186,8 @@ BOOST_AUTO_TEST_CASE( bits ) auto r = builtInT.get_entity_path(nullptr); BOOST_TEST_MESSAGE(r.path); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); - BOOST_REQUIRE( !diagnostic.has_errors() ); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + } @@ -200,10 +200,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_decimal64 ) ydk::ValidationService validation_service{}; ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; - builtInT.deci64 = ydk::Decimal64("3.2"); + builtInT.deci64 = ydk::Decimal64("3.12"); + + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -218,10 +218,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_string) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.name = "name_str"; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -237,10 +237,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_empty) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.emptee = empty; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -254,9 +254,9 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_boolean) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.bool_value = true; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -273,10 +273,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_embedded_enum) builtInT.embeded_enum = ydk::ydktest_sanity::Runner::Ytypes::BuiltInT::EmbededEnumEnum::seven; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -293,10 +293,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_enum) builtInT.enum_value = ydk::ydktest_sanity::YdkEnumTestEnum::none; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -313,10 +313,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_union) builtInT.younion = ydk::ydktest_sanity::YdkEnumTestEnum::none; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -333,10 +333,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_union_enum) builtInT.enum_int_value = ydk::ydktest_sanity::YdkEnumIntTestEnum::any; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } BOOST_AUTO_TEST_CASE( test_sanity_types_union_int) @@ -350,10 +350,10 @@ BOOST_AUTO_TEST_CASE( test_sanity_types_union_int) ydk::ydktest_sanity::Runner::Ytypes::BuiltInT builtInT{}; builtInT.enum_int_value = 2; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -370,10 +370,10 @@ BOOST_AUTO_TEST_CASE( test_union_leaflist) builtInT.llunion.append( static_cast(1)); builtInT.llunion.append( static_cast(2)); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -390,10 +390,10 @@ BOOST_AUTO_TEST_CASE( test_enum_leaflist) builtInT.enum_llist.append(ydk::ydktest_sanity::YdkEnumTestEnum::local); builtInT.enum_llist.append(ydk::ydktest_sanity::YdkEnumTestEnum::remote); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } BOOST_AUTO_TEST_CASE( test_identity_leaflist) @@ -409,9 +409,9 @@ BOOST_AUTO_TEST_CASE( test_identity_leaflist) builtInT.identity_llist.append(ydk::ydktest_sanity::ChildIdentityIdentity{}); builtInT.identity_llist.append(ydk::ydktest_sanity::ChildChildIdentityIdentity{}); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -429,9 +429,9 @@ BOOST_AUTO_TEST_CASE( test_union_complex_list) builtInT.younion_list.append("123:45"); - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); } @@ -449,9 +449,9 @@ BOOST_AUTO_TEST_CASE( test_identityref) auto identity = ydk::ydktest_sanity::ChildChildIdentityIdentity{}; builtInT.identity_ref_value = identity; - auto diagnostic = validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + validation_service.validate(sp, builtInT, ydk::ValidationService::Option::EDIT_CONFIG); + - BOOST_REQUIRE( !diagnostic.has_errors() ); }