json_utils: Add support jsonRead Patch/Action

Added support for readJson for Patch and Action. The only difference is
that Patch does not allow empty json input while Action does. Action with
empty input will use the default value based on the implementation and
return 200 OK response code.

readJsonPatch will replace the existing readJson and be used for path
requests. It will not allow empty json input and all requested
keys are required in the json input.

readJsonAction will be used for Action requests where it is possible for
all of the properties to be optional and allow empty request.
The optional properties are determined by the requested values type.

All current Action readJson are replaced with readJsonAction. It does
not change the existing behavior since it needs `std::optional`.
This will have to be updated later as we define the default behavior.

Tested:
Added unit tests and readJsonAction allows empty empty json object.

No Change to Redfish Tree.

Change-Id: Ia5e1f81695c528a20f1dc985aee19c920d8adaea
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index 39146c9..a9e0ec4 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -366,8 +366,8 @@
 {
     std::string broadcastMsg;
 
-    if (!redfish::json_util::readJson(req, asyncResp->res, "Message",
-                                      broadcastMsg))
+    if (!redfish::json_util::readJsonPatch(req, asyncResp->res, "Message",
+                                           broadcastMsg))
     {
         BMCWEB_LOG_DEBUG << "Not a Valid JSON";
         asyncResp->res.result(boost::beast::http::status::bad_request);
@@ -747,8 +747,8 @@
             [](const crow::Request& req,
                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
                 std::vector<nlohmann::json> body;
-                if (!redfish::json_util::readJson(req, asyncResp->res,
-                                                  "Request", body))
+                if (!redfish::json_util::readJsonAction(req, asyncResp->res,
+                                                        "Request", body))
                 {
                     BMCWEB_LOG_DEBUG << "Not a Valid JSON";
                     asyncResp->res.result(
@@ -765,9 +765,9 @@
                 std::string type;
                 std::vector<uint32_t> listTransactionIds;
 
-                if (!redfish::json_util::readJson(req, asyncResp->res, "Type",
-                                                  type, "TransactionIDs",
-                                                  listTransactionIds))
+                if (!redfish::json_util::readJsonPatch(
+                        req, asyncResp->res, "Type", type, "TransactionIDs",
+                        listTransactionIds))
                 {
                     asyncResp->res.result(
                         boost::beast::http::status::bad_request);
@@ -796,8 +796,8 @@
                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
                 ListOfSessionIds listSessionIds;
 
-                if (!redfish::json_util::readJson(req, asyncResp->res,
-                                                  "SessionIDs", listSessionIds))
+                if (!redfish::json_util::readJsonPatch(
+                        req, asyncResp->res, "SessionIDs", listSessionIds))
                 {
                     asyncResp->res.result(
                         boost::beast::http::status::bad_request);