177dd8813SKowalski, Kamil /* 277dd8813SKowalski, Kamil // Copyright (c) 2018 Intel Corporation 377dd8813SKowalski, Kamil // 477dd8813SKowalski, Kamil // Licensed under the Apache License, Version 2.0 (the "License"); 577dd8813SKowalski, Kamil // you may not use this file except in compliance with the License. 677dd8813SKowalski, Kamil // You may obtain a copy of the License at 777dd8813SKowalski, Kamil // 877dd8813SKowalski, Kamil // http://www.apache.org/licenses/LICENSE-2.0 977dd8813SKowalski, Kamil // 1077dd8813SKowalski, Kamil // Unless required by applicable law or agreed to in writing, software 1177dd8813SKowalski, Kamil // distributed under the License is distributed on an "AS IS" BASIS, 1277dd8813SKowalski, Kamil // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1377dd8813SKowalski, Kamil // See the License for the specific language governing permissions and 1477dd8813SKowalski, Kamil // limitations under the License. 1577dd8813SKowalski, Kamil */ 1677dd8813SKowalski, Kamil #pragma once 179712f8acSEd Tanous 189712f8acSEd Tanous #include <error_messages.hpp> 1904e438cbSEd Tanous #include <http_request.hpp> 2004e438cbSEd Tanous #include <http_response.hpp> 211abe55efSEd Tanous #include <nlohmann/json.hpp> 220627a2c7SEd Tanous 231214b7e7SGunnar Mills #include <bitset> 241214b7e7SGunnar Mills 251abe55efSEd Tanous namespace redfish 261abe55efSEd Tanous { 271abe55efSEd Tanous 281abe55efSEd Tanous namespace json_util 291abe55efSEd Tanous { 3077dd8813SKowalski, Kamil 3177dd8813SKowalski, Kamil /** 3277dd8813SKowalski, Kamil * @brief Processes request to extract JSON from its body. If it fails, adds 3377dd8813SKowalski, Kamil * MalformedJSON message to response and ends it. 3477dd8813SKowalski, Kamil * 3577dd8813SKowalski, Kamil * @param[io] res Response object 3677dd8813SKowalski, Kamil * @param[in] req Request object 3777dd8813SKowalski, Kamil * @param[out] reqJson JSON object extracted from request's body 3877dd8813SKowalski, Kamil * 3977dd8813SKowalski, Kamil * @return true if JSON is valid, false when JSON is invalid and response has 4077dd8813SKowalski, Kamil * been filled with message and ended. 4177dd8813SKowalski, Kamil */ 4255c7b7a2SEd Tanous bool processJsonFromRequest(crow::Response& res, const crow::Request& req, 4377dd8813SKowalski, Kamil nlohmann::json& reqJson); 449712f8acSEd Tanous namespace details 459712f8acSEd Tanous { 46771cfa0fSJason M. Bills 471214b7e7SGunnar Mills template <typename Type> 482c70f800SEd Tanous struct IsOptional : std::false_type 491214b7e7SGunnar Mills {}; 509712f8acSEd Tanous 51771cfa0fSJason M. Bills template <typename Type> 522c70f800SEd Tanous struct IsOptional<std::optional<Type>> : std::true_type 531214b7e7SGunnar Mills {}; 549712f8acSEd Tanous 55771cfa0fSJason M. Bills template <typename Type> 562c70f800SEd Tanous struct IsVector : std::false_type 571214b7e7SGunnar Mills {}; 58b1556427SEd Tanous 591214b7e7SGunnar Mills template <typename Type> 602c70f800SEd Tanous struct IsVector<std::vector<Type>> : std::true_type 611214b7e7SGunnar Mills {}; 62b1556427SEd Tanous 631214b7e7SGunnar Mills template <typename Type> 642c70f800SEd Tanous struct IsStdArray : std::false_type 651214b7e7SGunnar Mills {}; 66318226c2SJames Feist 67318226c2SJames Feist template <typename Type, std::size_t size> 682c70f800SEd Tanous struct IsStdArray<std::array<Type, size>> : std::true_type 691214b7e7SGunnar Mills {}; 70318226c2SJames Feist 71471a5eb8SAppaRao Puli enum class UnpackErrorCode 72471a5eb8SAppaRao Puli { 73471a5eb8SAppaRao Puli success, 74471a5eb8SAppaRao Puli invalidType, 75471a5eb8SAppaRao Puli outOfRange 76471a5eb8SAppaRao Puli }; 77471a5eb8SAppaRao Puli 78a6acbb31SJames Feist template <typename ToType, typename FromType> 79cb13a392SEd Tanous bool checkRange(const FromType& from, const std::string& key) 80a6acbb31SJames Feist { 81ee344e0fSEd Tanous if (from > std::numeric_limits<ToType>::max()) 82a6acbb31SJames Feist { 83a6acbb31SJames Feist BMCWEB_LOG_DEBUG << "Value for key " << key 84a6acbb31SJames Feist << " was greater than max: " << __PRETTY_FUNCTION__; 85a6acbb31SJames Feist return false; 86a6acbb31SJames Feist } 87ee344e0fSEd Tanous if (from < std::numeric_limits<ToType>::lowest()) 88a6acbb31SJames Feist { 89a6acbb31SJames Feist BMCWEB_LOG_DEBUG << "Value for key " << key 90a6acbb31SJames Feist << " was less than min: " << __PRETTY_FUNCTION__; 91a6acbb31SJames Feist return false; 92a6acbb31SJames Feist } 93a6acbb31SJames Feist if constexpr (std::is_floating_point_v<ToType>) 94a6acbb31SJames Feist { 95ee344e0fSEd Tanous if (std::isnan(from)) 96a6acbb31SJames Feist { 97a6acbb31SJames Feist BMCWEB_LOG_DEBUG << "Value for key " << key << " was NAN"; 98a6acbb31SJames Feist return false; 99a6acbb31SJames Feist } 100a6acbb31SJames Feist } 101a6acbb31SJames Feist 102a6acbb31SJames Feist return true; 103a6acbb31SJames Feist } 104a6acbb31SJames Feist 105771cfa0fSJason M. Bills template <typename Type> 106471a5eb8SAppaRao Puli UnpackErrorCode unpackValueWithErrorCode(nlohmann::json& jsonValue, 107471a5eb8SAppaRao Puli const std::string& key, Type& value) 108771cfa0fSJason M. Bills { 109471a5eb8SAppaRao Puli UnpackErrorCode ret = UnpackErrorCode::success; 11041352c24SSantosh Puranik 111a6acbb31SJames Feist if constexpr (std::is_floating_point_v<Type>) 112771cfa0fSJason M. Bills { 113a6acbb31SJames Feist double helper = 0; 114a6acbb31SJames Feist double* jsonPtr = jsonValue.get_ptr<double*>(); 115771cfa0fSJason M. Bills 116771cfa0fSJason M. Bills if (jsonPtr == nullptr) 117771cfa0fSJason M. Bills { 118a6acbb31SJames Feist int64_t* intPtr = jsonValue.get_ptr<int64_t*>(); 119a6acbb31SJames Feist if (intPtr != nullptr) 120771cfa0fSJason M. Bills { 121a6acbb31SJames Feist helper = static_cast<double>(*intPtr); 122a6acbb31SJames Feist jsonPtr = &helper; 123771cfa0fSJason M. Bills } 124a6acbb31SJames Feist } 1255eb2bef2SAppaRao Puli if (jsonPtr == nullptr) 1265eb2bef2SAppaRao Puli { 127471a5eb8SAppaRao Puli return UnpackErrorCode::invalidType; 1285eb2bef2SAppaRao Puli } 129cb13a392SEd Tanous if (!checkRange<Type>(*jsonPtr, key)) 130771cfa0fSJason M. Bills { 131471a5eb8SAppaRao Puli return UnpackErrorCode::outOfRange; 132771cfa0fSJason M. Bills } 133771cfa0fSJason M. Bills value = static_cast<Type>(*jsonPtr); 134771cfa0fSJason M. Bills } 135a6acbb31SJames Feist 136a6acbb31SJames Feist else if constexpr (std::is_signed_v<Type>) 137a6acbb31SJames Feist { 138a6acbb31SJames Feist int64_t* jsonPtr = jsonValue.get_ptr<int64_t*>(); 139271584abSEd Tanous if (jsonPtr == nullptr) 140271584abSEd Tanous { 141471a5eb8SAppaRao Puli return UnpackErrorCode::invalidType; 142271584abSEd Tanous } 143cb13a392SEd Tanous if (!checkRange<Type>(*jsonPtr, key)) 144a6acbb31SJames Feist { 145471a5eb8SAppaRao Puli return UnpackErrorCode::outOfRange; 146a6acbb31SJames Feist } 147a6acbb31SJames Feist value = static_cast<Type>(*jsonPtr); 148a6acbb31SJames Feist } 149a6acbb31SJames Feist 1508102ddbaSAppaRao Puli else if constexpr ((std::is_unsigned_v<Type>)&&( 1518102ddbaSAppaRao Puli !std::is_same_v<bool, Type>)) 152a6acbb31SJames Feist { 153a6acbb31SJames Feist uint64_t* jsonPtr = jsonValue.get_ptr<uint64_t*>(); 154271584abSEd Tanous if (jsonPtr == nullptr) 155271584abSEd Tanous { 156471a5eb8SAppaRao Puli return UnpackErrorCode::invalidType; 157271584abSEd Tanous } 158cb13a392SEd Tanous if (!checkRange<Type>(*jsonPtr, key)) 159a6acbb31SJames Feist { 160471a5eb8SAppaRao Puli return UnpackErrorCode::outOfRange; 161a6acbb31SJames Feist } 162a6acbb31SJames Feist value = static_cast<Type>(*jsonPtr); 163a6acbb31SJames Feist } 164a6acbb31SJames Feist 1650627a2c7SEd Tanous else if constexpr (std::is_same_v<nlohmann::json, Type>) 1660627a2c7SEd Tanous { 1670627a2c7SEd Tanous // Must be a complex type. Simple types (int string etc) should be 1680627a2c7SEd Tanous // unpacked directly 1698ebc91f6SEd Tanous if (!jsonValue.is_object() && !jsonValue.is_array() && 1708ebc91f6SEd Tanous !jsonValue.is_null()) 1710627a2c7SEd Tanous { 172471a5eb8SAppaRao Puli return UnpackErrorCode::invalidType; 1730627a2c7SEd Tanous } 1740627a2c7SEd Tanous 1750627a2c7SEd Tanous value = std::move(jsonValue); 1760627a2c7SEd Tanous } 177471a5eb8SAppaRao Puli else 178471a5eb8SAppaRao Puli { 179471a5eb8SAppaRao Puli using JsonType = std::add_const_t<std::add_pointer_t<Type>>; 180471a5eb8SAppaRao Puli JsonType jsonPtr = jsonValue.get_ptr<JsonType>(); 181471a5eb8SAppaRao Puli if (jsonPtr == nullptr) 182471a5eb8SAppaRao Puli { 183471a5eb8SAppaRao Puli BMCWEB_LOG_DEBUG 184471a5eb8SAppaRao Puli << "Value for key " << key 185471a5eb8SAppaRao Puli << " was incorrect type: " << jsonValue.type_name(); 186471a5eb8SAppaRao Puli return UnpackErrorCode::invalidType; 187471a5eb8SAppaRao Puli } 188471a5eb8SAppaRao Puli value = std::move(*jsonPtr); 189471a5eb8SAppaRao Puli } 190471a5eb8SAppaRao Puli return ret; 191471a5eb8SAppaRao Puli } 192471a5eb8SAppaRao Puli 193471a5eb8SAppaRao Puli template <typename Type> 194471a5eb8SAppaRao Puli bool unpackValue(nlohmann::json& jsonValue, const std::string& key, 195471a5eb8SAppaRao Puli crow::Response& res, Type& value) 196471a5eb8SAppaRao Puli { 197471a5eb8SAppaRao Puli bool ret = true; 198471a5eb8SAppaRao Puli 1992c70f800SEd Tanous if constexpr (IsOptional<Type>::value) 200471a5eb8SAppaRao Puli { 201471a5eb8SAppaRao Puli value.emplace(); 202471a5eb8SAppaRao Puli ret = unpackValue<typename Type::value_type>(jsonValue, key, res, 203471a5eb8SAppaRao Puli *value) && 204471a5eb8SAppaRao Puli ret; 205471a5eb8SAppaRao Puli } 2062c70f800SEd Tanous else if constexpr (IsStdArray<Type>::value) 207318226c2SJames Feist { 208318226c2SJames Feist if (!jsonValue.is_array()) 209318226c2SJames Feist { 21071f52d96SEd Tanous messages::propertyValueTypeError( 21171f52d96SEd Tanous res, 21271f52d96SEd Tanous res.jsonValue.dump(2, ' ', true, 21371f52d96SEd Tanous nlohmann::json::error_handler_t::replace), 21471f52d96SEd Tanous key); 21541352c24SSantosh Puranik return false; 216318226c2SJames Feist } 217318226c2SJames Feist if (jsonValue.size() != value.size()) 218318226c2SJames Feist { 21971f52d96SEd Tanous messages::propertyValueTypeError( 22071f52d96SEd Tanous res, 22171f52d96SEd Tanous res.jsonValue.dump(2, ' ', true, 22271f52d96SEd Tanous nlohmann::json::error_handler_t::replace), 22371f52d96SEd Tanous key); 22441352c24SSantosh Puranik return false; 225318226c2SJames Feist } 226318226c2SJames Feist size_t index = 0; 227318226c2SJames Feist for (const auto& val : jsonValue.items()) 228318226c2SJames Feist { 22941352c24SSantosh Puranik ret = unpackValue<typename Type::value_type>(val.value(), key, res, 23041352c24SSantosh Puranik value[index++]) && 23141352c24SSantosh Puranik ret; 232318226c2SJames Feist } 233318226c2SJames Feist } 2342c70f800SEd Tanous else if constexpr (IsVector<Type>::value) 235b1556427SEd Tanous { 236b1556427SEd Tanous if (!jsonValue.is_array()) 237b1556427SEd Tanous { 23871f52d96SEd Tanous messages::propertyValueTypeError( 23971f52d96SEd Tanous res, 24071f52d96SEd Tanous res.jsonValue.dump(2, ' ', true, 24171f52d96SEd Tanous nlohmann::json::error_handler_t::replace), 24271f52d96SEd Tanous key); 24341352c24SSantosh Puranik return false; 244b1556427SEd Tanous } 245b1556427SEd Tanous 246b1556427SEd Tanous for (const auto& val : jsonValue.items()) 247b1556427SEd Tanous { 248b1556427SEd Tanous value.emplace_back(); 24941352c24SSantosh Puranik ret = unpackValue<typename Type::value_type>(val.value(), key, res, 25041352c24SSantosh Puranik value.back()) && 25141352c24SSantosh Puranik ret; 252b1556427SEd Tanous } 253b1556427SEd Tanous } 254771cfa0fSJason M. Bills else 255771cfa0fSJason M. Bills { 256471a5eb8SAppaRao Puli UnpackErrorCode ec = unpackValueWithErrorCode(jsonValue, key, value); 257471a5eb8SAppaRao Puli if (ec != UnpackErrorCode::success) 258771cfa0fSJason M. Bills { 259471a5eb8SAppaRao Puli if (ec == UnpackErrorCode::invalidType) 260471a5eb8SAppaRao Puli { 26171f52d96SEd Tanous messages::propertyValueTypeError( 26271f52d96SEd Tanous res, 26371f52d96SEd Tanous jsonValue.dump(2, ' ', true, 26471f52d96SEd Tanous nlohmann::json::error_handler_t::replace), 26571f52d96SEd Tanous key); 266471a5eb8SAppaRao Puli } 267471a5eb8SAppaRao Puli else if (ec == UnpackErrorCode::outOfRange) 268471a5eb8SAppaRao Puli { 26971f52d96SEd Tanous messages::propertyValueNotInList( 27071f52d96SEd Tanous res, 27171f52d96SEd Tanous jsonValue.dump(2, ' ', true, 27271f52d96SEd Tanous nlohmann::json::error_handler_t::replace), 27371f52d96SEd Tanous key); 274471a5eb8SAppaRao Puli } 27541352c24SSantosh Puranik return false; 276771cfa0fSJason M. Bills } 277771cfa0fSJason M. Bills } 278471a5eb8SAppaRao Puli 279471a5eb8SAppaRao Puli return ret; 280471a5eb8SAppaRao Puli } 281471a5eb8SAppaRao Puli 282471a5eb8SAppaRao Puli template <typename Type> 283471a5eb8SAppaRao Puli bool unpackValue(nlohmann::json& jsonValue, const std::string& key, Type& value) 284471a5eb8SAppaRao Puli { 285471a5eb8SAppaRao Puli bool ret = true; 2862c70f800SEd Tanous if constexpr (IsOptional<Type>::value) 287471a5eb8SAppaRao Puli { 288471a5eb8SAppaRao Puli value.emplace(); 289471a5eb8SAppaRao Puli ret = unpackValue<typename Type::value_type>(jsonValue, key, *value) && 290471a5eb8SAppaRao Puli ret; 291471a5eb8SAppaRao Puli } 2922c70f800SEd Tanous else if constexpr (IsStdArray<Type>::value) 293471a5eb8SAppaRao Puli { 294471a5eb8SAppaRao Puli if (!jsonValue.is_array()) 295471a5eb8SAppaRao Puli { 296471a5eb8SAppaRao Puli return false; 297471a5eb8SAppaRao Puli } 298471a5eb8SAppaRao Puli if (jsonValue.size() != value.size()) 299471a5eb8SAppaRao Puli { 300471a5eb8SAppaRao Puli return false; 301471a5eb8SAppaRao Puli } 302471a5eb8SAppaRao Puli size_t index = 0; 303471a5eb8SAppaRao Puli for (const auto& val : jsonValue.items()) 304471a5eb8SAppaRao Puli { 305471a5eb8SAppaRao Puli ret = unpackValue<typename Type::value_type>(val.value(), key, 306471a5eb8SAppaRao Puli value[index++]) && 307471a5eb8SAppaRao Puli ret; 308471a5eb8SAppaRao Puli } 309471a5eb8SAppaRao Puli } 3102c70f800SEd Tanous else if constexpr (IsVector<Type>::value) 311471a5eb8SAppaRao Puli { 312471a5eb8SAppaRao Puli if (!jsonValue.is_array()) 313471a5eb8SAppaRao Puli { 314471a5eb8SAppaRao Puli return false; 315471a5eb8SAppaRao Puli } 316471a5eb8SAppaRao Puli 317471a5eb8SAppaRao Puli for (const auto& val : jsonValue.items()) 318471a5eb8SAppaRao Puli { 319471a5eb8SAppaRao Puli value.emplace_back(); 320471a5eb8SAppaRao Puli ret = unpackValue<typename Type::value_type>(val.value(), key, 321471a5eb8SAppaRao Puli value.back()) && 322471a5eb8SAppaRao Puli ret; 323471a5eb8SAppaRao Puli } 324471a5eb8SAppaRao Puli } 325471a5eb8SAppaRao Puli else 326471a5eb8SAppaRao Puli { 327471a5eb8SAppaRao Puli UnpackErrorCode ec = unpackValueWithErrorCode(jsonValue, key, value); 328471a5eb8SAppaRao Puli if (ec != UnpackErrorCode::success) 329471a5eb8SAppaRao Puli { 330471a5eb8SAppaRao Puli return false; 331471a5eb8SAppaRao Puli } 332471a5eb8SAppaRao Puli } 333471a5eb8SAppaRao Puli 33441352c24SSantosh Puranik return ret; 335771cfa0fSJason M. Bills } 336771cfa0fSJason M. Bills 3379712f8acSEd Tanous template <size_t Count, size_t Index> 338*104f09c9SEd Tanous bool readJsonValues(const std::string& key, nlohmann::json& /*jsonValue*/, 339*104f09c9SEd Tanous crow::Response& res, std::bitset<Count>& /*handled*/) 3409712f8acSEd Tanous { 3419712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Unable to find variable for key" << key; 342a08b46ccSJason M. Bills messages::propertyUnknown(res, key); 34341352c24SSantosh Puranik return false; 3449712f8acSEd Tanous } 3459712f8acSEd Tanous 3469712f8acSEd Tanous template <size_t Count, size_t Index, typename ValueType, 3479712f8acSEd Tanous typename... UnpackTypes> 34841352c24SSantosh Puranik bool readJsonValues(const std::string& key, nlohmann::json& jsonValue, 3499712f8acSEd Tanous crow::Response& res, std::bitset<Count>& handled, 3509712f8acSEd Tanous const char* keyToCheck, ValueType& valueToFill, 3519712f8acSEd Tanous UnpackTypes&... in) 3529712f8acSEd Tanous { 35341352c24SSantosh Puranik bool ret = true; 3549712f8acSEd Tanous if (key != keyToCheck) 3559712f8acSEd Tanous { 3569b6ffca5SEd Tanous ret = 3579b6ffca5SEd Tanous readJsonValues<Count, Index + 1>( 3589b6ffca5SEd Tanous key, jsonValue, res, handled, 3599b6ffca5SEd Tanous // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) 36041352c24SSantosh Puranik in...) && 36141352c24SSantosh Puranik ret; 36241352c24SSantosh Puranik return ret; 3639712f8acSEd Tanous } 3649712f8acSEd Tanous 3659712f8acSEd Tanous handled.set(Index); 3669712f8acSEd Tanous 36741352c24SSantosh Puranik return unpackValue<ValueType>(jsonValue, key, res, valueToFill) && ret; 3689712f8acSEd Tanous } 3699712f8acSEd Tanous 3709712f8acSEd Tanous template <size_t Index = 0, size_t Count> 371*104f09c9SEd Tanous bool handleMissing(std::bitset<Count>& /*handled*/, crow::Response& /*res*/) 3729712f8acSEd Tanous { 37341352c24SSantosh Puranik return true; 3749712f8acSEd Tanous } 3759712f8acSEd Tanous 3769712f8acSEd Tanous template <size_t Index = 0, size_t Count, typename ValueType, 3779712f8acSEd Tanous typename... UnpackTypes> 37841352c24SSantosh Puranik bool handleMissing(std::bitset<Count>& handled, crow::Response& res, 379*104f09c9SEd Tanous const char* key, ValueType& /*unusedValue*/, 380*104f09c9SEd Tanous UnpackTypes&... in) 3819712f8acSEd Tanous { 38241352c24SSantosh Puranik bool ret = true; 3832c70f800SEd Tanous if (!handled.test(Index) && !IsOptional<ValueType>::value) 3849712f8acSEd Tanous { 38541352c24SSantosh Puranik ret = false; 386a08b46ccSJason M. Bills messages::propertyMissing(res, key); 3879712f8acSEd Tanous } 3889b6ffca5SEd Tanous 3899b6ffca5SEd Tanous // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) 39041352c24SSantosh Puranik return details::handleMissing<Index + 1, Count>(handled, res, in...) && ret; 3919712f8acSEd Tanous } 3929712f8acSEd Tanous } // namespace details 3939712f8acSEd Tanous 3949712f8acSEd Tanous template <typename... UnpackTypes> 3950627a2c7SEd Tanous bool readJson(nlohmann::json& jsonRequest, crow::Response& res, const char* key, 3969712f8acSEd Tanous UnpackTypes&... in) 3979712f8acSEd Tanous { 39841352c24SSantosh Puranik bool result = true; 3999712f8acSEd Tanous if (!jsonRequest.is_object()) 4009712f8acSEd Tanous { 4019712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Json value is not an object"; 402f12894f8SJason M. Bills messages::unrecognizedRequestBody(res); 4039712f8acSEd Tanous return false; 4049712f8acSEd Tanous } 4059712f8acSEd Tanous 4069712f8acSEd Tanous if (jsonRequest.empty()) 4079712f8acSEd Tanous { 4089712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Json value is empty"; 409f12894f8SJason M. Bills messages::emptyJSON(res); 4109712f8acSEd Tanous return false; 4119712f8acSEd Tanous } 4129712f8acSEd Tanous 4139712f8acSEd Tanous std::bitset<(sizeof...(in) + 1) / 2> handled(0); 4149712f8acSEd Tanous for (const auto& item : jsonRequest.items()) 4159712f8acSEd Tanous { 41641352c24SSantosh Puranik result = 4179712f8acSEd Tanous details::readJsonValues<(sizeof...(in) + 1) / 2, 0, UnpackTypes...>( 41841352c24SSantosh Puranik item.key(), item.value(), res, handled, key, in...) && 41941352c24SSantosh Puranik result; 4209712f8acSEd Tanous } 4219712f8acSEd Tanous 42241352c24SSantosh Puranik BMCWEB_LOG_DEBUG << "JSON result is: " << result; 4239712f8acSEd Tanous 42441352c24SSantosh Puranik return details::handleMissing(handled, res, key, in...) && result; 4259712f8acSEd Tanous } 42677dd8813SKowalski, Kamil 4270627a2c7SEd Tanous template <typename... UnpackTypes> 4280627a2c7SEd Tanous bool readJson(const crow::Request& req, crow::Response& res, const char* key, 4290627a2c7SEd Tanous UnpackTypes&... in) 4300627a2c7SEd Tanous { 4310627a2c7SEd Tanous nlohmann::json jsonRequest; 4320627a2c7SEd Tanous if (!json_util::processJsonFromRequest(res, req, jsonRequest)) 4330627a2c7SEd Tanous { 4340627a2c7SEd Tanous BMCWEB_LOG_DEBUG << "Json value not readable"; 4350627a2c7SEd Tanous return false; 4360627a2c7SEd Tanous } 4370627a2c7SEd Tanous return readJson(jsonRequest, res, key, in...); 4380627a2c7SEd Tanous } 4390627a2c7SEd Tanous 440471a5eb8SAppaRao Puli template <typename Type> 441471a5eb8SAppaRao Puli bool getValueFromJsonObject(nlohmann::json& jsonData, const std::string& key, 442471a5eb8SAppaRao Puli Type& value) 443471a5eb8SAppaRao Puli { 444c638bc45SEd Tanous nlohmann::json::iterator it = jsonData.find(key); 445c638bc45SEd Tanous if (it == jsonData.end()) 446471a5eb8SAppaRao Puli { 447471a5eb8SAppaRao Puli BMCWEB_LOG_DEBUG << "Key " << key << " not exist"; 448471a5eb8SAppaRao Puli return false; 449471a5eb8SAppaRao Puli } 450471a5eb8SAppaRao Puli 451c638bc45SEd Tanous return details::unpackValue(*it, key, value); 452471a5eb8SAppaRao Puli } 45377dd8813SKowalski, Kamil } // namespace json_util 45477dd8813SKowalski, Kamil } // namespace redfish 455