Skip to content

Commit

Permalink
polycubed: fix issue with lists and default elements (#118)
Browse files Browse the repository at this point in the history
The logic to set default elements in a list was broken as it was trying
to fill the elements as if the list were a container.

This commit reworks the logic to fill default elements, in a list they
are filled only if there are children in the request.

Signed-off-by: Mauricio Vasquez B <mauriciovasquezbernal@gmail.com>
  • Loading branch information
mauriciovasquezbernal authored and frisso committed Apr 27, 2019
1 parent 9bb2ce7 commit b813c67
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 28 deletions.
24 changes: 0 additions & 24 deletions src/polycubed/src/server/Resources/Body/ListResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,6 @@ const Response ListResource::ReadWhole(const std::string &cube_name,
return ParentResource::ReadValue(cube_name, keys);
}

void ListResource::SetDefaultIfMissing(nlohmann::json &body) const {
// keys default values must be ignored (RFC7950#7.8.2)
std::set<std::string> key_names;
for (const auto &key : keys_) {
key_names.emplace(key.Name());
}

for (const auto &child : children_) {
// Set default only for configuration nodes. During initialization
// all non-keys can be defaulted, otherwise only the ones that are not
// marked as init-only-config.
if (key_names.count(child->Name()) == 0 && child->IsConfiguration() &&
!child->IsInitOnlyConfig()) {
child->SetDefaultIfMissing(body[child->Name()]);
if (body[child->Name()].empty()) {
body.erase(child->Name());
}
}
}
}

void ListResource::FillKeys(nlohmann::json &body, const ListKeyValues &keys) {
// TODO: is there a more efficient implementation of this?
for (auto &key : keys_) {
Expand Down Expand Up @@ -167,9 +146,6 @@ std::vector<Response> ListResource::BodyValidateMultiple(
}

for (auto &elem : jbody) {
if (initialization) {
SetDefaultIfMissing(elem);
}
auto body = BodyValidate(cube_name, keys, elem, initialization);
errors.reserve(errors.size() + body.size());
std::copy(std::begin(body), std::end(body), std::back_inserter(errors));
Expand Down
2 changes: 0 additions & 2 deletions src/polycubed/src/server/Resources/Body/ListResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ class ListResource : public virtual ParentResource {

bool IsMandatory() const override;

void SetDefaultIfMissing(nlohmann::json &body) const final;

/*
* This function takes the keys (parsed from the url in "keys") and save
* them in the body of the request
Expand Down
12 changes: 10 additions & 2 deletions src/polycubed/src/server/Resources/Body/ParentResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,21 @@ bool ParentResource::IsConfiguration() const {

void ParentResource::SetDefaultIfMissing(nlohmann::json &body) const {
for (const auto &child : children_) {
// keys default values must be ignored (RFC7950#7.8.2)
if (child->IsKey()) {
continue;
}

auto &child_body = body[child->Name()];
// Lists can't be defaulted. The only possible this is if a list
// Lists can't be defaulted. The only possible case is if a list
// (as json array) is provided in request body. In this situation
// each element of the array can be defaulted.
if (std::dynamic_pointer_cast<ListResource>(child) != nullptr) {
if (!child_body.empty()) {
if (child_body.is_array()) {
for (auto &entry : child_body) {
if (child->IsKey()) {
continue;
}
child->SetDefaultIfMissing(entry);
}
}
Expand Down

0 comments on commit b813c67

Please sign in to comment.