Skip to content

Commit

Permalink
Rename Read/Write Node API to Annotation API
Browse files Browse the repository at this point in the history
  • Loading branch information
garethsb committed May 19, 2023
1 parent bf67e66 commit f1b4898
Show file tree
Hide file tree
Showing 19 changed files with 106 additions and 83 deletions.
7 changes: 4 additions & 3 deletions Development/cmake/NmosCppLibraries.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -695,11 +695,12 @@ set(NMOS_IS13_SCHEMAS_HEADERS
set(NMOS_IS13_V1_0_TAG v1.0-dev)

set(NMOS_IS13_V1_0_SCHEMAS_JSON
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/annotationapi-base.json
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/annotationapi-node-base.json
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/error.json
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/resource_core.json
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/resource_core_patch.json
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/resource_cores.json
third_party/is-13/${NMOS_IS13_V1_0_TAG}/APIs/schemas/rwnodeapi-base.json
)

set(NMOS_IS13_SCHEMAS_JSON_MATCH "third_party/is-13/([^/]+)/APIs/schemas/([^;]+)\\.json")
Expand Down Expand Up @@ -813,6 +814,7 @@ set(NMOS_CPP_CPPREST_DETAILS_HEADERS
set(NMOS_CPP_NMOS_SOURCES
nmos/activation_utils.cpp
nmos/admin_ui.cpp
nmos/annotation_api.cpp
nmos/api_downgrade.cpp
nmos/api_utils.cpp
nmos/capabilities.cpp
Expand Down Expand Up @@ -864,7 +866,6 @@ set(NMOS_CPP_NMOS_SOURCES
nmos/registry_server.cpp
nmos/resource.cpp
nmos/resources.cpp
nmos/rwnode_api.cpp
nmos/schemas_api.cpp
nmos/sdp_utils.cpp
nmos/server.cpp
Expand All @@ -879,6 +880,7 @@ set(NMOS_CPP_NMOS_HEADERS
nmos/activation_mode.h
nmos/activation_utils.h
nmos/admin_ui.h
nmos/annotation_api.h
nmos/api_downgrade.h
nmos/api_utils.h
nmos/api_version.h
Expand Down Expand Up @@ -958,7 +960,6 @@ set(NMOS_CPP_NMOS_HEADERS
nmos/registry_server.h
nmos/resource.h
nmos/resources.h
nmos/rwnode_api.h
nmos/schemas_api.h
nmos/sdp_utils.h
nmos/server.h
Expand Down
2 changes: 1 addition & 1 deletion Development/cmake/NmosCppTest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ set(NMOS_CPP_TEST_MDNS_TEST_HEADERS
)

set(NMOS_CPP_TEST_NMOS_TEST_SOURCES
nmos/test/annotation_api_test.cpp
nmos/test/api_utils_test.cpp
nmos/test/capabilities_test.cpp
nmos/test/channels_test.cpp
nmos/test/did_sdid_test.cpp
nmos/test/event_type_test.cpp
nmos/test/json_validator_test.cpp
nmos/test/paging_utils_test.cpp
nmos/test/rwnode_api_test.cpp
nmos/test/query_api_test.cpp
nmos/test/sdp_utils_test.cpp
nmos/test/system_resources_test.cpp
Expand Down
2 changes: 1 addition & 1 deletion Development/nmos-cpp-node/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
//"events_port": 3216,
//"events_ws_port": 3217,
//"channelmapping_port": 3215,
//"rwnode_port": 3212,
//"annotation_port": 3212,
// system_port [node]: used to construct request URLs for the System API (if not discovered via DNS-SD)
//"system_port": 10641,

Expand Down
6 changes: 3 additions & 3 deletions Development/nmos-cpp-node/node_implementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1270,13 +1270,13 @@ nmos::channelmapping_activation_handler make_node_implementation_channelmapping_
}

// Example Read/Write Node API patch callback to update resource labels, descriptions and tags
nmos::rwnode_patch_merger make_node_implementation_rwnode_patch_merger(slog::base_gate& gate)
nmos::annotation_patch_merger make_node_implementation_annotation_patch_merger(slog::base_gate& gate)
{
return [&gate](const nmos::resource& resource, web::json::value& value, const web::json::value& patch)
{
const std::pair<nmos::id, nmos::type> id_type{ resource.id, resource.type };
slog::log<slog::severities::info>(gate, SLOG_FLF) << nmos::stash_category(impl::categories::node_implementation) << "Updating " << id_type;
nmos::details::merge_rwnode_patch(value, patch);
nmos::details::merge_annotation_patch(value, patch);
};
}

Expand Down Expand Up @@ -1434,5 +1434,5 @@ nmos::experimental::node_implementation make_node_implementation(nmos::node_mode
.on_connection_activated(make_node_implementation_connection_activation_handler(model, gate))
.on_validate_channelmapping_output_map(make_node_implementation_map_validator()) // may be omitted if not required
.on_channelmapping_activated(make_node_implementation_channelmapping_activation_handler(gate))
.on_merge_rwnode_patch(make_node_implementation_rwnode_patch_merger(gate)); // may be omitted if not required
.on_merge_annotation_patch(make_node_implementation_annotation_patch_merger(gate)); // may be omitted if not required
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "nmos/rwnode_api.h"
#include "nmos/annotation_api.h"

#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/adaptor/filtered.hpp>
Expand All @@ -11,39 +11,39 @@

namespace nmos
{
web::http::experimental::listener::api_router make_unmounted_rwnode_api(nmos::model& model, nmos::rwnode_patch_merger merge_patch, slog::base_gate& gate);
web::http::experimental::listener::api_router make_unmounted_annotation_api(nmos::model& model, nmos::annotation_patch_merger merge_patch, slog::base_gate& gate);

web::http::experimental::listener::api_router make_rwnode_api(nmos::model& model, nmos::rwnode_patch_merger merge_patch, slog::base_gate& gate)
web::http::experimental::listener::api_router make_annotation_api(nmos::model& model, nmos::annotation_patch_merger merge_patch, slog::base_gate& gate)
{
using namespace web::http::experimental::listener::api_router_using_declarations;

api_router rwnode_api;
api_router annotation_api;

rwnode_api.support(U("/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
annotation_api.support(U("/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
{
set_reply(res, status_codes::OK, nmos::make_sub_routes_body({ U("x-nmos/") }, req, res));
return pplx::task_from_result(true);
});

rwnode_api.support(U("/x-nmos/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
annotation_api.support(U("/x-nmos/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
{
set_reply(res, status_codes::OK, nmos::make_sub_routes_body({ U("rwnode/") }, req, res));
set_reply(res, status_codes::OK, nmos::make_sub_routes_body({ U("annotation/") }, req, res));
return pplx::task_from_result(true);
});

const auto versions = with_read_lock(model.mutex, [&model] { return nmos::is13_versions::from_settings(model.settings); });
rwnode_api.support(U("/x-nmos/") + nmos::patterns::rwnode_api.pattern + U("/?"), methods::GET, [versions](http_request req, http_response res, const string_t&, const route_parameters&)
annotation_api.support(U("/x-nmos/") + nmos::patterns::annotation_api.pattern + U("/?"), methods::GET, [versions](http_request req, http_response res, const string_t&, const route_parameters&)
{
set_reply(res, status_codes::OK, nmos::make_sub_routes_body(nmos::make_api_version_sub_routes(versions), req, res));
return pplx::task_from_result(true);
});

rwnode_api.mount(U("/x-nmos/") + nmos::patterns::rwnode_api.pattern + U("/") + nmos::patterns::version.pattern, make_unmounted_rwnode_api(model, std::move(merge_patch), gate));
annotation_api.mount(U("/x-nmos/") + nmos::patterns::annotation_api.pattern + U("/") + nmos::patterns::version.pattern, make_unmounted_annotation_api(model, std::move(merge_patch), gate));

return rwnode_api;
return annotation_api;
}

web::json::value make_rwnode_patch(const nmos::resource& resource)
web::json::value make_annotation_patch(const nmos::resource& resource)
{
using web::json::value_of;
return value_of({
Expand All @@ -53,7 +53,7 @@ namespace nmos
});
}

web::json::value make_rwnode_response(const nmos::resource& resource)
web::json::value make_annotation_response(const nmos::resource& resource)
{
using web::json::value_of;
return value_of({
Expand All @@ -73,7 +73,7 @@ namespace nmos
|| boost::algorithm::starts_with(key, U("urn:x-nmos:tag:grouphint/"));
}

void merge_rwnode_patch(web::json::value& value, const web::json::value& patch)
void merge_annotation_patch(web::json::value& value, const web::json::value& patch)
{
// reject changes to read-ony tags

Expand Down Expand Up @@ -105,16 +105,16 @@ namespace nmos
web::json::insert(value, std::make_pair(nmos::fields::tags, readonly_tags));
}

void assign_rwnode_patch(web::json::value& value, web::json::value&& patch)
void assign_annotation_patch(web::json::value& value, web::json::value&& patch)
{
if (value.has_string_field(nmos::fields::label)) value[nmos::fields::label] = std::move(patch.at(nmos::fields::label));
if (value.has_string_field(nmos::fields::description)) value[nmos::fields::description] = std::move(patch.at(nmos::fields::description));
if (value.has_object_field(nmos::fields::tags)) value[nmos::fields::tags] = std::move(patch.at(nmos::fields::tags));
}

void handle_rwnode_patch(nmos::resources& resources, const nmos::resource& resource, const web::json::value& patch, const nmos::rwnode_patch_merger& merge_patch, slog::base_gate& gate)
void handle_annotation_patch(nmos::resources& resources, const nmos::resource& resource, const web::json::value& patch, const nmos::annotation_patch_merger& merge_patch, slog::base_gate& gate)
{
auto merged = nmos::make_rwnode_patch(resource);
auto merged = nmos::make_annotation_patch(resource);
try
{
if (merge_patch)
Expand All @@ -123,7 +123,7 @@ namespace nmos
}
else
{
nmos::merge_rwnode_patch(resource, merged, patch);
nmos::merge_annotation_patch(resource, merged, patch);
}
}
catch (const web::json::json_exception& e)
Expand All @@ -137,28 +137,34 @@ namespace nmos
modify_resource(resources, resource.id, [&merged](nmos::resource& resource)
{
resource.data[nmos::fields::version] = web::json::value::string(nmos::make_version());
details::assign_rwnode_patch(resource.data, std::move(merged));
details::assign_annotation_patch(resource.data, std::move(merged));
});
}
}

web::http::experimental::listener::api_router make_unmounted_rwnode_api(nmos::model& model, nmos::rwnode_patch_merger merge_patch, slog::base_gate& gate_)
web::http::experimental::listener::api_router make_unmounted_annotation_api(nmos::model& model, nmos::annotation_patch_merger merge_patch, slog::base_gate& gate_)
{
using namespace web::http::experimental::listener::api_router_using_declarations;

api_router rwnode_api;
api_router annotation_api;

// check for supported API version
const auto versions = with_read_lock(model.mutex, [&model] { return nmos::is13_versions::from_settings(model.settings); });
rwnode_api.support(U(".*"), details::make_api_version_handler(versions, gate_));
annotation_api.support(U(".*"), details::make_api_version_handler(versions, gate_));

rwnode_api.support(U("/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
annotation_api.support(U("/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
{
set_reply(res, status_codes::OK, nmos::make_sub_routes_body({ U("node/") }, req, res));
return pplx::task_from_result(true);
});

annotation_api.support(U("/node/?"), methods::GET, [](http_request req, http_response res, const string_t&, const route_parameters&)
{
set_reply(res, status_codes::OK, nmos::make_sub_routes_body({ U("self/"), U("devices/"), U("sources/"), U("flows/"), U("senders/"), U("receivers/") }, req, res));
return pplx::task_from_result(true);
});

rwnode_api.support(U("/self/?"), methods::GET, [&model, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
annotation_api.support(U("/node/self/?"), methods::GET, [&model, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
{
nmos::api_gate gate(gate_, req, parameters);
auto lock = model.read_lock();
Expand All @@ -168,7 +174,7 @@ namespace nmos
if (resources.end() != resource)
{
slog::log<slog::severities::more_info>(gate, SLOG_FLF) << "Returning self resource: " << resource->id;
set_reply(res, status_codes::OK, nmos::make_rwnode_response(*resource));
set_reply(res, status_codes::OK, nmos::make_annotation_response(*resource));
}
else
{
Expand All @@ -182,18 +188,18 @@ namespace nmos
const web::json::experimental::json_validator validator
{
nmos::experimental::load_json_schema,
boost::copy_range<std::vector<web::uri>>(versions | boost::adaptors::transformed(experimental::make_rwnodeapi_resource_core_patch_request_schema_uri))
boost::copy_range<std::vector<web::uri>>(versions | boost::adaptors::transformed(experimental::make_annotationapi_resource_core_patch_request_schema_uri))
};

rwnode_api.support(U("/self/?"), methods::PATCH, [&model, validator, merge_patch, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
annotation_api.support(U("/node/self/?"), methods::PATCH, [&model, validator, merge_patch, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
{
nmos::api_gate gate(gate_, req, parameters);

return details::extract_json(req, gate).then([&model, &validator, merge_patch, req, res, parameters, gate](value body) mutable
{
const nmos::api_version version = nmos::parse_api_version(parameters.at(nmos::patterns::version.name));

validator.validate(body, experimental::make_rwnodeapi_resource_core_patch_request_schema_uri(version));
validator.validate(body, experimental::make_annotationapi_resource_core_patch_request_schema_uri(version));

auto lock = model.write_lock();
auto& resources = model.node_resources;
Expand All @@ -203,9 +209,9 @@ namespace nmos
{
slog::log<slog::severities::more_info>(gate, SLOG_FLF) << "Patching self resource: " << resource->id;

details::handle_rwnode_patch(resources, *resource, body, merge_patch, gate);
details::handle_annotation_patch(resources, *resource, body, merge_patch, gate);

set_reply(res, status_codes::OK, nmos::make_rwnode_response(*resource));
set_reply(res, status_codes::OK, nmos::make_annotation_response(*resource));

model.notify();
}
Expand All @@ -219,7 +225,7 @@ namespace nmos
});
});

rwnode_api.support(U("/") + nmos::patterns::subresourceType.pattern + U("/?"), methods::GET, [&model, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
annotation_api.support(U("/node/") + nmos::patterns::subresourceType.pattern + U("/?"), methods::GET, [&model, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
{
nmos::api_gate gate(gate_, req, parameters);
auto lock = model.read_lock();
Expand All @@ -235,7 +241,7 @@ namespace nmos
web::json::serialize_array(resources
| boost::adaptors::filtered(match)
| boost::adaptors::transformed(
[&count](const nmos::resources::value_type& resource) { ++count; return nmos::make_rwnode_response(resource); }
[&count](const nmos::resources::value_type& resource) { ++count; return nmos::make_annotation_response(resource); }
)),
web::http::details::mime_types::application_json);

Expand All @@ -244,7 +250,7 @@ namespace nmos
return pplx::task_from_result(true);
});

rwnode_api.support(U("/") + nmos::patterns::subresourceType.pattern + U("/") + nmos::patterns::resourceId.pattern + U("/?"), methods::GET, [&model, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
annotation_api.support(U("/node/") + nmos::patterns::subresourceType.pattern + U("/") + nmos::patterns::resourceId.pattern + U("/?"), methods::GET, [&model, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
{
nmos::api_gate gate(gate_, req, parameters);
auto lock = model.read_lock();
Expand All @@ -258,7 +264,7 @@ namespace nmos
if (resources.end() != resource)
{
slog::log<slog::severities::more_info>(gate, SLOG_FLF) << "Returning " << id_type;
set_reply(res, status_codes::OK, nmos::make_rwnode_response(*resource));
set_reply(res, status_codes::OK, nmos::make_annotation_response(*resource));
}
else
{
Expand All @@ -268,15 +274,15 @@ namespace nmos
return pplx::task_from_result(true);
});

rwnode_api.support(U("/") + nmos::patterns::subresourceType.pattern + U("/") + nmos::patterns::resourceId.pattern + U("/?"), methods::PATCH, [&model, validator, merge_patch, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
annotation_api.support(U("/node/") + nmos::patterns::subresourceType.pattern + U("/") + nmos::patterns::resourceId.pattern + U("/?"), methods::PATCH, [&model, validator, merge_patch, &gate_](http_request req, http_response res, const string_t&, const route_parameters& parameters)
{
nmos::api_gate gate(gate_, req, parameters);

return details::extract_json(req, gate).then([&model, &validator, merge_patch, req, res, parameters, gate](value body) mutable
{
const nmos::api_version version = nmos::parse_api_version(parameters.at(nmos::patterns::version.name));

validator.validate(body, experimental::make_rwnodeapi_resource_core_patch_request_schema_uri(version));
validator.validate(body, experimental::make_annotationapi_resource_core_patch_request_schema_uri(version));

auto lock = model.write_lock();
auto& resources = model.node_resources;
Expand All @@ -290,9 +296,9 @@ namespace nmos
{
slog::log<slog::severities::more_info>(gate, SLOG_FLF) << "Patching " << id_type;

details::handle_rwnode_patch(resources, *resource, body, merge_patch, gate);
details::handle_annotation_patch(resources, *resource, body, merge_patch, gate);

set_reply(res, status_codes::OK, nmos::make_rwnode_response(*resource));
set_reply(res, status_codes::OK, nmos::make_annotation_response(*resource));

model.notify();
}
Expand All @@ -305,6 +311,6 @@ namespace nmos
});
});

return rwnode_api;
return annotation_api;
}
}
Loading

0 comments on commit f1b4898

Please sign in to comment.