diff options
author | Willy Tu <wltu@google.com> | 2023-05-23 20:58:39 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2023-06-12 18:33:22 +0300 |
commit | 32cdb4a78399fec17442dc2cd36b2e57382475a3 (patch) | |
tree | 8f0c963ca453ee1a5e3808a23d338d527d583c96 /redfish-core | |
parent | 994fd86a3f6649a820f66313765e85e762ad105a (diff) | |
download | bmcweb-32cdb4a78399fec17442dc2cd36b2e57382475a3.tar.xz |
query: Fix default expand level with delegated
With delegate expand, the default expand level is -=
`queryCapabilities.canDelegateExpandLevel`. This creates an overlap of
expand process between delegate expand vs. default expand.
With
query.expandLevel = 2 ->
query.expandLevel = 1 and delegated.expandLevel = 1.
Both delegated and default expand will try to only expand of level one
instead of level 2 for the default.
The code in
https://github.com/openbmc/bmcweb/blob/479e899d5f57a67647f83b7f615d2c8565290bcf/redfish-core/include/utils/query_param.hpp#L583-L597
stated that the level with "@odata.id" + other property is treated as a
seperate level. So with `query.expandLevel = 1` it just loop through the
id that was already expanded and is noop.
Tested:
Before:
/redfish/v1/Chassis/BMC/Sensors?$expand=.($levels=2) returns
the same result as level=1. Needs level=3 to expand to the next level.
The RelatedItem in here doesn't get expanded with level=2.
```
wget -qO- 'http://localhost:80/redfish/v1/Chassis/BMC/Sensors?$expand=.($levels=1)'
...
{
"@odata.id": "/redfish/v1/Chassis/BMC/Sensors/temperature_DIMMXX",
"@odata.type": "#Sensor.v1_2_0.Sensor",
"Id": "temperature_DIMMXX",
"Name": "DIMMXX",
"Reading": 30.0,
"ReadingRangeMax": 127.0,
"ReadingRangeMin": -128.0,
"ReadingType": "Temperature",
"ReadingUnits": "Cel",
"RelatedItem": [
{
"@odata.id": "/redfish/v1/Systems/system/Memory/dimmXX"
}
],
"Status": {
"Health": "OK",
"State": "Enabled"
},
"Thresholds": {
"LowerCaution": {
"Reading": null
},
"LowerCritical": {
"Reading": null
},
"UpperCaution": {
"Reading": 93.0
},
"UpperCritical": {
"Reading": 95.0
}
}
}
],
"Members@odata.count": 242,
"Name": "Sensors"
}
```
After:
level=2 was able to expand to the next level.
Change-Id: I542177a94a33f8df7afbb68837f3a53b86140c86
Signed-off-by: Willy Tu <wltu@google.com>
Diffstat (limited to 'redfish-core')
-rw-r--r-- | redfish-core/include/query.hpp | 6 | ||||
-rw-r--r-- | redfish-core/include/utils/query_param.hpp | 48 |
2 files changed, 35 insertions, 19 deletions
diff --git a/redfish-core/include/query.hpp b/redfish-core/include/query.hpp index 10a337b96b..c1ca38e957 100644 --- a/redfish-core/include/query.hpp +++ b/redfish-core/include/query.hpp @@ -166,9 +166,9 @@ inline bool handleIfMatch(crow::App& app, const crow::Request& req, asyncResp->res.releaseCompleteRequestHandler(); asyncResp->res.setCompleteRequestHandler( - [&app, handler(std::move(handler)), - query{std::move(*queryOpt)}](crow::Response& resIn) mutable { - processAllParams(app, query, handler, resIn); + [&app, handler(std::move(handler)), query{std::move(*queryOpt)}, + delegated{delegated}](crow::Response& resIn) mutable { + processAllParams(app, query, delegated, handler, resIn); }); return needToCallHandlers; diff --git a/redfish-core/include/utils/query_param.hpp b/redfish-core/include/utils/query_param.hpp index 71fcbd7e05..e5402d50e3 100644 --- a/redfish-core/include/utils/query_param.hpp +++ b/redfish-core/include/utils/query_param.hpp @@ -221,7 +221,6 @@ inline Query delegate(const QueryCapabilities& queryCapabilities, Query& query) } else { - query.expandLevel -= queryCapabilities.canDelegateExpandLevel; delegated.expandLevel = queryCapabilities.canDelegateExpandLevel; } } @@ -534,8 +533,8 @@ struct ExpandNode // with the keys from the jsonResponse object inline void findNavigationReferencesRecursive( ExpandType eType, nlohmann::json& jsonResponse, - const nlohmann::json::json_pointer& p, int depth, bool inLinks, - std::vector<ExpandNode>& out) + const nlohmann::json::json_pointer& p, int depth, int skipDepth, + bool inLinks, std::vector<ExpandNode>& out) { // If no expand is needed, return early if (eType == ExpandType::None) @@ -554,7 +553,7 @@ inline void findNavigationReferencesRecursive( nlohmann::json::json_pointer newPtr = p / index; BMCWEB_LOG_DEBUG << "Traversing response at " << newPtr.to_string(); findNavigationReferencesRecursive(eType, element, newPtr, depth, - inLinks, out); + skipDepth, inLinks, out); index++; } } @@ -574,7 +573,10 @@ inline void findNavigationReferencesRecursive( if (uri != nullptr) { BMCWEB_LOG_DEBUG << "Found " << *uri << " at " << p.to_string(); - out.push_back({p, *uri}); + if (skipDepth == 0) + { + out.push_back({p, *uri}); + } return; } } @@ -589,11 +591,22 @@ inline void findNavigationReferencesRecursive( // "@odata.id" then that means we have entered a new level / expanded // resource. We need to stop traversing if we're already at the desired // depth - if ((obj->size() > 1) && (depth == 0)) + if (obj->size() > 1) { - return; + if (depth == 0) + { + return; + } + if (skipDepth > 0) + { + skipDepth--; + } + } + + if (skipDepth == 0) + { + newDepth--; } - newDepth--; } // Loop the object and look for links @@ -619,7 +632,8 @@ inline void findNavigationReferencesRecursive( BMCWEB_LOG_DEBUG << "Traversing response at " << newPtr; findNavigationReferencesRecursive(eType, element.second, newPtr, - newDepth, localInLinks, out); + newDepth, skipDepth, localInLinks, + out); } } @@ -630,13 +644,14 @@ inline void findNavigationReferencesRecursive( // lands. May want to avoid forwarding query params when request is uptree from // a top level collection. inline std::vector<ExpandNode> - findNavigationReferences(ExpandType eType, int depth, + findNavigationReferences(ExpandType eType, int depth, int skipDepth, nlohmann::json& jsonResponse) { std::vector<ExpandNode> ret; const nlohmann::json::json_pointer root = nlohmann::json::json_pointer(""); - findNavigationReferencesRecursive(eType, jsonResponse, root, depth, false, - ret); + // SkipDepth +1 since we are skipping the root by default. + findNavigationReferencesRecursive(eType, jsonResponse, root, depth, + skipDepth + 1, false, ret); return ret; } @@ -795,10 +810,11 @@ class MultiAsyncResp : public std::enable_shared_from_this<MultiAsyncResp> // Handles the very first level of Expand, and starts a chain of sub-queries // for deeper levels. - void startQuery(const Query& query) + void startQuery(const Query& query, const Query& delegated) { std::vector<ExpandNode> nodes = findNavigationReferences( - query.expandType, query.expandLevel, finalRes->res.jsonValue); + query.expandType, query.expandLevel, delegated.expandLevel, + finalRes->res.jsonValue); BMCWEB_LOG_DEBUG << nodes.size() << " nodes to traverse"; const std::optional<std::string> queryStr = formatQueryForExpand(query); if (!queryStr) @@ -960,7 +976,7 @@ inline void processSelect(crow::Response& intermediateResponse, } inline void - processAllParams(crow::App& app, const Query& query, + processAllParams(crow::App& app, const Query& query, const Query& delegated, std::function<void(crow::Response&)>& completionHandler, crow::Response& intermediateResponse) { @@ -998,7 +1014,7 @@ inline void asyncResp->res.setCompleteRequestHandler(std::move(completionHandler)); auto multi = std::make_shared<MultiAsyncResp>(app, asyncResp); - multi->startQuery(query); + multi->startQuery(query, delegated); return; } |