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 17*9712f8acSEd Tanous 1877dd8813SKowalski, Kamil #include <crow/http_request.h> 1977dd8813SKowalski, Kamil #include <crow/http_response.h> 2077dd8813SKowalski, Kamil 21*9712f8acSEd Tanous #include <bitset> 22*9712f8acSEd Tanous #include <error_messages.hpp> 231abe55efSEd Tanous #include <nlohmann/json.hpp> 241abe55efSEd Tanous namespace redfish 251abe55efSEd Tanous { 261abe55efSEd Tanous 271abe55efSEd Tanous namespace json_util 281abe55efSEd Tanous { 2977dd8813SKowalski, Kamil 3077dd8813SKowalski, Kamil /** 3177dd8813SKowalski, Kamil * @brief Defines JSON utils operation status 3277dd8813SKowalski, Kamil */ 331abe55efSEd Tanous enum class Result 341abe55efSEd Tanous { 351abe55efSEd Tanous SUCCESS, 361abe55efSEd Tanous NOT_EXIST, 371abe55efSEd Tanous WRONG_TYPE, 381abe55efSEd Tanous NULL_POINTER 391abe55efSEd Tanous }; 4077dd8813SKowalski, Kamil 4177dd8813SKowalski, Kamil /** 4277dd8813SKowalski, Kamil * @brief Describes JSON utils messages requirement 4377dd8813SKowalski, Kamil */ 441abe55efSEd Tanous enum class MessageSetting 451abe55efSEd Tanous { 4677dd8813SKowalski, Kamil NONE = 0x0, ///< No messages will be added 4777dd8813SKowalski, Kamil MISSING = 0x1, ///< PropertyMissing message will be added 4877dd8813SKowalski, Kamil TYPE_ERROR = 0x2 ///< PropertyValueTypeError message will be added 4977dd8813SKowalski, Kamil }; 5077dd8813SKowalski, Kamil 5177dd8813SKowalski, Kamil /** 5277dd8813SKowalski, Kamil * @brief Wrapper function for extracting string from JSON object without 5377dd8813SKowalski, Kamil * throwing exceptions 5477dd8813SKowalski, Kamil * 5577dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 5677dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 5777dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 5877dd8813SKowalski, Kamil * of success 5977dd8813SKowalski, Kamil * 6077dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 6177dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 6277dd8813SKowalski, Kamil */ 6377dd8813SKowalski, Kamil Result getString(const char* fieldName, const nlohmann::json& json, 6477dd8813SKowalski, Kamil const std::string*& output); 6577dd8813SKowalski, Kamil 6677dd8813SKowalski, Kamil /** 6777dd8813SKowalski, Kamil * @brief Wrapper function for extracting object from JSON object without 6877dd8813SKowalski, Kamil * throwing exceptions 6977dd8813SKowalski, Kamil * 7077dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 7177dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 7277dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 7377dd8813SKowalski, Kamil * of success 7477dd8813SKowalski, Kamil * 7577dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 7677dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 7777dd8813SKowalski, Kamil */ 7877dd8813SKowalski, Kamil Result getObject(const char* fieldName, const nlohmann::json& json, 7977dd8813SKowalski, Kamil nlohmann::json* output); 8077dd8813SKowalski, Kamil 8177dd8813SKowalski, Kamil /** 8277dd8813SKowalski, Kamil * @brief Wrapper function for extracting array from JSON object without 8377dd8813SKowalski, Kamil * throwing exceptions 8477dd8813SKowalski, Kamil * 8577dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 8677dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 8777dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 8877dd8813SKowalski, Kamil * of success 8977dd8813SKowalski, Kamil * 9077dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 9177dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 9277dd8813SKowalski, Kamil */ 9377dd8813SKowalski, Kamil Result getArray(const char* fieldName, const nlohmann::json& json, 9477dd8813SKowalski, Kamil nlohmann::json* output); 9577dd8813SKowalski, Kamil 9677dd8813SKowalski, Kamil /** 9777dd8813SKowalski, Kamil * @brief Wrapper function for extracting int from JSON object without 9877dd8813SKowalski, Kamil * throwing exceptions 9977dd8813SKowalski, Kamil * 10077dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 10177dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 10277dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 10377dd8813SKowalski, Kamil * of success 10477dd8813SKowalski, Kamil * 10577dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 10677dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 10777dd8813SKowalski, Kamil */ 10877dd8813SKowalski, Kamil Result getInt(const char* fieldName, const nlohmann::json& json, 10977dd8813SKowalski, Kamil int64_t& output); 11077dd8813SKowalski, Kamil 11177dd8813SKowalski, Kamil /** 11277dd8813SKowalski, Kamil * @brief Wrapper function for extracting uint from JSON object without 11377dd8813SKowalski, Kamil * throwing exceptions 11477dd8813SKowalski, Kamil * 11577dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 11677dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 11777dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 11877dd8813SKowalski, Kamil * of success 11977dd8813SKowalski, Kamil * 12077dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 12177dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 12277dd8813SKowalski, Kamil */ 12377dd8813SKowalski, Kamil Result getUnsigned(const char* fieldName, const nlohmann::json& json, 12477dd8813SKowalski, Kamil uint64_t& output); 12577dd8813SKowalski, Kamil 12677dd8813SKowalski, Kamil /** 12777dd8813SKowalski, Kamil * @brief Wrapper function for extracting bool from JSON object without 12877dd8813SKowalski, Kamil * throwing exceptions 12977dd8813SKowalski, Kamil * 13077dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 13177dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 13277dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 13377dd8813SKowalski, Kamil * of success 13477dd8813SKowalski, Kamil * 13577dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 13677dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 13777dd8813SKowalski, Kamil */ 13877dd8813SKowalski, Kamil Result getBool(const char* fieldName, const nlohmann::json& json, bool& output); 13977dd8813SKowalski, Kamil 14077dd8813SKowalski, Kamil /** 14177dd8813SKowalski, Kamil * @brief Wrapper function for extracting float from JSON object without 14277dd8813SKowalski, Kamil * throwing exceptions (nlohmann stores JSON floats as C++ doubles) 14377dd8813SKowalski, Kamil * 14477dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 14577dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 14677dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 14777dd8813SKowalski, Kamil * of success 14877dd8813SKowalski, Kamil * 14977dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 15077dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 15177dd8813SKowalski, Kamil */ 15277dd8813SKowalski, Kamil Result getDouble(const char* fieldName, const nlohmann::json& json, 15377dd8813SKowalski, Kamil double& output); 15477dd8813SKowalski, Kamil 15577dd8813SKowalski, Kamil /** 15677dd8813SKowalski, Kamil * @brief Wrapper function for extracting string from JSON object without 15777dd8813SKowalski, Kamil * throwing exceptions 15877dd8813SKowalski, Kamil * 15977dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 16077dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 16177dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 16277dd8813SKowalski, Kamil * of success 16377dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 16477dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 16577dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 16677dd8813SKowalski, Kamil * 16777dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 16877dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 16977dd8813SKowalski, Kamil */ 17077dd8813SKowalski, Kamil Result getString(const char* fieldName, const nlohmann::json& json, 17177dd8813SKowalski, Kamil const std::string*& output, uint8_t msgCfgMap, 17277dd8813SKowalski, Kamil nlohmann::json& msgJson, const std::string&& fieldPath); 17377dd8813SKowalski, Kamil 17477dd8813SKowalski, Kamil /** 17577dd8813SKowalski, Kamil * @brief Wrapper function for extracting object from JSON object without 17677dd8813SKowalski, Kamil * throwing exceptions 17777dd8813SKowalski, Kamil * 17877dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 17977dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 18077dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 18177dd8813SKowalski, Kamil * of success 18277dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 18377dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 18477dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 18577dd8813SKowalski, Kamil * 18677dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 18777dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 18877dd8813SKowalski, Kamil */ 18977dd8813SKowalski, Kamil Result getObject(const char* fieldName, const nlohmann::json& json, 19077dd8813SKowalski, Kamil nlohmann::json* output, uint8_t msgCfgMap, 19177dd8813SKowalski, Kamil nlohmann::json& msgJson, const std::string&& fieldPath); 19277dd8813SKowalski, Kamil 19377dd8813SKowalski, Kamil /** 19477dd8813SKowalski, Kamil * @brief Wrapper function for extracting array from JSON object without 19577dd8813SKowalski, Kamil * throwing exceptions 19677dd8813SKowalski, Kamil * 19777dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 19877dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 19977dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 20077dd8813SKowalski, Kamil * of success 20177dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 20277dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 20377dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 20477dd8813SKowalski, Kamil * 20577dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 20677dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 20777dd8813SKowalski, Kamil */ 20877dd8813SKowalski, Kamil Result getArray(const char* fieldName, const nlohmann::json& json, 20977dd8813SKowalski, Kamil nlohmann::json* output, uint8_t msgCfgMap, 21077dd8813SKowalski, Kamil nlohmann::json& msgJson, const std::string&& fieldPath); 21177dd8813SKowalski, Kamil 21277dd8813SKowalski, Kamil /** 21377dd8813SKowalski, Kamil * @brief Wrapper function for extracting int from JSON object without 21477dd8813SKowalski, Kamil * throwing exceptions 21577dd8813SKowalski, Kamil * 21677dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 21777dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 21877dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 21977dd8813SKowalski, Kamil * of success 22077dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 22177dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 22277dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 22377dd8813SKowalski, Kamil * 22477dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 22577dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 22677dd8813SKowalski, Kamil */ 22777dd8813SKowalski, Kamil Result getInt(const char* fieldName, const nlohmann::json& json, 22877dd8813SKowalski, Kamil int64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson, 22977dd8813SKowalski, Kamil const std::string&& fieldPath); 23077dd8813SKowalski, Kamil 23177dd8813SKowalski, Kamil /** 23277dd8813SKowalski, Kamil * @brief Wrapper function for extracting uint from JSON object without 23377dd8813SKowalski, Kamil * throwing exceptions 23477dd8813SKowalski, Kamil * 23577dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 23677dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 23777dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 23877dd8813SKowalski, Kamil * of success 23977dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 24077dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 24177dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 24277dd8813SKowalski, Kamil * 24377dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 24477dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 24577dd8813SKowalski, Kamil */ 24677dd8813SKowalski, Kamil Result getUnsigned(const char* fieldName, const nlohmann::json& json, 24777dd8813SKowalski, Kamil uint64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson, 24877dd8813SKowalski, Kamil const std::string&& fieldPath); 24977dd8813SKowalski, Kamil 25077dd8813SKowalski, Kamil /** 25177dd8813SKowalski, Kamil * @brief Wrapper function for extracting bool from JSON object without 25277dd8813SKowalski, Kamil * throwing exceptions 25377dd8813SKowalski, Kamil * 25477dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 25577dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 25677dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 25777dd8813SKowalski, Kamil * of success 25877dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 25977dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 26077dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 26177dd8813SKowalski, Kamil * 26277dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 26377dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 26477dd8813SKowalski, Kamil */ 26577dd8813SKowalski, Kamil Result getBool(const char* fieldName, const nlohmann::json& json, bool& output, 26677dd8813SKowalski, Kamil uint8_t msgCfgMap, nlohmann::json& msgJson, 26777dd8813SKowalski, Kamil const std::string&& fieldPath); 26877dd8813SKowalski, Kamil 26977dd8813SKowalski, Kamil /** 27077dd8813SKowalski, Kamil * @brief Wrapper function for extracting float from JSON object without 27177dd8813SKowalski, Kamil * throwing exceptions (nlohmann stores JSON floats as C++ doubles) 27277dd8813SKowalski, Kamil * 27377dd8813SKowalski, Kamil * @param[in] fieldName Name of requested field 27477dd8813SKowalski, Kamil * @param[in] json JSON object from which field should be extracted 27577dd8813SKowalski, Kamil * @param[out] output Variable to which extracted will be written in case 27677dd8813SKowalski, Kamil * of success 27777dd8813SKowalski, Kamil * @param[in] msgCfgMap Map for message addition settings 27877dd8813SKowalski, Kamil * @param[out] msgJson JSON to which error messages will be added 27977dd8813SKowalski, Kamil * @param[in] fieldPath Field path in JSON 28077dd8813SKowalski, Kamil * 28177dd8813SKowalski, Kamil * @return Result informing about operation status, output will be 28277dd8813SKowalski, Kamil * written only in case of Result::SUCCESS 28377dd8813SKowalski, Kamil */ 28477dd8813SKowalski, Kamil Result getDouble(const char* fieldName, const nlohmann::json& json, 28577dd8813SKowalski, Kamil double& output, uint8_t msgCfgMap, nlohmann::json& msgJson, 28677dd8813SKowalski, Kamil const std::string&& fieldPath); 28777dd8813SKowalski, Kamil 28877dd8813SKowalski, Kamil /** 28977dd8813SKowalski, Kamil * @brief Processes request to extract JSON from its body. If it fails, adds 29077dd8813SKowalski, Kamil * MalformedJSON message to response and ends it. 29177dd8813SKowalski, Kamil * 29277dd8813SKowalski, Kamil * @param[io] res Response object 29377dd8813SKowalski, Kamil * @param[in] req Request object 29477dd8813SKowalski, Kamil * @param[out] reqJson JSON object extracted from request's body 29577dd8813SKowalski, Kamil * 29677dd8813SKowalski, Kamil * @return true if JSON is valid, false when JSON is invalid and response has 29777dd8813SKowalski, Kamil * been filled with message and ended. 29877dd8813SKowalski, Kamil */ 29955c7b7a2SEd Tanous bool processJsonFromRequest(crow::Response& res, const crow::Request& req, 30077dd8813SKowalski, Kamil nlohmann::json& reqJson); 301*9712f8acSEd Tanous namespace details 302*9712f8acSEd Tanous { 303*9712f8acSEd Tanous template <typename Type> struct unpackValue 304*9712f8acSEd Tanous { 305*9712f8acSEd Tanous using isRequired = std::true_type; 306*9712f8acSEd Tanous using JsonType = std::add_const_t<std::add_pointer_t<Type>>; 307*9712f8acSEd Tanous }; 308*9712f8acSEd Tanous 309*9712f8acSEd Tanous template <typename OptionalType> 310*9712f8acSEd Tanous struct unpackValue<boost::optional<OptionalType>> 311*9712f8acSEd Tanous { 312*9712f8acSEd Tanous using isRequired = std::false_type; 313*9712f8acSEd Tanous using JsonType = std::add_const_t<std::add_pointer_t<OptionalType>>; 314*9712f8acSEd Tanous }; 315*9712f8acSEd Tanous 316*9712f8acSEd Tanous template <size_t Count, size_t Index> 317*9712f8acSEd Tanous void readJsonValues(const std::string& key, nlohmann::json& jsonValue, 318*9712f8acSEd Tanous crow::Response& res, std::bitset<Count>& handled) 319*9712f8acSEd Tanous { 320*9712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Unable to find variable for key" << key; 321*9712f8acSEd Tanous messages::addMessageToErrorJson(res.jsonValue, 322*9712f8acSEd Tanous messages::propertyUnknown(key)); 323*9712f8acSEd Tanous res.result(boost::beast::http::status::bad_request); 324*9712f8acSEd Tanous } 325*9712f8acSEd Tanous 326*9712f8acSEd Tanous template <size_t Count, size_t Index, typename ValueType, 327*9712f8acSEd Tanous typename... UnpackTypes> 328*9712f8acSEd Tanous void readJsonValues(const std::string& key, nlohmann::json& jsonValue, 329*9712f8acSEd Tanous crow::Response& res, std::bitset<Count>& handled, 330*9712f8acSEd Tanous const char* keyToCheck, ValueType& valueToFill, 331*9712f8acSEd Tanous UnpackTypes&... in) 332*9712f8acSEd Tanous { 333*9712f8acSEd Tanous if (key != keyToCheck) 334*9712f8acSEd Tanous { 335*9712f8acSEd Tanous readJsonValues<Count, Index + 1>(key, jsonValue, res, handled, in...); 336*9712f8acSEd Tanous return; 337*9712f8acSEd Tanous } 338*9712f8acSEd Tanous 339*9712f8acSEd Tanous handled.set(Index); 340*9712f8acSEd Tanous 341*9712f8acSEd Tanous using UnpackType = typename unpackValue<ValueType>::JsonType; 342*9712f8acSEd Tanous UnpackType value = jsonValue.get_ptr<UnpackType>(); 343*9712f8acSEd Tanous if (value == nullptr) 344*9712f8acSEd Tanous { 345*9712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Value for key " << key 346*9712f8acSEd Tanous << " was incorrect type: " << jsonValue.type_name(); 347*9712f8acSEd Tanous messages::addMessageToErrorJson( 348*9712f8acSEd Tanous res.jsonValue, 349*9712f8acSEd Tanous messages::propertyValueTypeError(jsonValue.dump(), key)); 350*9712f8acSEd Tanous res.result(boost::beast::http::status::bad_request); 351*9712f8acSEd Tanous 352*9712f8acSEd Tanous return; 353*9712f8acSEd Tanous } 354*9712f8acSEd Tanous 355*9712f8acSEd Tanous valueToFill = *value; 356*9712f8acSEd Tanous } 357*9712f8acSEd Tanous 358*9712f8acSEd Tanous template <size_t Index = 0, size_t Count> 359*9712f8acSEd Tanous void handleMissing(std::bitset<Count>& handled, crow::Response& res) 360*9712f8acSEd Tanous { 361*9712f8acSEd Tanous } 362*9712f8acSEd Tanous 363*9712f8acSEd Tanous template <size_t Index = 0, size_t Count, typename ValueType, 364*9712f8acSEd Tanous typename... UnpackTypes> 365*9712f8acSEd Tanous void handleMissing(std::bitset<Count>& handled, crow::Response& res, 366*9712f8acSEd Tanous const char* key, ValueType& unused, UnpackTypes&... in) 367*9712f8acSEd Tanous { 368*9712f8acSEd Tanous if (!handled.test(Index) && unpackValue<ValueType>::isRequired::value) 369*9712f8acSEd Tanous { 370*9712f8acSEd Tanous messages::addMessageToErrorJson(res.jsonValue, 371*9712f8acSEd Tanous messages::propertyMissing(key)); 372*9712f8acSEd Tanous res.result(boost::beast::http::status::bad_request); 373*9712f8acSEd Tanous } 374*9712f8acSEd Tanous details::handleMissing<Index + 1, Count>(handled, res, in...); 375*9712f8acSEd Tanous } 376*9712f8acSEd Tanous } // namespace details 377*9712f8acSEd Tanous 378*9712f8acSEd Tanous template <typename... UnpackTypes> 379*9712f8acSEd Tanous bool readJson(const crow::Request& req, crow::Response& res, const char* key, 380*9712f8acSEd Tanous UnpackTypes&... in) 381*9712f8acSEd Tanous { 382*9712f8acSEd Tanous nlohmann::json jsonRequest; 383*9712f8acSEd Tanous if (!json_util::processJsonFromRequest(res, req, jsonRequest)) 384*9712f8acSEd Tanous { 385*9712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Json value not readable"; 386*9712f8acSEd Tanous return false; 387*9712f8acSEd Tanous } 388*9712f8acSEd Tanous if (!jsonRequest.is_object()) 389*9712f8acSEd Tanous { 390*9712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Json value is not an object"; 391*9712f8acSEd Tanous messages::addMessageToErrorJson(res.jsonValue, 392*9712f8acSEd Tanous messages::unrecognizedRequestBody()); 393*9712f8acSEd Tanous res.result(boost::beast::http::status::bad_request); 394*9712f8acSEd Tanous return false; 395*9712f8acSEd Tanous } 396*9712f8acSEd Tanous 397*9712f8acSEd Tanous if (jsonRequest.empty()) 398*9712f8acSEd Tanous { 399*9712f8acSEd Tanous BMCWEB_LOG_DEBUG << "Json value is empty"; 400*9712f8acSEd Tanous messages::addMessageToErrorJson(res.jsonValue, messages::emptyJSON()); 401*9712f8acSEd Tanous res.result(boost::beast::http::status::bad_request); 402*9712f8acSEd Tanous return false; 403*9712f8acSEd Tanous } 404*9712f8acSEd Tanous 405*9712f8acSEd Tanous std::bitset<(sizeof...(in) + 1) / 2> handled(0); 406*9712f8acSEd Tanous for (const auto& item : jsonRequest.items()) 407*9712f8acSEd Tanous { 408*9712f8acSEd Tanous details::readJsonValues<(sizeof...(in) + 1) / 2, 0, UnpackTypes...>( 409*9712f8acSEd Tanous item.key(), item.value(), res, handled, key, in...); 410*9712f8acSEd Tanous } 411*9712f8acSEd Tanous 412*9712f8acSEd Tanous if (!handled.all()) 413*9712f8acSEd Tanous { 414*9712f8acSEd Tanous details::handleMissing(handled, res, key, in...); 415*9712f8acSEd Tanous 416*9712f8acSEd Tanous return false; 417*9712f8acSEd Tanous } 418*9712f8acSEd Tanous return res.result() == boost::beast::http::status::ok; 419*9712f8acSEd Tanous } 42077dd8813SKowalski, Kamil 42177dd8813SKowalski, Kamil } // namespace json_util 42277dd8813SKowalski, Kamil } // namespace redfish 423