Skip to content

Commit

Permalink
Added support for non-top level objects in gNMI Service
Browse files Browse the repository at this point in the history
  • Loading branch information
Yan Gorelik committed Dec 12, 2018
1 parent a982548 commit 9770669
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 245 deletions.
9 changes: 6 additions & 3 deletions sdk/cpp/gnmi/src/gnmi_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,12 @@ static GnmiClientRequest build_set_request(gNMIServiceProvider& provider, Entity
else {
parse_entity_prefix(entity, path);
payload = get_data_payload(provider, entity);
auto pos = payload.find("{", 4);
if (pos != string::npos)
payload = payload.substr(pos, payload.length()-pos-1);
if (entity.is_top_level_class) {
// Remove prefix part from the payload
auto pos = payload.find("{", 4);
if (pos != string::npos)
payload = payload.substr(pos, payload.length()-pos-1);
}
}

GnmiClientRequest request{};
Expand Down
63 changes: 33 additions & 30 deletions sdk/cpp/gnmi/src/gnmi_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <ydk/errors.hpp>
#include <ydk/logger.hpp>
#include <ydk/entity_util.hpp>
#include <ydk/common_utilities.hpp>

#include "gnmi_util.hpp"

Expand Down Expand Up @@ -152,9 +153,6 @@ static void parse_entity(Entity & entity, gnmi::Path* path)
}
if (is_key && leaf_data.is_set) {
keys[name_value.first] = leaf_data.value;

// Add surrounding quotes for YDK to work with XR gNMI server
// keys[name_value.first] = "\"" + leaf_data.value + "\"";
}
else if (leaf_data.yfilter != YFilter::not_set) {
leafs[name_value.first] = to_string(leaf_data.yfilter);
Expand Down Expand Up @@ -212,23 +210,6 @@ static void parse_entity_children(Entity & entity, gnmi::Path* path)
}
}

void parse_entity_prefix(Entity& entity, gnmi::Path* path)
{
// Add origin and first container to the path
EntityPath root_path = get_entity_path(entity, nullptr);
auto s = root_path.path;
parse_prefix_to_path(s, path);
}

void parse_entity_to_path(Entity& entity, gnmi::Path* path)
{
// Add origin and first container to the path
parse_entity_prefix(entity, path);

// Add children path
parse_entity_children(entity, path);
}

static void add_path_elem(gnmi::Path* path, string s)
{
map<string,string> keys{};
Expand All @@ -245,10 +226,6 @@ static void add_path_elem(gnmi::Path* path, string s)
string key_value = key_path.substr(equal_pos+2, close_bracket_pos-equal_pos-3);
keys[key_name] = key_value;

// Add surrounding quotes for YDK to work with XR gNMI server.
// This could be an issue with other gNMI servers
// keys[key_name] = "\""+key_value+"\"";

if (close_bracket_pos == key_path.length()-1)
break;
else
Expand All @@ -265,6 +242,38 @@ static void add_path_elem(gnmi::Path* path, string s)
}
}

namespace path {
vector<string> segmentalize(const string& path);
}

void parse_entity_prefix(Entity& entity, gnmi::Path* path)
{
// Add origin and first container to the path
EntityPath root_path = get_entity_path(entity, nullptr);
auto full_path = root_path.path;
vector<string> segments = ydk::path::segmentalize(full_path);
YLOG_DEBUG("parse_entity_prefix: Entity path: '{}'", full_path);
parse_prefix_to_path(segments[0], path);
auto segment_path = entity.get_segment_path();
for (size_t i=1; i < segments.size(); i++) {
if (segments[i] == segment_path)
break;
add_path_elem(path, segments[i]);
}
}

void parse_entity_to_path(Entity& entity, gnmi::Path* path)
{
// Add origin and first container to the path
parse_entity_prefix(entity, path);

// Add children path
if (entity.is_top_level_class)
parse_entity_children(entity, path);
else
parse_entity(entity, path);
}

void parse_prefix_to_path(const string& prefix, gnmi::Path* path)
{
// Add origin and first container to the path
Expand All @@ -286,8 +295,6 @@ void parse_prefix_to_path(const string& prefix, gnmi::Path* path)

namespace path {

vector<string> segmentalize(const string& path);

static path::DataNode* get_last_datanode(DataNode* dn)
{
auto children = dn->get_children();
Expand Down Expand Up @@ -317,10 +324,6 @@ void parse_datanode_to_path(DataNode* dn, gnmi::Path* path)
std::vector<std::string> segments = path::segmentalize(full_path);

YLOG_DEBUG("parse_datanode_to_path: Data node path: '{}'", full_path);
int count = 0;
for (auto segment : segments) {
YLOG_DEBUG("parse_datanode_to_path: Segment {}: '{}'", count++, segment);
}

// Add origin and first container to the path
auto s = segments[1];
Expand Down
14 changes: 5 additions & 9 deletions sdk/cpp/gnmi/tests/test_core_gnmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,12 @@

TEST_CASE( "test_gnmi_entity_to_path" )
{
auto ifc = std::make_shared<ydktest::openconfig_interfaces::Interfaces::Interface>();
ifc->name = "Loopback10";
ifc->config->yfilter = ydk::YFilter::read;

ydktest::openconfig_interfaces::Interfaces ifcs{};
ifcs.interface.append(ifc);
auto ifc = ydktest::openconfig_interfaces::Interfaces::Interface();
ifc.name = "Loopback10";
ifc.config->yfilter = ydk::YFilter::read;

gnmi::Path* path = new gnmi::Path();
ydk::parse_entity_to_path(ifcs, path);
ydk::parse_entity_to_path(ifc, path);

std::string expected = R"(origin: "openconfig-interfaces"
elem {
Expand Down Expand Up @@ -331,11 +328,10 @@ TEST_CASE("gnmi_rpc_subscribe")
subscription.create_datanode("encoding", "JSON_IETF");

auto & ifs = schema.create_datanode("openconfig-interfaces:interfaces", "");
ifs.create_datanode("interface[name='*']/state");
auto int_json = codec.encode(ifs, ydk::EncodingFormat::JSON, false);

auto & bgp = schema.create_datanode("openconfig-bgp:bgp", "");
bgp.create_datanode("neighbors/neighbor[neighbor-address='0.0.0.0']/state");
bgp.create_datanode("neighbors");
auto bgp_json = codec.encode(bgp, ydk::EncodingFormat::JSON, false);

auto & int_subscription = subscription.create_datanode("subscription-list[alias='int']", "");
Expand Down
50 changes: 26 additions & 24 deletions sdk/cpp/gnmi/tests/test_gnmi_crud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,35 @@ TEST_CASE("gnmi_crud_single_entity")
CodecServiceProvider codec_provider{EncodingFormat::JSON};
CodecService codec_service{};

auto ifc = make_shared<openconfig_interfaces::Interfaces::Interface>();
ifc->name = "Loopback10";
ifc->config->name = "Loopback10";

openconfig_interfaces::Interfaces ifcs{};
ifcs.interface.append(ifc);
auto ifc = openconfig_interfaces::Interfaces::Interface();
ifc.name = "Loopback10";
ifc.config->name = "Loopback10";

// Set-replace Request
auto reply = crud.create(provider, ifcs);
auto reply = crud.create(provider, ifc);
REQUIRE(reply);

ifc->config->description = "Test";
reply = crud.update(provider, ifcs);
ifc.config->description = "Test";
reply = crud.update(provider, ifc);
REQUIRE(reply);

// READ and VERIFY
openconfig_interfaces::Interfaces filter{};
auto ifc_read = crud.read(provider, filter);
auto ifc_filter = make_shared<openconfig_interfaces::Interfaces::Interface>();
ifc_filter->name = "Loopback10";
filter.interface.append(ifc_filter);

auto ifc_read = crud.read(provider, *ifc_filter);
REQUIRE(ifc_read != nullptr);
REQUIRE(*ifc_read == ifcs);
REQUIRE(*ifc_read == ifc);

ifc_read = crud.read_config(provider, filter);
ifc_read = crud.read_config(provider, *ifc_filter);
REQUIRE(ifc_read != nullptr);
REQUIRE(*ifc_read == ifc);

reply = crud.delete_(provider, ifcs);
auto ifc_delete = openconfig_interfaces::Interfaces::Interface();
ifc_delete.name = "Loopback10";
reply = crud.delete_(provider, ifc_delete);
REQUIRE(reply);
}

Expand All @@ -95,21 +100,18 @@ TEST_CASE("gnmi_crud_read_leaf")
openconfig_interfaces::Interfaces ifcs{};
ifcs.interface.append(ifc);

auto ifc_read = crud.read(provider, ifcs);
auto ifc_read = crud.read(provider, *ifc);
REQUIRE(ifc_read != nullptr);
string expected = R"( <interfaces>
<interface>
<name>Loopback10</name>
<config>
<description>Test</description>
</config>
</interface>
</interfaces>
string expected = R"( <interface>
<name>Loopback10</name>
<config>
<description>Test</description>
</config>
</interface>
)";
REQUIRE(entity2string(ifc_read, provider.get_session().get_root_schema()) == expected);

auto reply = crud.delete_(provider, ifcs);
REQUIRE(reply);
delete_int_config(provider);
}

TEST_CASE("gnmi_crud_multiple_entities")
Expand Down
23 changes: 6 additions & 17 deletions sdk/cpp/gnmi/tests/test_gnmi_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,13 @@ TEST_CASE("gnmi_service_capabilities")
REQUIRE(json_caps.find(cap_update) != string::npos);
}

static string int_update = R"(val {
json_ietf_val: "{\"interface\":[{\"name\":\"Loopback10\",\"config\":{\"name\":\"Loopback10\",\"description\":\"Test\"}}]}"
})";
static string int_update = R"([{\"name\":\"Loopback10\",\"config\":{\"name\":\"Loopback10\",\"description\":\"Test\"}}])";

static string bgp_update = R"(val {
json_ietf_val: "{\"global\":{\"config\":{\"as\":65172} },\"neighbors\":{\"neighbor\":[{\"neighbor-address\":\"172.16.255.2\",\"config\":{\"neighbor-address\":\"172.16.255.2\",\"peer-as\":65172}}]}}"
})";
static string bgp_update = R"([{\"neighbor-address\":\"172.16.255.2\",\"config\":{\"neighbor-address\":\"172.16.255.2\",\"peer-as\":65172}}])";

void read_sub(const char * subscribe_response)
{
cout << subscribe_response << endl;
cout << endl << subscribe_response << endl;
}

void gnmi_service_subscribe_callback(const char * subscribe_response)
Expand Down Expand Up @@ -102,14 +98,11 @@ TEST_CASE("gnmi_service_subscribe")
build_int_config(provider);

// Build subscription
openconfig_interfaces::Interfaces filter = {};
auto i = make_shared<openconfig_interfaces::Interfaces::Interface>();
i->yfilter = YFilter::read;
//i->name = "*";
filter.interface.append(i);

gNMISubscription subscription{};
subscription.entity = &filter;
subscription.entity = i.get();
//subscription.subscription_mode = "ON_CHANGE";
subscription.sample_interval = 10000000000;
//subscription.suppress_redundant = true;
Expand All @@ -132,26 +125,22 @@ TEST_CASE("gnmi_service_subscribe_multiples")
build_bgp_config(provider);

// Build subscription
openconfig_interfaces::Interfaces ifcs = {};
auto ifc = make_shared<openconfig_interfaces::Interfaces::Interface>();
ifc->name = "*";
ifcs.interface.append(ifc);

openconfig_bgp::Bgp bgp = {};
auto neighbor = make_shared<openconfig_bgp::Bgp::Neighbors::Neighbor>();
neighbor->neighbor_address = "*";
bgp.neighbors->neighbor.append(neighbor);

// Build subscriptions
gNMISubscription ifc_subscription{};
ifc_subscription.entity = &ifcs;
ifc_subscription.entity = ifc.get();
//ifc_subscription.subscription_mode = "ON_CHANGE";
ifc_subscription.sample_interval = 10000000000;
//ifc_subscription.suppress_redundant = true;
ifc_subscription.heartbeat_interval = 100000000000;

gNMISubscription bgp_subscription{};
bgp_subscription.entity = &bgp;
bgp_subscription.entity = neighbor.get();
bgp_subscription.subscription_mode = "TARGET_DEFINED";
bgp_subscription.sample_interval = 20000000000;
bgp_subscription.suppress_redundant = false;
Expand Down
16 changes: 6 additions & 10 deletions sdk/cpp/gnmi/tests/test_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ void config_bgp(openconfig_bgp::Bgp& bgp)
neighbor->config->neighbor_address = "172.16.255.2";
neighbor->config->peer_as = 65172;

neighbor->parent = bgp.neighbors.get();
bgp.neighbors->neighbor.append(neighbor);
}

Expand All @@ -108,17 +107,14 @@ void build_bgp_config(gNMIServiceProvider& provider)

void build_int_config(gNMIServiceProvider& provider)
{
auto ifc = make_shared<openconfig_interfaces::Interfaces::Interface>();
ifc->name = "Loopback10";
ifc->config->name = "Loopback10";
ifc->config->description = "Test";

openconfig_interfaces::Interfaces ifcs{};
ifcs.interface.append(ifc);
ifcs.yfilter = YFilter::replace;
auto ifc = openconfig_interfaces::Interfaces::Interface();
ifc.name = "Loopback10";
ifc.config->name = "Loopback10";
ifc.config->description = "Test";
ifc.yfilter = YFilter::replace;

gNMIService gs{};
gs.set(provider, ifcs);
gs.set(provider, ifc);
}

void delete_bgp_config(gNMIServiceProvider& provider)
Expand Down
Loading

0 comments on commit 9770669

Please sign in to comment.