Skip to content

Commit

Permalink
Fix yang case when two containers with same name , but different name… (
Browse files Browse the repository at this point in the history
#640)

* Fix yang case when two containers with same name , but different namespaces, augment one container

 * Fix golang naming to be consistent with other langs
  * Updated samples and tests
 * address #535
 * Add more debug msgs and throw exceptions to avoid segfaults
 * tcp server start/stop

* Fix golang struct member issue

* Codacy

* Address review
* Fixes #612
  • Loading branch information
Abhi Keshav committed Nov 30, 2017
1 parent c787803 commit 457e0a1
Show file tree
Hide file tree
Showing 58 changed files with 743 additions and 286 deletions.
2 changes: 2 additions & 0 deletions profiles/test/ydktest-cpp.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
"sdk/cpp/core/tests/models/openconfig-bgp.yang",
"sdk/cpp/core/tests/models/openconfig-extensions.yang",
"sdk/cpp/core/tests/models/openconfig-interfaces.yang",
"sdk/cpp/core/tests/models/openconfig-if-ethernet.yang",
"sdk/cpp/core/tests/models/openconfig-policy-types.yang",
"sdk/cpp/core/tests/models/openconfig-routing-policy.yang",
"sdk/cpp/core/tests/models/openconfig-types.yang",
"sdk/cpp/core/tests/models/openconfig-platform.yang",
"sdk/cpp/core/tests/models/openconfig-platform-transceiver.yang",
"sdk/cpp/core/tests/models/openconfig-platform-types.yang",
"sdk/cpp/core/tests/models/openconfig-transport-types.yang",
"sdk/cpp/core/tests/models/openconfig-terminal-device.yang",
"sdk/cpp/core/tests/models/ydktest-filterread@2015-11-17.yang",
"sdk/cpp/core/tests/models/ydktest-sanity-augm@2015-11-17.yang",
"sdk/cpp/core/tests/models/ydktest-sanity-submodule@2016-04-25.yang",
Expand Down
40 changes: 26 additions & 14 deletions sdk/cpp/core/src/entity_data_node_walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static bool data_node_is_leaf(path::DataNode & data_node);
static bool data_node_is_list(path::DataNode & data_node);
static string get_segment_path(const string & path);
static void add_annotation_to_datanode(const Entity & entity, path::DataNode & data_node);
static void add_annotation_to_datanode(const std::pair<std::string, LeafData> & name_value, path::DataNode & data_node);
static void add_annotation_to_datanode(const pair<string, LeafData> & name_value, path::DataNode & data_node);
static path::Annotation get_annotation(YFilter yfilter);


Expand Down Expand Up @@ -124,21 +124,21 @@ static void populate_data_node(Entity & entity, path::DataNode & parent_data_nod
static void populate_name_values(path::DataNode & data_node, EntityPath & path)
{
YLOG_DEBUG("Leaf count: {}", path.value_paths.size());
for(const std::pair<std::string, LeafData> & name_value : path.value_paths)
for(const pair<string, LeafData> & name_value : path.value_paths)
{
path::DataNode* result = nullptr;
LeafData leaf_data = name_value.second;
YLOG_DEBUG("Creating child {} of {} with value: '{}', is_set: {}", name_value.first, data_node.get_path(),
YLOG_DEBUG("Creating leaf {} of {} with value: '{}', is_set: {}", name_value.first, data_node.get_path(),
leaf_data.value, leaf_data.is_set);

if(leaf_data.is_set)
{
result = &data_node.create_datanode(name_value.first, leaf_data.value);
YLOG_DEBUG("Result: {}", (result?"success":"failure"));
YLOG_DEBUG("Creating datanode");
auto & result = data_node.create_datanode(name_value.first, leaf_data.value);
YLOG_DEBUG("Created datanode");

if(is_set(leaf_data.yfilter))
{
add_annotation_to_datanode(name_value, *result);
add_annotation_to_datanode(name_value, result);
}
}
}
Expand All @@ -157,7 +157,7 @@ static void add_annotation_to_datanode(const Entity & entity, path::DataNode & d
}
}

static void add_annotation_to_datanode(const std::pair<std::string, LeafData> & name_value, path::DataNode & data_node)
static void add_annotation_to_datanode(const pair<string, LeafData> & name_value, path::DataNode & data_node)
{
YLOG_DEBUG("Got yfilter '{}' for {}", to_string(name_value.second.yfilter), name_value.first);
if (name_value.second.yfilter != YFilter::read)
Expand All @@ -179,24 +179,35 @@ static path::Annotation get_annotation(YFilter yfilter)
//////////////////////////////////////////////////////////////////////////
// Entity from DataNode*
//////////////////////////////////////////////////////////////////////////
void get_entity_from_data_node(path::DataNode * node, std::shared_ptr<Entity> entity)
void get_entity_from_data_node(path::DataNode * node, shared_ptr<Entity> entity)
{
if (entity == nullptr || node == nullptr)
return;

YLOG_DEBUG("Looking at parent entity {}", entity->yang_name);
string module_name = node->get_schema_node().get_statement().module_name;
for(auto & child_data_node:node->get_children())
{
std::string child_name = child_data_node->get_schema_node().get_statement().arg;
string child_name = child_data_node->get_schema_node().get_statement().arg;
string child_module_name = child_data_node->get_schema_node().get_statement().module_name;
if(module_name != child_module_name)
{
child_name = child_module_name + ":" + child_name;
}

YLOG_DEBUG("Looking at child {} '{}'", child_data_node->get_schema_node().get_statement().keyword, child_data_node->get_path());

if(data_node_is_leaf(*child_data_node))
{
YLOG_DEBUG("Creating leaf {} of value '{}' in parent {}", child_name,
YLOG_DEBUG("Creating entity leaf {} of value '{}' in parent {}", child_name,
child_data_node->get_value(), node->get_path());
entity->set_value(child_name, child_data_node->get_value());
YLOG_DEBUG("Created leaf");
}
else
{
YLOG_DEBUG("Going into child {} in parent {}", child_name, node->get_path());
std::shared_ptr<Entity> child_entity;
shared_ptr<Entity> child_entity;
if(data_node_is_list(*child_data_node))
{
child_entity = entity->get_child_by_name(child_name, get_segment_path(child_data_node->get_path()));
Expand All @@ -205,12 +216,13 @@ void get_entity_from_data_node(path::DataNode * node, std::shared_ptr<Entity> en
{
child_entity = entity->get_child_by_name(child_name);
}
child_entity->parent = entity.get();

if(child_entity == nullptr)
{
YLOG_ERROR("Couldn't fetch child entity {} in parent {}!", child_name, node->get_path());
throw(path::YCPPCoreError{"Couldn't fetch child entity '" + child_name + "' in parent " + node->get_path()});
}
child_entity->parent = entity.get();
get_entity_from_data_node(child_data_node.get(), child_entity);
}
}
Expand All @@ -229,7 +241,7 @@ static bool data_node_is_list(path::DataNode & data_node)

static string get_segment_path(const string & path)
{
std::vector<std::string> segments = path::segmentalize(path);
vector<string> segments = path::segmentalize(path);
return segments.back();
}

Expand Down
22 changes: 22 additions & 0 deletions sdk/cpp/core/src/path/data_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@
#include "path_private.hpp"
#include "../logger.hpp"

namespace ydk
{
namespace path
{

static void check_ly_schema_node_for_path(lyd_node* node, const std::string & path)
{
if(node == nullptr || node->schema == nullptr || node->schema->priv == nullptr)
{
YLOG_ERROR("Couldn't fetch schema node {}!", path);
throw(YCPPCoreError{"Couldn't fetch schema node " + path});
}
}

}
}

////////////////////////////////////////////////////////////////////////
/// DataNode
Expand Down Expand Up @@ -70,6 +86,7 @@ ydk::path::DataNodeImpl::~DataNodeImpl()
const ydk::path::SchemaNode&
ydk::path::DataNodeImpl::get_schema_node() const
{
check_ly_schema_node_for_path(m_node, get_path());
auto schema_ptr = reinterpret_cast<const SchemaNode*>(m_node->schema->priv);
return *schema_ptr;
}
Expand All @@ -89,14 +106,17 @@ ydk::path::DataNodeImpl::get_path() const
void
ydk::path::DataNodeImpl::populate_new_schemas_from_path(const std::string& path)
{
check_ly_schema_node_for_path(m_node, path);
auto snode = reinterpret_cast<SchemaNodeImpl*>(m_node->schema->priv);
snode->populate_new_schemas_from_path(path);
}

ydk::path::DataNode&
ydk::path::DataNodeImpl::create_datanode(const std::string& path, const std::string& value)
{
YLOG_DEBUG("Populating schemas for {}", path);
populate_new_schemas_from_path(path);
YLOG_DEBUG("Populating schemas for {}", value);
populate_new_schemas_from_path(value);
return create_helper(path, value);
}
Expand All @@ -110,6 +130,8 @@ ydk::path::DataNodeImpl::create_helper(const std::string& path, const std::strin
throw(YCPPInvalidArgumentError{"Path is empty."});
}

YLOG_DEBUG("Creating node '{}' with value '{}'", path, value);

std::vector<std::string> segments = segmentalize(path);

DataNodeImpl* dn = this;
Expand Down
1 change: 1 addition & 0 deletions sdk/cpp/core/src/path/repository.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ ydk::path::RepositoryPtr::get_new_ly_modules_from_path(ly_ctx* ctx,
const std::string& path,
const std::unordered_map<std::string, path::Capability>& lookup_table)
{
YLOG_DEBUG("Getting new modules for {}", path);
auto module_names = path::segmentalize_module_names(path);
return get_new_ly_modules_from_lookup(ctx, module_names, lookup_table);
}
Expand Down
1 change: 1 addition & 0 deletions sdk/cpp/core/src/path/root_schema_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ ydk::path::RootSchemaNodeImpl::populate_new_schemas_from_payload(const std::stri

void
ydk::path::RootSchemaNodeImpl::populate_new_schemas_from_path(const std::string& path) {
YLOG_DEBUG("Getting new modules for {}", path);
auto new_modules = m_priv_repo->get_new_ly_modules_from_path(m_ctx, path, m_name_namespace_lookup);
populate_new_schemas(new_modules);
}
Expand Down
36 changes: 20 additions & 16 deletions sdk/cpp/core/src/path/schema_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "path_private.hpp"
#include "../logger.hpp"

using namespace std;

///////////////////////////////////////////////////////////////////////////////
/// SchemaNode
Expand All @@ -46,14 +47,14 @@ ydk::path::SchemaNodeImpl::SchemaNodeImpl(const SchemaNode* parent, struct lys_n
const struct lys_node *last = nullptr;

while( auto q = lys_getnext(last, node, nullptr, 0)) {
m_children.emplace_back(std::make_unique<SchemaNodeImpl>(this, const_cast<struct lys_node*>(q)));
m_children.emplace_back(make_unique<SchemaNodeImpl>(this, const_cast<struct lys_node*>(q)));
last = q;
}
}
}

void
ydk::path::SchemaNodeImpl::populate_augmented_schema_node(std::vector<lys_node*>& ancestors, struct lys_node* node) {
ydk::path::SchemaNodeImpl::populate_augmented_schema_node(vector<lys_node*>& ancestors, struct lys_node* node) {
if (!ancestors.empty()) {
auto curr = ancestors.back();
ancestors.pop_back();
Expand All @@ -70,8 +71,8 @@ ydk::path::SchemaNodeImpl::populate_augmented_schema_node(std::vector<lys_node*>
p = p->child;
}
if (p) {
YLOG_DEBUG("Populating new schema node '{}'", std::string(p->name));
m_children.emplace_back(std::make_unique<SchemaNodeImpl>(this, const_cast<struct lys_node*>(p)));
YLOG_DEBUG("Populating new schema node '{}'", string(p->name));
m_children.emplace_back(make_unique<SchemaNodeImpl>(this, const_cast<struct lys_node*>(p)));
}
node = node->next;
}
Expand All @@ -82,12 +83,12 @@ ydk::path::SchemaNodeImpl::~SchemaNodeImpl()
{
}

std::string
string
ydk::path::SchemaNodeImpl::get_path() const
{
std::string ret{};
string ret{};

std::vector<std::string> segments;
vector<string> segments;

struct lys_node* cur_node = m_node;
struct lys_module* module = nullptr;
Expand All @@ -97,7 +98,7 @@ ydk::path::SchemaNodeImpl::get_path() const
if (!cur_node->parent || cur_node->parent->module != module) {
//qualify with module name

std::string segname {module->name};
string segname {module->name};
segname+=':';
segname+=cur_node->name;
segments.push_back(segname);
Expand All @@ -107,7 +108,7 @@ ydk::path::SchemaNodeImpl::get_path() const
cur_node = cur_node->parent;
}

std::reverse(segments.begin(), segments.end());
reverse(segments.begin(), segments.end());
for ( auto seg : segments ) {
ret+="/";
ret+=seg;
Expand All @@ -117,8 +118,8 @@ ydk::path::SchemaNodeImpl::get_path() const
return ret;
}

std::vector<ydk::path::SchemaNode*>
ydk::path::SchemaNodeImpl::find(const std::string& path)
vector<ydk::path::SchemaNode*>
ydk::path::SchemaNodeImpl::find(const string& path)
{
populate_new_schemas_from_path(path);

Expand All @@ -135,7 +136,7 @@ ydk::path::SchemaNodeImpl::find(const std::string& path)
throw(YCPPInvalidArgumentError{"path must be a relative path"});
}

std::vector<SchemaNode*> ret;
vector<SchemaNode*> ret;
struct ly_ctx* ctx = m_node->module->ctx;

const struct lys_node* found_node = ly_ctx_get_node(ctx, m_node, path.c_str());
Expand All @@ -158,7 +159,7 @@ ydk::path::SchemaNodeImpl::get_parent() const noexcept
return m_parent;
}

const std::vector<std::unique_ptr<ydk::path::SchemaNode>> &
const vector<unique_ptr<ydk::path::SchemaNode>> &
ydk::path::SchemaNodeImpl::get_children() const
{

Expand All @@ -179,9 +180,11 @@ ydk::path::SchemaNodeImpl::get_root() const noexcept
}

void
ydk::path::SchemaNodeImpl::populate_new_schemas_from_path(const std::string& path) {
ydk::path::SchemaNodeImpl::populate_new_schemas_from_path(const string& path) {
YLOG_DEBUG("Looking to populate schemas for {}", path);
auto snode = const_cast<SchemaNode*>(&get_root());
auto rsnode = reinterpret_cast<RootSchemaNodeImpl*>(snode);
YLOG_DEBUG("Ready to populate schemas for {}", path);
rsnode->populate_new_schemas_from_path(path);
}

Expand All @@ -195,6 +198,7 @@ ydk::path::SchemaNodeImpl::get_statement() const
{
Statement s{};
s.arg = m_node->name;
s.module_name = m_node->module?m_node->module->name:"";
if(is_submodule(m_node))
{
s.name_space = ((lys_submodule*)m_node->module)->belongsto->ns;
Expand Down Expand Up @@ -270,10 +274,10 @@ ydk::path::SchemaNodeImpl::get_statement() const
/// Returns the vector of Statement keys
/// @return vector of Statement that represent keys
///
std::vector<ydk::path::Statement>
vector<ydk::path::Statement>
ydk::path::SchemaNodeImpl::get_keys() const
{
std::vector<Statement> stmts{};
vector<Statement> stmts{};

Statement stmt = get_statement();
if(stmt.keyword == "list") {
Expand Down
2 changes: 2 additions & 0 deletions sdk/cpp/core/src/path_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ struct Statement {
std::string keyword;
/// the arg if any
std::string arg;
/// the module name if any
std::string module_name;
/// the namespace if any
std::string name_space;

Expand Down
8 changes: 8 additions & 0 deletions sdk/cpp/core/src/ydk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,14 @@ const char* DataNodeGetKeyword(DataNode datanode)
return string_to_array(s);
}

const char* DataNodeGetModuleName(DataNode datanode)
{
DataNodeWrapper* datanode_wrapper = (DataNodeWrapper*)datanode;
ydk::path::DataNode* real_datanode = unwrap(datanode_wrapper);
string s = real_datanode->get_schema_node().get_statement().module_name;
return string_to_array(s);
}

const char* DataNodeGetPath(DataNode datanode)
{
DataNodeWrapper* datanode_wrapper = (DataNodeWrapper*)datanode;
Expand Down
1 change: 1 addition & 0 deletions sdk/cpp/core/src/ydk.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ DataNode RpcExecute(YDKStatePtr, Rpc, ServiceProvider);

DataNode DataNodeCreate(YDKStatePtr, DataNode, const char*, const char*);
const char* DataNodeGetArgument(DataNode);
const char* DataNodeGetModuleName(DataNode);
const char* DataNodeGetKeyword(DataNode);
const char* DataNodeGetPath(DataNode);
const char* DataNodeGetValue(DataNode);
Expand Down
10 changes: 8 additions & 2 deletions sdk/cpp/core/tests/confd/ydktest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ all: openconfig-platform.deviation\
ydktest-types.fxs openconfig-bgp-types.fxs openconfig-bgp-policy.fxs openconfig-extensions.fxs openconfig-policy-types.fxs\
ietf-interfaces.fxs openconfig-types.fxs openconfig-routing-policy.fxs openconfig-platform.fxs openconfig-interfaces.fxs openconfig-bgp.fxs\
openconfig-platform-types.fxs openconfig-platform-transceiver.fxs oc-pattern.fxs main.fxs main-aug1.fxs iana-if-type.fxs\
openconfig-transport-types.fxs ietf-aug-base-1.fxs ietf-aug-base-2.fxs\
openconfig-transport-types.fxs ietf-aug-base-1.fxs ietf-aug-base-2.fxs openconfig-terminal-device.fxs openconfig-if-ethernet.fxs\
ydktest-aug-ietf-1.fxs ydktest-aug-ietf-2.fxs ydktest-aug-ietf-4.fxs ydktest-aug-ietf-5.fxs\
$(CDB_DIR) ssh-keydir
@echo "Build complete"

openconfig-platform.deviation : cisco-xr-openconfig-platform-deviations.yang \
openconfig-platform.yang openconfig-platform-transceiver.yang openconfig-transport-types.yang openconfig-platform-types.yang\
openconfig-extensions.yang openconfig-interfaces.yang
openconfig-extensions.yang openconfig-interfaces.yang openconfig-terminal-device.yang openconfig-if-ethernet.yang
$(CONFDC) $(FXS_WERR) $(EXTRA_LINK_FLAGS) -o $(basename $@).fxs -c $(basename $@).yang \
--deviation $(word 1, $^)

Expand Down Expand Up @@ -98,6 +98,12 @@ openconfig-platform.yang: openconfig-platform-types.yang openconfig-platform-tra
openconfig-transport-types.yang
cp ../../models/openconfig-platform.yang openconfig-platform.yang

openconfig-terminal-device.yang: openconfig-platform.yang openconfig-if-ethernet.yang
cp ../../models/openconfig-terminal-device.yang openconfig-terminal-device.yang

openconfig-if-ethernet.yang:
cp ../../models/openconfig-if-ethernet.yang openconfig-if-ethernet.yang

openconfig-platform-types.yang:
cp ../../models/openconfig-platform-types.yang openconfig-platform-types.yang

Expand Down
Loading

0 comments on commit 457e0a1

Please sign in to comment.