Skip to content

Commit aa2750b

Browse files
Added /rolePaths/{rolePath}/properties endpoint
1 parent 3a63684 commit aa2750b

File tree

3 files changed

+76
-14
lines changed

3 files changed

+76
-14
lines changed

Development/nmos/configuration_api.cpp

+73-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//#include "cpprest/json_validator.h"
66
#include "nmos/api_utils.h"
77
#include "nmos/control_protocol_resource.h"
8+
#include "nmos/control_protocol_state.h"
89
#include "nmos/control_protocol_utils.h"
910
#include "nmos/is14_versions.h"
1011
//#include "nmos/json_schema.h"
@@ -13,9 +14,9 @@
1314

1415
namespace nmos
1516
{
16-
inline web::http::experimental::listener::api_router make_unmounted_configuration_api(nmos::node_model& model, slog::base_gate& gate);
17+
inline web::http::experimental::listener::api_router make_unmounted_configuration_api(nmos::node_model& model, get_control_protocol_class_descriptor_handler get_control_protocol_class_descriptor, slog::base_gate& gate);
1718

18-
web::http::experimental::listener::api_router make_configuration_api(nmos::node_model& model, web::http::experimental::listener::route_handler validate_authorization, slog::base_gate& gate)
19+
web::http::experimental::listener::api_router make_configuration_api(nmos::node_model& model, web::http::experimental::listener::route_handler validate_authorization, get_control_protocol_class_descriptor_handler get_control_protocol_class_descriptor, slog::base_gate& gate)
1920
{
2021
using namespace web::http::experimental::listener::api_router_using_declarations;
2122

@@ -46,7 +47,7 @@ namespace nmos
4647
return pplx::task_from_result(true);
4748
});
4849

49-
configuration_api.mount(U("/x-nmos/") + nmos::patterns::configuration_api.pattern + U("/") + nmos::patterns::version.pattern, make_unmounted_configuration_api(model, gate));
50+
configuration_api.mount(U("/x-nmos/") + nmos::patterns::configuration_api.pattern + U("/") + nmos::patterns::version.pattern, make_unmounted_configuration_api(model, get_control_protocol_class_descriptor, gate));
5051

5152
return configuration_api;
5253
}
@@ -120,7 +121,7 @@ namespace nmos
120121
}
121122
}
122123

123-
bool verify_role_path(const resources& resources, const nmos::resource& resource, std::list<utility::string_t>& role_path_segments)
124+
web::json::value get_nc_object(const resources& resources, const nmos::resource& resource, std::list<utility::string_t>& role_path_segments)
124125
{
125126
if (resource.data.has_field(nmos::fields::nc::members))
126127
{
@@ -130,16 +131,16 @@ namespace nmos
130131
role_path_segments.pop_front();
131132
// find the role_path_segment member
132133
auto member_found = std::find_if(members.begin(), members.end(), [&](const web::json::value& member)
133-
{
134-
return role_path_segement == nmos::fields::nc::role(member);
135-
});
134+
{
135+
return role_path_segement == nmos::fields::nc::role(member);
136+
});
136137

137138
if (members.end() != member_found)
138139
{
139140
if (role_path_segments.empty())
140141
{
141142
// role_path verified
142-
return true;
143+
return *member_found;
143144
}
144145

145146
// get the role_path_segement member resource
@@ -151,16 +152,16 @@ namespace nmos
151152
if (resources.end() != found)
152153
{
153154
// verify the reminding role_path_segments
154-
return verify_role_path(resources, *found, role_path_segments);
155+
return get_nc_object(resources, *found, role_path_segments);
155156
}
156157
}
157158
}
158159
}
159-
return false;
160+
return web::json::value().null();
160161
}
161162
}
162163

163-
inline web::http::experimental::listener::api_router make_unmounted_configuration_api(nmos::node_model& model, slog::base_gate& gate_)
164+
inline web::http::experimental::listener::api_router make_unmounted_configuration_api(nmos::node_model& model, get_control_protocol_class_descriptor_handler get_control_protocol_class_descriptor, slog::base_gate& gate_)
164165
{
165166
using namespace web::http::experimental::listener::api_router_using_declarations;
166167

@@ -221,7 +222,7 @@ namespace nmos
221222
{
222223
role_path_segments.pop_front();
223224

224-
result = role_path_segments.size() ? details::verify_role_path(resources, *resource, role_path_segments) : true;
225+
result = role_path_segments.size() ? !details::get_nc_object(resources, *resource, role_path_segments).is_null() : true;
225226
}
226227
}
227228

@@ -237,6 +238,66 @@ namespace nmos
237238
return pplx::task_from_result(true);
238239
});
239240

241+
configuration_api.support(U("/rolePaths/") + nmos::patterns::rolePath.pattern + U("/properties/?"), methods::GET, [&model, get_control_protocol_class_descriptor, &gate_](http_request req, http_response res, const string_t& route_path, const route_parameters& parameters)
242+
{
243+
const string_t role_path = parameters.at(nmos::patterns::rolePath.name);
244+
245+
// tokenize the role_path with the '.' delimiter
246+
std::list<utility::string_t> role_path_segments;
247+
boost::algorithm::split(role_path_segments, role_path, [](utility::char_t c) { return '.' == c; });
248+
249+
bool result{ false };
250+
std::set<utility::string_t> properties_routes;
251+
252+
auto lock = model.read_lock();
253+
auto& resources = model.control_protocol_resources;
254+
auto resource = nmos::find_resource(resources, utility::s2us(std::to_string(nmos::root_block_oid)));
255+
if (resources.end() != resource)
256+
{
257+
const auto role = nmos::fields::nc::role(resource->data);
258+
if (role_path_segments.size() && role == role_path_segments.front())
259+
{
260+
role_path_segments.pop_front();
261+
262+
auto nc_object = details::get_nc_object(resources, *resource, role_path_segments);
263+
264+
result = !nc_object.is_null();
265+
266+
if (result)
267+
{
268+
nc_class_id class_id = nmos::details::parse_nc_class_id(nmos::fields::nc::class_id(nc_object));
269+
270+
while (!class_id.empty())
271+
{
272+
const auto& control_class = get_control_protocol_class_descriptor(class_id);
273+
auto& property_descriptors = control_class.property_descriptors.as_array();
274+
275+
for (auto property_descriptor : property_descriptors)
276+
{
277+
auto property_id = nmos::fields::nc::id(property_descriptor);
278+
std::wostringstream property_id_str;
279+
property_id_str << nmos::fields::nc::level(property_id) << 'p' << nmos::fields::nc::index(property_id) << '/';
280+
properties_routes.insert(property_id_str.str());
281+
}
282+
283+
class_id.pop_back();
284+
}
285+
}
286+
}
287+
}
288+
289+
if (result)
290+
{
291+
set_reply(res, status_codes::OK, nmos::make_sub_routes_body(properties_routes, req, res));
292+
}
293+
else
294+
{
295+
set_error_reply(res, status_codes::NotFound, U("Not Found; ") + role_path);
296+
}
297+
298+
return pplx::task_from_result(true);
299+
});
300+
240301
return configuration_api;
241302
}
242303
}

Development/nmos/configuration_api.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define NMOS_CONFIGURATION_API_H
33

44
#include "cpprest/api_router.h"
5+
#include "nmos/control_protocol_handlers.h"
56

67
namespace slog
78
{
@@ -14,7 +15,7 @@ namespace nmos
1415
{
1516
struct node_model;
1617

17-
web::http::experimental::listener::api_router make_configuration_api(nmos::node_model& model, web::http::experimental::listener::route_handler validate_authorization, slog::base_gate& gate);
18+
web::http::experimental::listener::api_router make_configuration_api(nmos::node_model& model, web::http::experimental::listener::route_handler validate_authorization, get_control_protocol_class_descriptor_handler get_control_protocol_class_descriptor, slog::base_gate& gate);
1819
}
1920

2021
#endif

Development/nmos/node_server.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ namespace nmos
7777

7878
// Configure the Configuration API
7979

80-
node_server.api_routers[{ {}, nmos::fields::configuration_port(node_model.settings) }].mount({}, nmos::make_configuration_api(node_model, validate_authorization ? validate_authorization(nmos::experimental::scopes::configuration) : nullptr, gate));
80+
node_server.api_routers[{ {}, nmos::fields::configuration_port(node_model.settings) }].mount({}, nmos::make_configuration_api(node_model, validate_authorization ? validate_authorization(nmos::experimental::scopes::configuration) : nullptr, node_implementation.get_control_protocol_class_descriptor, gate));
8181

8282
const auto& events_ws_port = nmos::fields::events_ws_port(node_model.settings);
8383
auto& events_ws_api = node_server.ws_handlers[{ {}, nmos::fields::events_ws_port(node_model.settings) }];

0 commit comments

Comments
 (0)